Java tutorial
/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2007-2014 The OpenNMS Group, Inc. * OpenNMS(R) is Copyright (C) 1999-2014 The OpenNMS Group, Inc. * * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. * * OpenNMS(R) is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * OpenNMS(R) 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with OpenNMS(R). If not, see: * http://www.gnu.org/licenses/ * * For more information contact: * OpenNMS(R) Licensing <license@opennms.org> * http://www.opennms.org/ * http://www.opennms.com/ *******************************************************************************/ package org.opennms.netmgt.vmmgr; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.management.ManagementFactory; import java.net.URL; import java.util.List; import java.util.Map.Entry; import java.util.Properties; import java.util.TreeMap; import javax.management.MBeanServer; import org.apache.commons.io.IOUtils; import org.opennms.core.logging.Logging; import org.opennms.netmgt.config.ServiceConfigFactory; import org.opennms.netmgt.config.service.Service; import org.opennms.netmgt.config.service.types.InvokeAtType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * <p> * The Manager is responsible for launching/starting all services in the VM * that it is started for. The Manager operates in two modes, normal and * server * </p> * <p> * normal mode: In the normal mode, the Manager starts all services configured * for its VM in the service-configuration.xml and starts listening for * control events on the 'control-broadcast' JMS topic for stop control * messages for itself * </p> * <p> * server mode: In the server mode, the Manager starts up and listens on the * 'control-broadcast' JMS topic for 'start' control messages for services in * its VM and a stop control messge for itself. When a start for a service is * received, it launches only that service and sends a successful 'running' or * an 'error' response to the Controller * </p> * <p> * <strong>Note: </strong>The Manager is NOT intelligent - if it receives a * stop control event, it will exit - does not check to see if the services * its started are all stopped * <p> * * @author <a href="mailto:weave@oculan.com">Brian Weaver</a> * @author <a href="mailto:sowmya@opennms.org">Sowmya Nataraj</a> */ public class Starter { private static final Logger LOG = LoggerFactory.getLogger(Starter.class); /** * The log4j category used to log debug messsages and statements. */ private static final String LOG4J_CATEGORY = "manager"; private void setLogPrefix() { Logging.putPrefix(LOG4J_CATEGORY); } /** * <p>startDaemon</p> */ public void startDaemon() { try { configureLog4j(); setLogPrefix(); setupMx4jLogger(); loadGlobalProperties(); setDefaultProperties(); start(); } catch (Exception e) { die("Exception during startup: " + e.getMessage(), e); } } public static class Mx4jSlf4JLogger extends mx4j.log.Logger { Logger m_slf4jLogger; @Override protected void log(int priority, Object msg, Throwable t) { switch (priority) { case mx4j.log.Logger.DEBUG: m_slf4jLogger.debug(msg == null ? "" : msg.toString(), t); case mx4j.log.Logger.ERROR: m_slf4jLogger.error(msg == null ? "" : msg.toString(), t); case mx4j.log.Logger.FATAL: m_slf4jLogger.error(msg == null ? "" : msg.toString(), t); case mx4j.log.Logger.INFO: m_slf4jLogger.info(msg == null ? "" : msg.toString(), t); case mx4j.log.Logger.TRACE: m_slf4jLogger.trace(msg == null ? "" : msg.toString(), t); case mx4j.log.Logger.WARN: m_slf4jLogger.warn(msg == null ? "" : msg.toString(), t); } } @Override protected void setCategory(String category) { super.setCategory(category); m_slf4jLogger = LoggerFactory.getLogger(category); } } private void setupMx4jLogger() { mx4j.log.Log.redirectTo(new Mx4jSlf4JLogger()); } private void configureLog4j() { } private void setDefaultProperties() { setupFileResourceProperty("opennms.library.jicmp", System.mapLibraryName("jicmp"), "Initialization of ICMP socket will likely fail."); setupFileResourceProperty("opennms.library.jrrd", System.mapLibraryName("jrrd"), "Initialization of RRD code will likely fail if the JniRrdStrategy is used."); setupFileResourceProperty("jcifs.properties", "jcifs.properties", "Initialization of JCIFS will likely fail or may be improperly configured."); } private void setupFileResourceProperty(String propertyName, String file, String notFoundWarning) { if (System.getProperty(propertyName) == null) { LOG.debug("System property '{}' not set. Searching for file '{}' in the class path.", propertyName, file); URL url = getClass().getClassLoader().getResource(file); if (url != null) { LOG.info("Found file '{}' at '{}'. Setting '{}' to this path.", file, url.getPath(), propertyName); System.setProperty(propertyName, url.getPath()); } else { LOG.warn( "Did not find file '{}' in the class path. {} Set the property '{}' to the location of the file.", file, notFoundWarning, propertyName); } } else { LOG.debug("System property '{}' already set to '{}'.", propertyName, System.getProperty(propertyName)); } } private void loadGlobalProperties() { // Log system properties, sorted by property name TreeMap<Object, Object> sortedProps = new TreeMap<Object, Object>(System.getProperties()); for (Entry<Object, Object> entry : sortedProps.entrySet()) { LOG.debug("System property '{}' already set to value '{}'.", entry.getKey(), entry.getValue()); } File propertiesFile = getPropertiesFile(); if (!propertiesFile.exists()) { // don't require the file return; } Properties props = new Properties(); InputStream in = null; try { in = new FileInputStream(propertiesFile); props.load(in); } catch (IOException e) { die("Error trying to read properties file '" + propertiesFile + "': " + e, e); } finally { IOUtils.closeQuietly(in); } for (Entry<Object, Object> entry : props.entrySet()) { String systemValue = System.getProperty(entry.getKey().toString()); if (systemValue != null) { LOG.debug( "Property '{}' from {} already exists as a system property (with value '{}'). Not overridding existing system property.", entry.getKey(), propertiesFile, systemValue); } else { LOG.debug("Setting system property '{}' to '{}' from {}.", entry.getKey(), entry.getValue(), propertiesFile); System.setProperty(entry.getKey().toString(), entry.getValue().toString()); } } if (props.containsKey("networkaddress.cache.ttl")) { java.security.Security.setProperty("networkaddress.cache.ttl", props.getProperty("networkaddress.cache.ttl")); } else { java.security.Security.setProperty("networkaddress.cache.ttl", "120"); } } /** * Print out a message and stack trace and then exit. * This method does not return. * * @param message message to print to System.err * @param t Throwable for which to print a stack trace */ private void die(String message, Throwable t) { LOG.error(message, t); System.exit(1); } public void die(String message) { die(message, null); } private File getPropertiesFile() { String homeDir = System.getProperty("opennms.home"); File etcDir = new File(homeDir, "etc"); return new File(etcDir, "opennms.properties"); } private void start() { LOG.debug("Beginning startup"); MBeanServer server = ManagementFactory.getPlatformMBeanServer(); Invoker invoker = new Invoker(); invoker.setServer(server); invoker.setAtType(InvokeAtType.START); List<InvokerService> services = InvokerService.createServiceList(new ServiceConfigFactory().getServices()); invoker.setServices(services); invoker.instantiateClasses(); List<InvokerResult> resultInfo = invoker.invokeMethods(); for (InvokerResult result : resultInfo) { if (result != null && result.getThrowable() != null) { Service service = result.getService(); String name = service.getName(); String className = service.getClassName(); String message = "An error occurred while attempting to start the \"" + name + "\" service (class " + className + "). " + "Shutting down and exiting."; LOG.error(message, result.getThrowable()); System.err.println(message); result.getThrowable().printStackTrace(); Manager manager = new Manager(); manager.stop(); manager.doSystemExit(); // Shouldn't get here return; } } LOG.debug("Startup complete"); } }