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    import javax.management.remote.JMXServiceURL;
028    
029    import org.apache.activemq.console.util.JmxMBeansUtil;
030    
031    public class ShutdownCommand extends AbstractJmxCommand {
032    
033        protected String[] helpFile = new String[] {
034            "Task Usage: Main stop [stop-options] [broker-name1] [broker-name2] ...",
035            "Description: Stops a running broker.",
036            "", 
037            "Stop Options:",
038            "    --jmxurl <url>      Set the JMX URL to connect to.",
039            "    --all               Stop all brokers.",
040            "    --version           Display the version information.",
041            "    -h,-?,--help        Display the stop broker help information.",
042            "",
043            "Broker Names:",
044            "    Name of the brokers that will be stopped.",
045            "    If omitted, it is assumed that there is only one broker running, and it will be stopped.",
046            "    Use -all to stop all running brokers.",
047            ""
048        };
049    
050        private boolean isStopAllBrokers;
051    
052        /**
053         * Shuts down the specified broker or brokers
054         * 
055         * @param brokerNames - names of brokers to shutdown
056         * @throws Exception
057         */
058        protected void runTask(List brokerNames) throws Exception {
059            try {
060                Collection mbeans;
061    
062                // Stop all brokers
063                if (isStopAllBrokers) {
064                    mbeans = JmxMBeansUtil.getAllBrokers(useJmxServiceUrl());
065                    brokerNames.clear();
066                } else if (brokerNames.isEmpty()) {
067                    // Stop the default broker
068                    mbeans = JmxMBeansUtil.getAllBrokers(useJmxServiceUrl());
069    
070                    // If there is no broker to stop
071                    if (mbeans.isEmpty()) {
072                        context.printInfo("There are no brokers to stop.");
073                        return;
074    
075                        // There should only be one broker to stop
076                    } else if (mbeans.size() > 1) {
077                        context.printInfo("There are multiple brokers to stop. Please select the broker(s) to stop or use --all to stop all brokers.");
078                        return;
079    
080                        // Get the first broker only
081                    } else {
082                        Object firstBroker = mbeans.iterator().next();
083                        mbeans.clear();
084                        mbeans.add(firstBroker);
085                    }
086                } else {
087                    // Stop each specified broker
088                    String brokerName;
089                    mbeans = new HashSet();
090                    while (!brokerNames.isEmpty()) {
091                        brokerName = (String)brokerNames.remove(0);
092                        Collection matchedBrokers = JmxMBeansUtil.getBrokersByName(useJmxServiceUrl(), brokerName);
093                        if (matchedBrokers.isEmpty()) {
094                            context.printInfo(brokerName + " did not match any running brokers.");
095                        } else {
096                            mbeans.addAll(matchedBrokers);
097                        }
098                    }
099                }
100    
101                // Stop all brokers in set
102                stopBrokers(useJmxServiceUrl(), mbeans);
103            } catch (Exception e) {
104                context.printException(new RuntimeException("Failed to execute stop task. Reason: " + e));
105                throw new Exception(e);
106            }
107        }
108    
109        /**
110         * Stops the list of brokers.
111         * 
112         * @param jmxServiceUrl - JMX service url to connect to
113         * @param brokerBeans - broker mbeans to stop
114         * @throws Exception
115         */
116        protected void stopBrokers(JMXServiceURL jmxServiceUrl, Collection brokerBeans) throws Exception {
117            MBeanServerConnection server = createJmxConnector().getMBeanServerConnection();
118    
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                    server.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            closeJmxConnector();
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    }