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 */ 017package org.apache.activemq.console.command; 018 019import java.util.Collection; 020import java.util.HashSet; 021import java.util.Iterator; 022import java.util.List; 023 024import javax.management.MBeanServerConnection; 025import javax.management.ObjectInstance; 026import javax.management.ObjectName; 027 028import org.apache.activemq.console.util.JmxMBeansUtil; 029 030public 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 @Override 056 public String getName() { 057 return "stop"; 058 } 059 060 @Override 061 public String getOneLineDescription() { 062 return "Stops a running broker specified by the broker name."; 063 } 064 065 /** 066 * Shuts down the specified broker or brokers 067 * 068 * @param brokerNames - names of brokers to shutdown 069 * @throws Exception 070 */ 071 protected void runTask(List brokerNames) throws Exception { 072 try { 073 Collection mbeans; 074 075 // Stop all brokers 076 if (isStopAllBrokers) { 077 mbeans = JmxMBeansUtil.getAllBrokers(createJmxConnection()); 078 brokerNames.clear(); 079 } else if (brokerNames.isEmpty()) { 080 // Stop the default broker 081 mbeans = JmxMBeansUtil.getAllBrokers(createJmxConnection()); 082 // If there is no broker to stop 083 if (mbeans.isEmpty()) { 084 context.printInfo("There are no brokers to stop."); 085 return; 086 087 // There should only be one broker to stop 088 } else if (mbeans.size() > 1) { 089 context.printInfo("There are multiple brokers to stop. Please select the broker(s) to stop or use --all to stop all brokers."); 090 return; 091 092 // Get the first broker only 093 } else { 094 Object firstBroker = mbeans.iterator().next(); 095 mbeans.clear(); 096 mbeans.add(firstBroker); 097 } 098 } else { 099 // Stop each specified broker 100 String brokerName; 101 mbeans = new HashSet(); 102 while (!brokerNames.isEmpty()) { 103 brokerName = (String)brokerNames.remove(0); 104 Collection matchedBrokers = JmxMBeansUtil.getBrokersByName(createJmxConnection(), brokerName); 105 if (matchedBrokers.isEmpty()) { 106 context.printInfo(brokerName + " did not match any running brokers."); 107 } else { 108 mbeans.addAll(matchedBrokers); 109 } 110 } 111 } 112 113 // Stop all brokers in set 114 stopBrokers(createJmxConnection(), mbeans); 115 } catch (Exception e) { 116 context.printException(new RuntimeException("Failed to execute stop task. Reason: " + e)); 117 throw new Exception(e); 118 } 119 } 120 121 /** 122 * Stops the list of brokers. 123 * 124 * @param jmxConnection - connection to the mbean server 125 * @param brokerBeans - broker mbeans to stop @throws Exception 126 */ 127 protected void stopBrokers(MBeanServerConnection jmxConnection, Collection brokerBeans) throws Exception { 128 ObjectName brokerObjName; 129 for (Iterator i = brokerBeans.iterator(); i.hasNext();) { 130 brokerObjName = ((ObjectInstance)i.next()).getObjectName(); 131 132 String brokerName = brokerObjName.getKeyProperty("brokerName"); 133 context.print("Stopping broker: " + brokerName); 134 135 try { 136 jmxConnection.invoke(brokerObjName, "terminateJVM", new Object[] { 137 Integer.valueOf(0) 138 }, new String[] { 139 "int" 140 }); 141 context.print("Succesfully stopped broker: " + brokerName); 142 } catch (Exception e) { 143 // TODO: Check exceptions throwned 144 // System.out.println("Failed to stop broker: [ " + brokerName + 145 // " ]. Reason: " + e.getMessage()); 146 } 147 } 148 149 closeJmxConnection(); 150 } 151 152 /** 153 * Handle the --all option. 154 * 155 * @param token - option token to handle 156 * @param tokens - succeeding command arguments 157 * @throws Exception 158 */ 159 protected void handleOption(String token, List<String> tokens) throws Exception { 160 // Try to handle the options first 161 if (token.equals("--all")) { 162 isStopAllBrokers = true; 163 } else { 164 // Let the super class handle the option 165 super.handleOption(token, tokens); 166 } 167 } 168 169 /** 170 * Print the help messages for the browse command 171 */ 172 protected void printHelp() { 173 context.printHelp(helpFile); 174 } 175 176}