001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.activemq.console.command;
018
019 import java.util.Collection;
020 import java.util.HashSet;
021 import java.util.Iterator;
022 import java.util.List;
023
024 import javax.management.MBeanServerConnection;
025 import javax.management.ObjectInstance;
026 import javax.management.ObjectName;
027
028 import org.apache.activemq.console.util.JmxMBeansUtil;
029
030 public class ShutdownCommand extends AbstractJmxCommand {
031
032 protected String[] helpFile = new String[] {
033 "Task Usage: Main stop [stop-options] [broker-name1] [broker-name2] ...",
034 "Description: Stops a running broker.",
035 "",
036 "Stop Options:",
037 " --jmxurl <url> Set the JMX URL to connect to.",
038 " --pid <pid> Set the pid to connect to (only on Sun JVM).",
039 " --jmxuser <user> Set the JMX user used for authenticating.",
040 " --jmxpassword <password> Set the JMX password used for authenticating.",
041 " --jmxlocal Use the local JMX server instead of a remote one.",
042 " --all Stop all brokers.",
043 " --version Display the version information.",
044 " -h,-?,--help Display the stop broker help information.",
045 "",
046 "Broker Names:",
047 " Name of the brokers that will be stopped.",
048 " If omitted, it is assumed that there is only one broker running, and it will be stopped.",
049 " Use -all to stop all running brokers.",
050 ""
051 };
052
053 private boolean isStopAllBrokers;
054
055 /**
056 * Shuts down the specified broker or brokers
057 *
058 * @param brokerNames - names of brokers to shutdown
059 * @throws Exception
060 */
061 protected void runTask(List brokerNames) throws Exception {
062 try {
063 Collection mbeans;
064
065 // Stop all brokers
066 if (isStopAllBrokers) {
067 mbeans = JmxMBeansUtil.getAllBrokers(createJmxConnection());
068 brokerNames.clear();
069 } else if (brokerNames.isEmpty()) {
070 // Stop the default broker
071 mbeans = JmxMBeansUtil.getAllBrokers(createJmxConnection());
072
073 // If there is no broker to stop
074 if (mbeans.isEmpty()) {
075 context.printInfo("There are no brokers to stop.");
076 return;
077
078 // There should only be one broker to stop
079 } else if (mbeans.size() > 1) {
080 context.printInfo("There are multiple brokers to stop. Please select the broker(s) to stop or use --all to stop all brokers.");
081 return;
082
083 // Get the first broker only
084 } else {
085 Object firstBroker = mbeans.iterator().next();
086 mbeans.clear();
087 mbeans.add(firstBroker);
088 }
089 } else {
090 // Stop each specified broker
091 String brokerName;
092 mbeans = new HashSet();
093 while (!brokerNames.isEmpty()) {
094 brokerName = (String)brokerNames.remove(0);
095 Collection matchedBrokers = JmxMBeansUtil.getBrokersByName(createJmxConnection(), brokerName);
096 if (matchedBrokers.isEmpty()) {
097 context.printInfo(brokerName + " did not match any running brokers.");
098 } else {
099 mbeans.addAll(matchedBrokers);
100 }
101 }
102 }
103
104 // Stop all brokers in set
105 stopBrokers(createJmxConnection(), mbeans);
106 } catch (Exception e) {
107 context.printException(new RuntimeException("Failed to execute stop task. Reason: " + e));
108 throw new Exception(e);
109 }
110 }
111
112 /**
113 * Stops the list of brokers.
114 *
115 * @param jmxConnection - connection to the mbean server
116 * @param brokerBeans - broker mbeans to stop @throws Exception
117 */
118 protected void stopBrokers(MBeanServerConnection jmxConnection, Collection brokerBeans) throws Exception {
119 ObjectName brokerObjName;
120 for (Iterator i = brokerBeans.iterator(); i.hasNext();) {
121 brokerObjName = ((ObjectInstance)i.next()).getObjectName();
122
123 String brokerName = brokerObjName.getKeyProperty("BrokerName");
124 context.print("Stopping broker: " + brokerName);
125
126 try {
127 jmxConnection.invoke(brokerObjName, "terminateJVM", new Object[] {
128 Integer.valueOf(0)
129 }, new String[] {
130 "int"
131 });
132 context.print("Succesfully stopped broker: " + brokerName);
133 } catch (Exception e) {
134 // TODO: Check exceptions throwned
135 // System.out.println("Failed to stop broker: [ " + brokerName +
136 // " ]. Reason: " + e.getMessage());
137 }
138 }
139
140 closeJmxConnection();
141 }
142
143 /**
144 * Handle the --all option.
145 *
146 * @param token - option token to handle
147 * @param tokens - succeeding command arguments
148 * @throws Exception
149 */
150 protected void handleOption(String token, List<String> tokens) throws Exception {
151 // Try to handle the options first
152 if (token.equals("--all")) {
153 isStopAllBrokers = true;
154 } else {
155 // Let the super class handle the option
156 super.handleOption(token, tokens);
157 }
158 }
159
160 /**
161 * Print the help messages for the browse command
162 */
163 protected void printHelp() {
164 context.printHelp(helpFile);
165 }
166
167 }