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