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
020 import java.util.Collection;
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
029 /**
030 * A StopGracefullyCommand
031 *
032 */
033 public class StopGracefullyCommand extends ShutdownCommand {
034
035 protected String connectorName, queueName;
036 protected long timeout;
037 protected long pollInterval;
038 /**
039 * Constructor
040 */
041 public StopGracefullyCommand(){
042 super();
043 this.helpFile = new String[] {
044 "Task Usage: Main stopGracefully [stop-options] [broker-name1] [broker-name2] ...",
045 "Description: Stops a running broker if there is no pending messages in the queues. It first stops the connector for client connection, then check queuesize until it becomes 0 before stop the broker.",
046 "",
047 "Stop Options:",
048 " --connectorName <connectorName> connectorName to stop",
049 " --queueName <queueName> check the queuesize of the queueName for pending message",
050 " --timeout <timeout> periodically check the queuesize before the timeout expires",
051 " --pollInterval <pollInterval> the time interval it checks the queuesize",
052 " --jmxurl <url> Set the JMX URL to connect to.",
053 " --jmxuser <user> Set the JMX user used for authenticating.",
054 " --jmxpassword <password> Set the JMX password used for authenticating.",
055 " --jmxlocal Use the local JMX server instead of a remote one.",
056 " --localProcessId Use the local process id to connect( ignore jmxurl, jmxuser, jmxpassword), need to be root to use this option",
057 " --all Stop all brokers.",
058 " --version Display the version information.",
059 " -h,-?,--help Display the stop broker help information.",
060 "",
061 "Broker Names:",
062 " Name of the brokers that will be stopped.",
063 " If omitted, it is assumed that there is only one broker running, and it will be stopped.",
064 " Use -all to stop all running brokers.",
065 ""
066 };
067 }
068
069 /**
070 * Stops the list of brokers.
071 *
072 * @param jmxConnection - connection to the mbean server
073 * @param brokerBeans - broker mbeans to stop @throws Exception
074 */
075 protected void stopBrokers(MBeanServerConnection jmxConnection, Collection brokerBeans) throws Exception {
076 ObjectName brokerObjName;
077 for (Iterator i = brokerBeans.iterator(); i.hasNext();) {
078 brokerObjName = ((ObjectInstance)i.next()).getObjectName();
079
080 String brokerName = brokerObjName.getKeyProperty("BrokerName");
081 context.print("Stopping broker: " + brokerName);
082
083 try {
084 jmxConnection.invoke(brokerObjName, "stopGracefully", new Object[] {
085 connectorName, queueName, timeout, pollInterval
086 }, new String[] {
087 "java.lang.String", "java.lang.String", "long", "long"
088 });
089 context.print("Succesfully stopped broker: " + brokerName);
090 } catch (Exception e) {
091 if(!(e.getMessage().startsWith("Error unmarshaling return header"))){
092 context.print("Exception:"+e.getMessage());
093 }
094 }
095 }
096
097 closeJmxConnection();
098 }
099 /**
100 * @param token - option token to handle
101 * @param tokens - succeeding command arguments
102 * @throws Exception
103 */
104 protected void handleOption(String token, List<String> tokens) throws Exception {
105 // Try to handle the options first
106 if (token.equals("--connectorName")) {
107 if (tokens.isEmpty() || ((String)tokens.get(0)).startsWith("-")) {
108 context.printException(new IllegalArgumentException("connectorName not specified"));
109 return;
110 }
111
112 connectorName=(String)tokens.remove(0);
113 } else if (token.equals("--timeout")) {
114 if (tokens.isEmpty() || ((String)tokens.get(0)).startsWith("-")) {
115 context.printException(new IllegalArgumentException("timeout not specified"));
116 return;
117 }
118 timeout=Long.parseLong(tokens.remove(0));
119 } else if (token.equals("--pollInterval")) {
120 if (tokens.isEmpty() || ((String)tokens.get(0)).startsWith("-")) {
121 context.printException(new IllegalArgumentException("pollInterval not specified"));
122 return;
123 }
124 pollInterval=Long.parseLong(tokens.remove(0));
125 }else if(token.equals("--queueName")) {
126 if (tokens.isEmpty() || ((String)tokens.get(0)).startsWith("-")) {
127 context.printException(new IllegalArgumentException("queueName not specified"));
128 return;
129 }
130 queueName=(String)tokens.remove(0);
131 }else {
132 // Let the super class handle the option
133 super.handleOption(token, tokens);
134 }
135 }
136
137 }