001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tc.admin;
005:
006: import org.apache.commons.cli.CommandLine;
007: import org.apache.commons.cli.GnuParser;
008: import org.apache.commons.cli.HelpFormatter;
009: import org.apache.commons.cli.Option;
010: import org.apache.commons.cli.Options;
011: import org.apache.commons.cli.UnrecognizedOptionException;
012: import org.apache.commons.lang.ArrayUtils;
013:
014: import com.tc.config.schema.NewCommonL2Config;
015: import com.tc.config.schema.setup.FatalIllegalConfigurationChangeHandler;
016: import com.tc.config.schema.setup.L2TVSConfigurationSetupManager;
017: import com.tc.config.schema.setup.StandardTVSConfigurationSetupManagerFactory;
018: import com.tc.config.schema.setup.TVSConfigurationSetupManagerFactory;
019: import com.tc.management.JMXConnectorProxy;
020: import com.tc.management.TerracottaManagement;
021: import com.tc.management.beans.L2MBeanNames;
022: import com.tc.management.beans.TCServerInfoMBean;
023:
024: import java.io.File;
025: import java.io.IOException;
026: import java.lang.reflect.Method;
027: import java.net.ConnectException;
028: import java.util.ArrayList;
029: import java.util.Arrays;
030: import java.util.HashMap;
031:
032: import javax.management.MBeanServerConnection;
033: import javax.management.remote.JMXConnector;
034:
035: public class TCStop {
036:
037: private String m_host;
038: private int m_port;
039: private String m_userName;
040:
041: public static final String DEFAULT_HOST = "localhost";
042: public static final int DEFAULT_PORT = 9520;
043:
044: public static final void main(String[] args) throws Exception {
045: Options options = StandardTVSConfigurationSetupManagerFactory
046: .createOptions(true);
047: CommandLine commandLine = null;
048:
049: Option userNameOption = new Option("u", "username", true,
050: "user name");
051: userNameOption.setType(String.class);
052: userNameOption.setRequired(false);
053: options.addOption(userNameOption);
054:
055: Option helpOption = new Option("h", "help");
056: helpOption.setType(String.class);
057: helpOption.setRequired(false);
058: options.addOption(helpOption);
059:
060: try {
061: commandLine = new GnuParser().parse(options, args);
062: } catch (UnrecognizedOptionException e) {
063: System.err.println(e.getMessage());
064: usageAndDie(options);
065: }
066:
067: if (commandLine == null || commandLine.getArgs().length > 2) {
068: usageAndDie(options);
069: }
070:
071: String host = null;
072: int port = -1;
073:
074: if (commandLine.hasOption("h")) {
075: new HelpFormatter().printHelp("java "
076: + TCStop.class.getName(), options);
077: System.exit(1);
078: }
079:
080: String defaultName = StandardTVSConfigurationSetupManagerFactory.DEFAULT_CONFIG_SPEC;
081: File configFile = new File(System.getProperty("user.dir"),
082: defaultName);
083: boolean configSpecified = commandLine.hasOption('f');
084: boolean nameSpecified = commandLine.hasOption('n');
085: boolean userNameSpecified = commandLine.hasOption('u');
086:
087: String userName = null;
088: if (userNameSpecified) {
089: userName = commandLine.getOptionValue('u');
090: }
091:
092: if (configSpecified || System.getProperty("tc.config") != null
093: || configFile.exists()) {
094: if (!configSpecified
095: && System.getProperty("tc.config") == null) {
096: ArrayList tmpArgs = new ArrayList(Arrays.asList(args));
097:
098: tmpArgs.add("-f");
099: tmpArgs.add(configFile.getAbsolutePath());
100: args = (String[]) tmpArgs.toArray(new String[tmpArgs
101: .size()]);
102: }
103:
104: FatalIllegalConfigurationChangeHandler changeHandler = new FatalIllegalConfigurationChangeHandler();
105: TVSConfigurationSetupManagerFactory factory = new StandardTVSConfigurationSetupManagerFactory(
106: args, true, changeHandler);
107:
108: String name = null;
109: if (nameSpecified) {
110: name = commandLine.getOptionValue('n');
111: }
112:
113: L2TVSConfigurationSetupManager manager = factory
114: .createL2TVSConfigurationSetupManager(name);
115: String[] servers = manager.allCurrentlyKnownServers();
116:
117: if (nameSpecified && !Arrays.asList(servers).contains(name)) {
118: System.err
119: .println("The specified Terracotta server configuration '"
120: + name + "' does not exist; exiting.");
121: System.exit(1);
122: }
123:
124: if (name == null && servers != null && servers.length == 1) {
125: name = servers[0];
126: System.err
127: .println("There is only one Terracotta server in this configuration file ("
128: + name + "); stopping it.");
129: } else if (name == null && servers != null
130: && servers.length > 1) {
131: System.err
132: .println("There are multiple Terracotta servers defined in this configuration file; please specify "
133: + "which one you want to stop, using the '-n' command-line option. Available servers are:\n"
134: + " " + ArrayUtils.toString(servers));
135: System.exit(1);
136: }
137:
138: NewCommonL2Config serverConfig = manager
139: .commonL2ConfigFor(name);
140:
141: host = serverConfig.host().getString();
142: if (host == null)
143: host = name;
144: if (host == null)
145: host = DEFAULT_HOST;
146: port = serverConfig.jmxPort().getInt();
147: System.err.println("Host: " + host + ", port: " + port);
148: } else {
149: if (commandLine.getArgs().length == 0) {
150: host = DEFAULT_HOST;
151: port = DEFAULT_PORT;
152: System.err
153: .println("No host or port provided. Stopping the Terracotta server at '"
154: + host
155: + "', port "
156: + port
157: + " by default.");
158: } else if (commandLine.getArgs().length == 1) {
159: host = DEFAULT_HOST;
160: port = Integer.parseInt(commandLine.getArgs()[0]);
161: } else {
162: host = commandLine.getArgs()[0];
163: port = Integer.parseInt(commandLine.getArgs()[1]);
164: }
165: }
166:
167: try {
168: new TCStop(host, port, userName).stop();
169: } catch (SecurityException se) {
170: System.err.println(se.getMessage());
171: usageAndDie(options);
172: } catch (Exception e) {
173: Throwable root = getRootCause(e);
174: if (root instanceof ConnectException) {
175: System.err
176: .println("Unable to connect to host '"
177: + host
178: + "', port "
179: + port
180: + ". Are you sure there is a Terracotta server running there?");
181: }
182: }
183: }
184:
185: private static Throwable getRootCause(Throwable e) {
186: Throwable t = e;
187: while (t != null) {
188: e = t;
189: t = t.getCause();
190: }
191: return e;
192: }
193:
194: private static void usageAndDie(Options options) throws Exception {
195: new HelpFormatter().printHelp("java " + TCStop.class.getName(),
196: options);
197: System.exit(1);
198: }
199:
200: public TCStop(String host, int port) {
201: m_host = host;
202: m_port = port;
203: }
204:
205: public TCStop(String host, int port, String userName) {
206: this (host, port);
207: m_userName = userName;
208: }
209:
210: public void stop() throws IOException {
211: JMXConnector jmxc = getJMXConnector();
212: MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
213:
214: if (mbsc != null) {
215: TCServerInfoMBean tcServerInfo = (TCServerInfoMBean) TerracottaManagement
216: .findMBean(L2MBeanNames.TC_SERVER_INFO,
217: TCServerInfoMBean.class, mbsc);
218: try {
219: tcServerInfo.shutdown();
220: } finally {
221: jmxc.close();
222: }
223: }
224: }
225:
226: private static String getPassword() {
227: try {
228: Method m = System.class
229: .getMethod("console", new Class[] {});
230: Object console = m.invoke(null, (Object[]) null);
231: if (console != null) {
232: m = console.getClass().getMethod("readPassword",
233: new Class[] { String.class, Object[].class });
234: if (m != null) {
235: byte[] pw = (byte[]) m.invoke(console,
236: new Object[] { "[%s]",
237: "[console] Enter Password: " });
238: return new String(pw);
239: }
240: }
241: } catch (Exception e) {/**/
242: }
243:
244: try {
245: System.out.print("Enter password: ");
246: return new jline.ConsoleReader()
247: .readLine(new Character('*'));
248: } catch (Exception e) {/**/
249: }
250:
251: return null;
252: }
253:
254: private JMXConnector getJMXConnector() {
255: HashMap env = null;
256:
257: if (m_userName != null) {
258: env = new HashMap();
259: String[] creds = { m_userName, getPassword() };
260: env.put("jmx.remote.credentials", creds);
261: }
262:
263: return new JMXConnectorProxy(m_host, m_port, env);
264: }
265: }
|