/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2008-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.netmgt.vmmgr; import java.io.BufferedReader; import java.io.InputStreamReader; import java.lang.reflect.UndeclaredThrowableException; import java.net.Authenticator; import java.net.ConnectException; import java.net.MalformedURLException; import java.net.PasswordAuthentication; import java.net.URL; import java.net.URLConnection; import java.util.LinkedHashMap; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; public class StatusGetter { public enum Status { UNKNOWN, RUNNING, PARTIALLY_RUNNING, NOT_RUNNING, CONNECTION_REFUSED } private static final URL DEFAULT_INVOKE_URL; private boolean m_verbose = false; private URL m_invokeURL = DEFAULT_INVOKE_URL; private Status m_status = Status.UNKNOWN; static { try { DEFAULT_INVOKE_URL = new URL("http://127.0.0.1:8181/invoke?objectname=OpenNMS:Name=Manager&operation=status"); } catch (final MalformedURLException e) { // This should never happen throw new UndeclaredThrowableException(e); } } /** * <p>Constructor for StatusGetter.</p> */ public StatusGetter() { } /** * <p>isVerbose</p> * * @return a boolean. */ public boolean isVerbose() { return m_verbose; } /** * <p>setVerbose</p> * * @param verbose a boolean. */ public void setVerbose(boolean verbose) { m_verbose = verbose; } /** * <p>getInvokeURL</p> * * @return a {@link java.net.URL} object. */ public URL getInvokeURL() { return m_invokeURL; } /** * <p>setInvokeURL</p> * * @param invokeURL a {@link java.net.URL} object. */ public void setInvokeURL(URL invokeURL) { m_invokeURL = invokeURL; } /** * <p>getStatus</p> * * @return a {@link org.opennms.netmgt.vmmgr.StatusGetter.Status} object. */ public Status getStatus() { return m_status; } /** * <p>main</p> * * @param argv an array of {@link java.lang.String} objects. * @throws java.lang.Exception if any. */ public static void main(String[] argv) throws Exception { StatusGetter statusGetter = new StatusGetter(); int i; for (i = 0; i < argv.length; i++) { if (argv[i].equals("-h")) { System.out.println("Accepted options:"); System.out.println(" -v Verbose mode."); System.out.println(" -u <URL> Alternate invoker URL."); System.out.println("The default invoker URL is: " + statusGetter.getInvokeURL()); statusGetter.setVerbose(true); } else if (argv[i].equals("-v")) { statusGetter.setVerbose(true); } else if (argv[i].equals("-u")) { statusGetter.setInvokeURL(new URL(argv[i + 1])); i++; } else { throw new Exception("Invalid command-line option: \"" + argv[i] + "\""); } } Authenticator.setDefault(new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("manager", "manager".toCharArray()); } }); statusGetter.queryStatus(); if (statusGetter.getStatus() == Status.NOT_RUNNING || statusGetter.getStatus() == Status.CONNECTION_REFUSED) { System.exit(3); // According to LSB: 3 - service not running } else if (statusGetter.getStatus() == Status.PARTIALLY_RUNNING) { /* * According to LSB: reserved for application So, I say 160 - * partially running */ System.exit(160); } else if (statusGetter.getStatus() == Status.RUNNING) { System.exit(0); // everything should be good and running } else { throw new Exception("Unknown status returned from " + "statusGetter.getStatus(): " + statusGetter.getStatus()); } } /** * <p>queryStatus</p> * * @throws java.lang.Exception if any. */ public void queryStatus() throws Exception { URLConnection connection = m_invokeURL.openConnection(); BufferedReader reader; try { connection.connect(); reader = new BufferedReader( new InputStreamReader( connection.getInputStream(), "UTF-8")); } catch (ConnectException e) { if (isVerbose()) { System.out.println("Could not connect to " + getInvokeURL().getHost() + " on port " + getInvokeURL().getPort() + " (OpenNMS might not be running or " + "could be starting up or shutting down): " + e.getMessage()); } m_status = Status.CONNECTION_REFUSED; return; } StringBuffer statusResultsBuf = new StringBuffer(); String line; while ((line = reader.readLine()) != null) { statusResultsBuf.append(line); statusResultsBuf.append("\n"); } String statusResults = statusResultsBuf.toString(); int i; if ((i = statusResults.indexOf("return=\"[")) == -1) { throw new Exception("could not find start of status results"); } statusResults = statusResults.substring(i + "return=\"[".length()); if ((i = statusResults.indexOf("]\"")) == -1) { throw new Exception("could not find end of status results"); } statusResults = statusResults.substring(0, i); LinkedHashMap<String, String> results = new LinkedHashMap<String, String>(); Pattern p = Pattern.compile("Status: OpenNMS:Name=(\\S+) = (\\S+)"); /* * Once we split a status entry, it will look like this: Status: * OpenNMS:Name=Eventd = RUNNING */ while (statusResults.length() > 0) { String result; i = statusResults.indexOf(", "); if (i == -1) { result = statusResults; } else { result = statusResults.substring(0, i); } Matcher m = p.matcher(result); if (!m.matches()) { throw new Exception("Result \"" + result + "\" does not match our regular expression"); } results.put(m.group(1), m.group(2)); if (i == -1) { break; } else { statusResults = statusResults.substring(i + ", ".length()); } } /* * We want our output to look like this: * OpenNMS.Eventd : running */ String spaces = " "; int running = 0; int services = 0; for (Entry<String, String> entry : results.entrySet()) { String daemon = entry.getKey(); String status = entry.getValue().toLowerCase(); services++; if (status.equals("running")) { running++; } if (m_verbose) { System.out.println("OpenNMS." + daemon + spaces.substring(daemon.length()) + ": " + status); } } if (services == 0) { m_status = Status.NOT_RUNNING; } else if (running != services) { m_status = Status.PARTIALLY_RUNNING; } else { m_status = Status.RUNNING; } } }