/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2009-2011 The OpenNMS Group, Inc. * OpenNMS(R) is Copyright (C) 1999-2011 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 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 General Public License for more details. * * You should have received a copy of the GNU 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.poller.remote; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; import org.opennms.core.utils.LogUtils; import org.opennms.netmgt.poller.remote.PollerFrontEnd; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; /** * <p>Main class.</p> * * @author <a href="mailto:ranger@opennms.org">Benjamin Reed</a> * @author <a href="mailto:brozow@opennms.org">Mathew Brozowski</a> */ public class Main { String[] m_args; ClassPathXmlApplicationContext m_context; PollerFrontEnd m_frontEnd; URI m_uri; String m_locationName; String m_username = null; String m_password = null; String m_pollerHome = null; boolean m_shuttingDown = false; boolean m_gui = false; CommandLine m_cl; private Main(String[] args) throws Exception { m_args = args; m_pollerHome = System.getProperty("poller.home"); if (m_pollerHome == null) { if (System.getProperty("os.name").contains("Windows")) { m_pollerHome = System.getProperty("java.io.tmpdir"); } else { m_pollerHome = System.getProperty("user.home") + File.separator + ".opennms"; } } initializeLogging(); final String pingerClass = System.getProperty("org.opennms.netmgt.icmp.pingerClass"); if (pingerClass == null) { LogUtils.infof(this, "org.opennms.netmgt.icmp.pingerClass not set; using JnaPinger by default"); System.setProperty("org.opennms.netmgt.icmp.pingerClass", "org.opennms.netmgt.icmp.jna.JnaPinger"); } } private void initializeLogging() throws Exception { String logFile; logFile = System.getProperty("poller.logfile", m_pollerHome + File.separator + "opennms-remote-poller.log"); File logDirectory = new File(logFile).getParentFile(); if (!logDirectory.exists()) { if (!logDirectory.mkdirs()) { throw new IllegalStateException("Could not create parent directory for log file '" + logFile + "'"); } } if (Boolean.getBoolean("debug")) { LogUtils.logToConsole(); } else { LogUtils.logToFile(logFile); } } private void getAuthenticationInfo() { if (m_uri == null || m_uri.getScheme() == null) { throw new RuntimeException("no URI specified!"); } if (m_uri.getScheme().equals("rmi")) { // RMI doesn't have authentication return; } if (m_username == null) { GroovyGui gui = createGui(); gui.createAndShowGui(); AuthenticationBean auth = gui.getAuthenticationBean(); m_username = auth.getUsername(); m_password = auth.getPassword(); } if (m_username != null) { SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_GLOBAL); SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(m_username, m_password)); } } private GroovyGui createGui() { try { return (GroovyGui)Class.forName("org.opennms.groovy.poller.remote.ConfigurationGui").newInstance(); } catch (Throwable e) { throw new RuntimeException("Unable to find Configuration GUI!", e); } } private void run() { try { parseArguments(); getAuthenticationInfo(); createAppContext(); registerShutDownHook(); if (!m_gui) { if (!m_frontEnd.isRegistered()) { if (m_locationName == null) { LogUtils.errorf(this, "No location name provided. You must pass a location name the first time you start the remote poller!"); System.exit(27); } else { m_frontEnd.register(m_locationName); } } } } catch(Throwable e) { // a fatal exception occurred LogUtils.errorf(this, e, "Exception occurred during registration!"); System.exit(27); } } private void parseArguments() throws ParseException { Options options = new Options(); options.addOption("h", "help", false, "this help"); options.addOption("d", "debug", false, "write debug messages to the log"); options.addOption("g", "gui", false, "start a GUI (default: false)"); options.addOption("l", "location", true, "the location name of this remote poller"); options.addOption("u", "url", true, "the URL for OpenNMS (default: rmi://server-name/)"); options.addOption("n", "name", true, "the name of the user to connect as"); options.addOption("p", "password", true, "the password to use when connecting"); CommandLineParser parser = new PosixParser(); m_cl = parser.parse(options, m_args); if (m_cl.hasOption("h")) { usage(options); System.exit(1); } if (m_cl.hasOption("d")) { LogUtils.enableDebugging(); } if (m_cl.hasOption("l")) { m_locationName = m_cl.getOptionValue("l"); } if (m_cl.hasOption("u")) { String arg = m_cl.getOptionValue("u").toLowerCase(); try { m_uri = new URI(arg); } catch (URISyntaxException e) { usage(options); e.printStackTrace(); System.exit(2); } } else { usage(options); System.exit(3); } if (m_cl.hasOption("g")) { m_gui = true; } if (m_cl.hasOption("n")) { m_username = m_cl.getOptionValue("n"); m_password = m_cl.getOptionValue("p"); if (m_password == null) { m_password = ""; } } } private void usage(Options o) { HelpFormatter formatter = new HelpFormatter(); formatter.printHelp(HelpFormatter.DEFAULT_SYNTAX_PREFIX, o); } private void registerShutDownHook() { Thread shutdownHook = new Thread() { public void run() { m_shuttingDown = true; m_context.close(); } }; Runtime.getRuntime().addShutdownHook(shutdownHook); } private void createAppContext() { File homeDir = new File(System.getProperty("user.home")); String homeUrl = homeDir.toURI().toString(); if (homeUrl.endsWith("/")) { homeUrl = homeUrl.substring(0, homeUrl.length()-1); } LogUtils.infof(this, "user.home.url = %s", homeUrl); System.setProperty("user.home.url", homeUrl); String serverURI = m_uri.toString().replaceAll("/*$", ""); LogUtils.infof(this, "opennms.poller.server.url = %s", serverURI); System.setProperty("opennms.poller.server.url", serverURI); LogUtils.infof(this, "location name = %s", m_locationName); List<String> configs = new ArrayList<String>(); configs.add("classpath:/META-INF/opennms/applicationContext-remotePollerBackEnd-" + m_uri.getScheme() + ".xml"); configs.add("classpath:/META-INF/opennms/applicationContext-pollerFrontEnd.xml"); if (m_gui) { configs.add("classpath:/META-INF/opennms/applicationContext-ws-gui.xml"); } m_context = new ClassPathXmlApplicationContext(configs.toArray(new String[0])); m_frontEnd = (PollerFrontEnd) m_context.getBean("pollerFrontEnd"); m_frontEnd.addPropertyChangeListener(new PropertyChangeListener() { private boolean shouldExit(PropertyChangeEvent e) { LogUtils.infof(this, "shouldExit: received property change event: %s;oldvalue:%s;newvalue:%s", e.getPropertyName(), e.getOldValue(), e.getNewValue()); String propName = e.getPropertyName(); Object newValue = e.getNewValue(); // if exitNecessary becomes true.. then return true if ("exitNecessary".equals(propName) && Boolean.TRUE.equals(newValue)) { LogUtils.infof(this, "shouldExit: Exiting because exitNecessary is TRUE"); return true; } // if started becomes false the we should exit if ("started".equals(propName) && Boolean.FALSE.equals(newValue)) { LogUtils.infof(this, "shouldExit: Exiting because started is now false"); return true; } LogUtils.infof(this, "shouldExit: not exiting"); return false; } public void propertyChange(PropertyChangeEvent e) { if (!m_shuttingDown && shouldExit(e)) { System.exit(10); } } }); } /** * <p>main</p> * * @param args an array of {@link java.lang.String} objects. * @throws java.lang.Exception if any. */ public static void main(String[] args) throws Exception { String killSwitchFileName = System.getProperty("opennms.poller.killSwitch.resource"); File killSwitch = null; if (! "".equals(killSwitchFileName) && killSwitchFileName != null) { killSwitch = new File(System.getProperty("opennms.poller.killSwitch.resource")); if (!killSwitch.exists()) { try { killSwitch.createNewFile(); } catch (IOException ioe) { // We'll just do without one } } } new Main(args).run(); } }