001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.gcrunner;
006:
007: import org.apache.commons.cli.CommandLine;
008: import org.apache.commons.cli.GnuParser;
009: import org.apache.commons.cli.HelpFormatter;
010: import org.apache.commons.cli.Option;
011: import org.apache.commons.cli.Options;
012: import org.apache.commons.cli.UnrecognizedOptionException;
013:
014: import com.tc.admin.TCStop;
015: import com.tc.logging.CustomerLogging;
016: import com.tc.logging.TCLogger;
017: import com.tc.management.JMXConnectorProxy;
018: import com.tc.management.beans.L2MBeanNames;
019: import com.tc.management.beans.object.ObjectManagementMonitorMBean;
020:
021: import java.io.IOException;
022: import java.lang.reflect.Method;
023: import java.util.Arrays;
024: import java.util.HashMap;
025:
026: import javax.management.MBeanServerConnection;
027: import javax.management.MBeanServerInvocationHandler;
028: import javax.management.remote.JMXConnector;
029:
030: /**
031: * Application that runs gc by interacting with ObjectManagementMonitorMBean. Expects 2 args: (1) hostname of machine
032: * running DSO server (2) jmx server port number
033: */
034: public class GCRunner {
035: private static final TCLogger consoleLogger = CustomerLogging
036: .getConsoleLogger();
037:
038: private String m_host;
039: private int m_port;
040: private String m_userName;
041:
042: public static final String DEFAULT_HOST = "localhost";
043: public static final int DEFAULT_PORT = 9520;
044:
045: public static void main(String[] args) throws Exception {
046: Options options = new Options();
047: CommandLine commandLine = null;
048:
049: Option hostOption = new Option("n", "hostname", true,
050: "Terracotta Server hostname");
051: hostOption.setType(String.class);
052: hostOption.setRequired(false);
053: hostOption.setArgName("l2-hostname");
054: options.addOption(hostOption);
055:
056: Option jmxPortOption = new Option("p", "jmxport", true,
057: "Terracotta Server JMX port");
058: jmxPortOption.setType(Integer.class);
059: jmxPortOption.setRequired(false);
060: jmxPortOption.setArgName("l2-jmx-port");
061: options.addOption(jmxPortOption);
062:
063: Option userNameOption = new Option("u", "username", true,
064: "user name");
065: userNameOption.setType(String.class);
066: userNameOption.setRequired(false);
067: options.addOption(userNameOption);
068:
069: Option helpOption = new Option("h", "help");
070: helpOption.setType(String.class);
071: helpOption.setRequired(false);
072: options.addOption(helpOption);
073:
074: try {
075: commandLine = new GnuParser().parse(options, args);
076: } catch (UnrecognizedOptionException e) {
077: System.err.println(e.getMessage());
078: usageAndDie(options);
079: }
080:
081: System.err.println("args: "
082: + Arrays.asList(commandLine.getArgs()));
083: if (commandLine == null || commandLine.getArgs().length > 2) {
084: usageAndDie(options);
085: }
086:
087: if (commandLine.hasOption("h")) {
088: new HelpFormatter().printHelp("java "
089: + TCStop.class.getName(), options);
090: System.exit(1);
091: }
092:
093: String userName = null;
094: if (commandLine.hasOption('u')) {
095: userName = commandLine.getOptionValue('u');
096: }
097:
098: String host = null;
099: int port = -1;
100:
101: if (commandLine.getArgs().length == 0) {
102: host = DEFAULT_HOST;
103: port = DEFAULT_PORT;
104: System.err
105: .println("No host or port provided. Invoking GC on Terracotta server at '"
106: + host + "', port " + port + " by default.");
107: } else if (commandLine.getArgs().length == 1) {
108: host = DEFAULT_HOST;
109: try {
110: port = Integer.parseInt(commandLine.getArgs()[0]);
111: } catch (NumberFormatException e) {
112: port = DEFAULT_PORT;
113: System.err
114: .println("Invalid port number specified. Using default port '"
115: + port + "'");
116: }
117: } else {
118: host = commandLine.getArgs()[0];
119: port = Integer.parseInt(commandLine.getArgs()[1]);
120: }
121:
122: try {
123: new GCRunner(host, port, userName).runGC();
124: } catch (IOException ioe) {
125: System.err
126: .println("Unable to connect to host '"
127: + host
128: + "', port "
129: + port
130: + ". Are you sure there is a Terracotta server running there?");
131: } catch (SecurityException se) {
132: System.err.println(se.getMessage());
133: usageAndDie(options);
134: }
135: }
136:
137: private static void usageAndDie(Options options) throws Exception {
138: new HelpFormatter().printHelp("java "
139: + GCRunner.class.getName(), options);
140: System.exit(1);
141: }
142:
143: public GCRunner(String host, int port) {
144: m_host = host;
145: m_port = port;
146: }
147:
148: public GCRunner(String host, int port, String userName) {
149: this (host, port);
150: m_userName = userName;
151: }
152:
153: private void runGC() throws Exception {
154: ObjectManagementMonitorMBean mbean = null;
155: final JMXConnector jmxConnector = getJMXConnector();
156: final MBeanServerConnection mbs = jmxConnector
157: .getMBeanServerConnection();
158: mbean = (ObjectManagementMonitorMBean) MBeanServerInvocationHandler
159: .newProxyInstance(mbs, L2MBeanNames.OBJECT_MANAGEMENT,
160: ObjectManagementMonitorMBean.class, false);
161: try {
162: mbean.runGC();
163: } catch (RuntimeException e) {
164: consoleLogger.error(e.getCause().getMessage());
165: }
166: }
167:
168: private static String getPassword() {
169: try {
170: Method m = System.class
171: .getMethod("console", new Class[] {});
172: Object console = m.invoke(null, (Object[]) null);
173: if (console != null) {
174: m = console.getClass().getMethod("readPassword",
175: new Class[] { String.class, Object[].class });
176: if (m != null) {
177: byte[] pw = (byte[]) m.invoke(console,
178: new Object[] { "[%s]",
179: "[console] Enter Password: " });
180: return new String(pw);
181: }
182: }
183: } catch (Exception e) {/**/
184: }
185:
186: try {
187: System.out.print("Enter password: ");
188: return new jline.ConsoleReader()
189: .readLine(new Character('*'));
190: } catch (Exception e) {/**/
191: }
192:
193: return null;
194: }
195:
196: private JMXConnector getJMXConnector() {
197: HashMap env = null;
198:
199: if (m_userName != null) {
200: env = new HashMap();
201: String[] creds = { m_userName, getPassword() };
202: env.put("jmx.remote.credentials", creds);
203: }
204:
205: return new JMXConnectorProxy(m_host, m_port, env);
206: }
207: }
|