/* * Claudia Project * http://claudia.morfeo-project.org * * (C) Copyright 2010 Telefonica Investigacion y Desarrollo * S.A.Unipersonal (Telefonica I+D) * * See CREDITS file for info about members and contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Affero GNU General Public License (AGPL) as * published by the Free Software Foundation; either version 3 of the License, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the Affero GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * If you want to use this software an plan to distribute a * proprietary application in any way, and you are not licensing and * distributing your source code under AGPL, you probably need to * purchase a commercial license of the product. Please contact * claudia-support@lists.morfeo-project.org for more information. */ package com.telefonica.claudia.slm.common; import java.net.MalformedURLException; import java.rmi.AlreadyBoundException; import java.rmi.RemoteException; import java.util.Observable; import java.util.Observer; import javax.jms.JMSException; import javax.naming.NamingException; import org.apache.log4j.ConsoleAppender; import org.apache.log4j.Level; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import org.apache.log4j.PatternLayout; import com.telefonica.claudia.slm.eventsBus.AdministrationConnector; import com.telefonica.claudia.slm.eventsBus.events.AdministrativeEvent; import com.telefonica.claudia.slm.eventsBus.events.AdministrativeEvent.CommandType; import com.telefonica.claudia.slm.eventsBus.events.AdministrativeEvent.SubcommandType; import com.telefonica.claudia.slm.lifecyclemanager.LifecycleController; public class ServiceManagerServer implements Observer { private static final int ERROR_CODE_BAD_PARAMETERS=1; private static final int ERROR_CODE_SYSTEM_CONFIGURATION=2; private static final int ERROR_CODE_COMMAND_EXECUTION=3; private static final int POOLING_DELAY=20000; private static Logger logger = Logger.getLogger(ServiceManagerServer.class); private static ServiceManagerServer sms = new ServiceManagerServer(); static { Logger.getLogger("com.telefonica.claudia.slm.launcher.ServiceManagerServer").addAppender( new ConsoleAppender(new PatternLayout("%-5p [%t] %c{2}: %m%n"), "System.out")); } //-------------------------------------------------------------------------------------------------------------------------- private LifecycleController lcc = null; //-------------------------------------------------------------------------------------------------------------------------- private static void showUsage() { System.out.println("Usage:\n\tclotho <command> [<subcommand>] [<options>]\n\n"); System.out.println("\t start"); System.out.println("\t\tStart a new Service Manager process.\n"); System.out.println("\t stop"); System.out.println("\t\tStop a Service Manager that is currently running.\n"); System.out.println("\t status"); System.out.println("\t\tGet information on the Service Manager that is currently running.\n"); System.out.println("\t networkrange create <description>"); System.out.println("\t\tCreate a new network range with the provided description.\n"); System.out.println("\t networkrange remove <network_name>"); System.out.println("\t\tCreate the network range with the provided network name. Will fail if its in use.\n"); } public static void main(String[] args) throws MalformedURLException, RemoteException, AlreadyBoundException, InterruptedException, JMSException, NamingException { if (args.length < 1) { System.out.println("Command not recognized. \n"); showUsage(); System.exit(ERROR_CODE_BAD_PARAMETERS); } CommandType command = CommandType.START; try { command = AdministrativeEvent.CommandType.valueOf(args[0].toUpperCase()); } catch (IllegalArgumentException iae) { System.out.println("Command not recognized. \n"); showUsage(); System.exit(ERROR_CODE_BAD_PARAMETERS); } if (command != CommandType.START) { LogManager.getLoggerRepository().setThreshold(Level.ERROR); } try { SMConfiguration.loadProperties(); } catch (Exception e) { e.printStackTrace(); System.exit(ERROR_CODE_SYSTEM_CONFIGURATION); } if (command != CommandType.START) { try { if (executeCommand(command, args)) System.exit(0); else { System.exit(ERROR_CODE_COMMAND_EXECUTION); } } catch (JMSException je) { logger.error("Exception connecting to the JMS queues: " +je.getMessage()); } catch (NamingException ne) { logger.error("Exception in JNDI searching for connection data: " + ne.getMessage()); } } logger.info("\n\n\n\n\nInitiating a new Service Lifecycle Manager Instance"); logger.info("--------------------------------------------------------------------------------------------------------------\n"); sms.lcc = new LifecycleController(); logger.info("Lifecycle manager created"); // Prepare to receive the termination signal try { final SignalHandler sh = new SignalHandler(); sh.addObserver( sms ); sh.handleSignal( "TERM" ); logger.info("Signal handlers attached"); } catch (Throwable t) { t.printStackTrace(); logger.warn("Watch Out!! Signal handler mechanisms could not be started, probably because a lack of support in this JavaVM. SLM can only be stopped with a kill signal."); } logger.info("Initialization finished, waiting for requests\n\n\n\n\n"); while (true) { Thread.sleep(POOLING_DELAY); } } /** * Execute a command issued from the command line. * * @param command * Command to be executed. * * @param args * Arguments for the command. The first one is the textual representation of the command itself. * * @return * true if the command has executed correctly. * false otherwise. * * @throws NamingException * @throws JMSException */ private static boolean executeCommand(CommandType command, String[] args) throws NamingException, JMSException { AdministrationConnector connector = new AdministrationConnector(); SubcommandType subcommand = null; if (args.length >1) try { subcommand = SubcommandType.valueOf(args[1].toUpperCase()); } catch (IllegalArgumentException iae) { System.out.println("\n\n Syntax was not recognized. Use help for command syntax."); return false; } switch (command) { case STOP: connector.finish(); return true; case NETWORKRANGE: // Two actions can be done, "CREATE" and "REMOVE" if (args.length > 2 && subcommand == SubcommandType.CREATE) { connector.createNetworkRange(args[2].replace(" ", "")); } else if (args.length > 2 && subcommand == SubcommandType.REMOVE) { connector.removeNetworkRange(args[2].replace(" ", "")); } else { System.out.println("\n\n Syntax was not recognized. Use help for command syntax."); return false; } break; case STATUS: System.out.println("\n\n" + connector.getStatus() + "\n\n"); return true; case HELP: default: showUsage(); return true; } return false; } public void update(Observable arg0, Object arg1) { logger.info("Termination signal received. Saving actual state and asking services to finish."); if (lcc!=null) lcc.finish(); logger.info("Returned from SLM's last stage. Exiting."); System.exit(0); } }