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 /** 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}