OGAgent.java revision 682
58N/A/*
58N/A * CDDL HEADER START
58N/A *
58N/A * The contents of this file are subject to the terms of the
58N/A * Common Development and Distribution License (the "License").
58N/A * You may not use this file except in compliance with the License.
58N/A *
58N/A * See LICENSE.txt included in this distribution for the specific
58N/A * language governing permissions and limitations under the License.
58N/A *
58N/A * When distributing Covered Code, include this CDDL HEADER in each
58N/A * file and include the License file at LICENSE.txt.
58N/A * If applicable, add the following below this CDDL HEADER, with the
58N/A * fields enclosed by brackets "[]" replaced with your own identifying
58N/A * information: Portions Copyright [yyyy] [name of copyright owner]
58N/A *
58N/A * CDDL HEADER END
58N/A */
58N/A
58N/A/*
77N/A * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
58N/A * Use is subject to license terms.
58N/A */
58N/Apackage org.opensolaris.opengrok.management;
58N/A
58N/Aimport java.io.File;
58N/Aimport java.io.FileInputStream;
58N/Aimport java.io.IOException;
58N/Aimport java.io.InputStream;
58N/Aimport java.net.MalformedURLException;
58N/Aimport java.net.URI;
58N/Aimport java.net.URISyntaxException;
77N/Aimport java.net.URL;
77N/Aimport java.util.ArrayList;
77N/Aimport java.util.Date;
77N/Aimport java.util.HashMap;
58N/Aimport java.util.Properties;
58N/Aimport java.util.logging.Level;
58N/Aimport java.util.logging.Logger;
58N/Aimport javax.management.JMException;
58N/Aimport javax.management.MBeanServer;
58N/Aimport javax.management.MBeanServerFactory;
58N/Aimport javax.management.NotificationFilter;
58N/Aimport javax.management.ObjectName;
58N/Aimport javax.management.remote.JMXConnectorServer;
58N/Aimport javax.management.remote.JMXServiceURL;
65N/Aimport javax.management.remote.jmxmp.JMXMPConnectorServer;
77N/Aimport javax.management.remote.rmi.RMIConnectorServer;
58N/Aimport javax.management.timer.Timer;
58N/Aimport org.opensolaris.opengrok.Info;
58N/Aimport org.opensolaris.opengrok.OpenGrokLogger;
58N/A
58N/A/**
58N/A * OG Agent main class.
58N/A * Class for starting the basic components:
58N/A * Monitor and JMX and HTTP Connectors.
58N/A * @author Jan S Berg
58N/A */
58N/Apublic class OGAgent {
58N/A Properties props;
58N/A
58N/A private final static Logger log = Logger.getLogger("org.opensolaris.opengrok");
58N/A private MBeanServer server = null;
58N/A
58N/A
58N/A @SuppressWarnings("PMD.SystemPrintln")
58N/A private static boolean loadProperties(File file, InputStream in, Properties props) {
58N/A boolean ret = false;
58N/A try {
58N/A if (file != null) {
58N/A in = new FileInputStream(file);
58N/A }
58N/A props.load(in);
58N/A ret = true;
58N/A } catch (IOException e) {
58N/A System.err.println("Failed to read configuration");
58N/A e.printStackTrace();
58N/A ret = false;
58N/A } finally {
58N/A try {
58N/A in.close();
58N/A } catch (IOException e) {
58N/A System.err.println("Failed to close stream");
58N/A e.printStackTrace();
58N/A ret = false;
58N/A }
58N/A }
58N/A return ret;
58N/A }
58N/A
58N/A @SuppressWarnings("PMD.SystemPrintln")
58N/A public static void main(final String args[]) {
58N/A
58N/A Properties props = new Properties();
58N/A // Load default values
58N/A boolean success = loadProperties(null, OGAgent.class.getResourceAsStream("oga.properties"), props);
58N/A
58N/A File file = new File("/etc/opengrok/opengrok.properties");
58N/A if (file.exists()) {
58N/A success = loadProperties(file, null, props);
58N/A }
58N/A
58N/A // System properties should override default properties
58N/A props.putAll(System.getProperties());
58N/A
58N/A // @todo Add support for longopts!!
58N/A for (int i = 0; success && i < args.length; i++) {
58N/A if (args[i].startsWith("--agent=")) {
58N/A props.setProperty("agent", args[i].substring("--agent=".length()));
58N/A } else if (args[i].startsWith("--config=")) {
58N/A file = new File(args[i].substring("--config=".length()));
58N/A if (file.exists()) {
58N/A success = loadProperties(file, null, props);
58N/A } else {
58N/A success = false;
58N/A System.err.println("Cannot load file \"" + file.getAbsolutePath() + "\": No such file");
58N/A }
58N/A }
58N/A }
58N/A
58N/A URI uri = null;
77N/A if (success) {
65N/A try {
65N/A uri = new URI(props.getProperty("agent"));
65N/A } catch (URISyntaxException ex) {
65N/A success = false;
65N/A System.err.println("Failed to decode agent url");
65N/A ex.printStackTrace();
65N/A }
77N/A }
77N/A
77N/A if (success) {
77N/A if (props.getProperty("org.opensolaris.opengrok.management.logging.path") == null) {
77N/A props.setProperty("org.opensolaris.opengrok.management.logging.path",
77N/A uri.getPath());
77N/A }
77N/A
58N/A if (props.getProperty("org.opensolaris.opengrok.management.connection.host") == null) {
props.setProperty("org.opensolaris.opengrok.management.connection.host",
uri.getHost());
}
if (props.getProperty("org.opensolaris.opengrok.management.connection.port") == null) {
props.setProperty("org.opensolaris.opengrok.management.connection.port",
Integer.toString(uri.getPort()));
}
success = createLogger(props);
}
if (success) {
OGAgent oga = new OGAgent(props);
try {
oga.runOGA();
} catch (MalformedURLException e) {
log.log(Level.SEVERE, "Could not create connector server: " + e, e);
System.exit(1);
} catch (IOException e) {
log.log(Level.SEVERE, "Could not start connector server: " + e, e);
System.exit(2);
} catch (Exception ex) {
Logger.getLogger(OGAgent.class.getName()).log(Level.SEVERE, null, ex);
System.exit(1);
}
} else {
System.exit(1);
}
}
private OGAgent(Properties props) {
this.props = props;
}
public final void runOGA() throws MalformedURLException, IOException, JMException {
String machinename = java.net.InetAddress.getLocalHost().getHostName();
String javaver = System.getProperty("java.version");
log.info("Starting " + Info.getFullVersion() +
" JMX Agent, with java version " + javaver);
//create mbeanserver
String connprotocol = props.getProperty("org.opensolaris.opengrok.management.connection.protocol", "jmxmp");
int connectorport = Integer.parseInt(props.getProperty("org.opensolaris.opengrok.management.connection.port"));
log.fine("Using protocol " + connprotocol + ", port: " + connectorport);
ArrayList mbservs = MBeanServerFactory.findMBeanServer(null);
log.fine("Finding MBeanservers, size " + mbservs.size());
if (mbservs.isEmpty()) {
server = MBeanServerFactory.createMBeanServer();
} else {
server = (MBeanServer) mbservs.get(0);
}
//instantiate and register OGAManagement
ObjectName manager = new ObjectName("OGA:name=Management");
server.registerMBean(Management.getInstance(props), manager);
//instantiate and register OGA:JMXConfiguration
ObjectName config = new ObjectName("OGA:name=JMXConfiguration");
JMXConfiguration jc = new JMXConfiguration();
server.registerMBean(jc, config);
//instantiate and register Timer service and resource purger
createIndexTimer(props);
log.info("MBeans registered");
// Create and start connector server
log.fine("Starting JMX connector");
HashMap<String, Object> env = new HashMap<String, Object>();
JMXServiceURL url = new JMXServiceURL(connprotocol, machinename, connectorport);
JMXConnectorServer connectorServer = null;
if ("jmxmp".equals(connprotocol)) {
connectorServer = new JMXMPConnectorServer(url, env, server);
} else if ("rmi".equals(connprotocol) || "iiop".equals(connprotocol)) {
connectorServer = new RMIConnectorServer(url, env, server);
} else {
throw new IOException("Unknown connector protocol");
}
connectorServer.start();
log.info("OGA is ready and running...");
}
private void createIndexTimer(Properties properties) throws IOException, JMException {
//instantiate, register and start the Timer service
ObjectName timer = new ObjectName("service:name=timer");
server.registerMBean(new Timer(), timer);
server.invoke(timer, "start", null, null);
log.info("Started timer service");
boolean enabled = Boolean.parseBoolean(properties.getProperty("org.opensolaris.opengrok.management.indexer.enabled"));
int period = Integer.parseInt(properties.getProperty("org.opensolaris.opengrok.management.indexer.sleeptime"));
log.fine("Indexer enabled: " + enabled);
log.fine("Indexer period: " + period + " seconds");
//instantiate and register resource purger
ObjectName indexRunner = new ObjectName("OGA:name=AgentIndexRunner," + "source=timer");
server.registerMBean(AgentIndexRunner.getInstance(enabled), indexRunner);
// Add index notification to timer (read from org.opensolaris.opengrok.management.indexer.sleeptime property).
Date date = new Date(System.currentTimeMillis() + Timer.ONE_SECOND * 5);
Long longPeriod = Long.valueOf(period * Timer.ONE_SECOND);
Integer id = (Integer) server.invoke(timer, "addNotification",
new Object[]{"timer.notification", // Type
"Time to index again", // Message
null, // user data
date, // Start time
longPeriod, // Period
},
new String[]{String.class.getName(),
String.class.getName(),
Object.class.getName(),
Date.class.getName(),
"long",});
// Add indexer as listener to index notifications
NotificationFilter filter = new TimerFilter(id);
server.addNotificationListener(timer, indexRunner, filter, null);
}
@SuppressWarnings("PMD.SystemPrintln")
private static boolean createLogger(Properties props) {
boolean ret = true;
String OGAlogpath = props.getProperty("org.opensolaris.opengrok.management.logging.path");
Level loglevel = null;
try {
loglevel = Level.parse(props.getProperty("org.opensolaris.opengrok.management.logging.filelevel"));
} catch (Exception exll) {
loglevel = Level.FINE;
}
Level consoleloglevel = null;
try {
consoleloglevel = Level.parse(props.getProperty("org.opensolaris.opengrok.management.logging.consolelevel"));
} catch (Exception excl) {
consoleloglevel = Level.INFO;
}
try {
OpenGrokLogger.setupLogger(OGAlogpath, loglevel, consoleloglevel);
} catch (IOException ex) {
System.err.println("OGAgent failed set up logging: " + ex);
ret = false;
}
return ret;
}
}