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 018 package org.apache.activemq.console.command; 019 020 import java.net.URI; 021 import java.net.URISyntaxException; 022 import java.util.ArrayList; 023 import java.util.Iterator; 024 import java.util.List; 025 import java.util.concurrent.atomic.AtomicInteger; 026 027 import org.apache.activemq.broker.BrokerFactory; 028 import org.apache.activemq.broker.BrokerService; 029 030 public class StartCommand extends AbstractCommand { 031 032 public static final String DEFAULT_CONFIG_URI = "xbean:activemq.xml"; 033 034 protected String[] helpFile = new String[] { 035 "Task Usage: Main start [start-options] [uri]", 036 "Description: Creates and starts a broker using a configuration file, or a broker URI.", 037 "", 038 "Start Options:", 039 " -D<name>=<value> Define a system property.", 040 " --version Display the version information.", 041 " -h,-?,--help Display the start broker help information.", 042 "", 043 "URI:", 044 "", 045 " XBean based broker configuration:", 046 "", 047 " Example: Main xbean:file:activemq.xml", 048 " Loads the xbean configuration file from the current working directory", 049 " Example: Main xbean:activemq.xml", 050 " Loads the xbean configuration file from the classpath", 051 "", 052 " URI Parameter based broker configuration:", 053 "", 054 " Example: Main broker:(tcp://localhost:61616, tcp://localhost:5000)?useJmx=true", 055 " Configures the broker with 2 transport connectors and jmx enabled", 056 " Example: Main broker:(tcp://localhost:61616, network:tcp://localhost:5000)?persistent=false", 057 " Configures the broker with 1 transport connector, and 1 network connector and persistence disabled", 058 "" 059 }; 060 061 private URI configURI; 062 private List<BrokerService> brokers = new ArrayList<BrokerService>(5); 063 064 /** 065 * The default task to start a broker or a group of brokers 066 * 067 * @param brokerURIs 068 */ 069 protected void runTask(List<String> brokerURIs) throws Exception { 070 try { 071 // If no config uri, use default setting 072 if (brokerURIs.isEmpty()) { 073 setConfigUri(new URI(DEFAULT_CONFIG_URI)); 074 startBroker(getConfigUri()); 075 076 // Set configuration data, if available, which in this case 077 // would be the config URI 078 } else { 079 String strConfigURI; 080 081 while (!brokerURIs.isEmpty()) { 082 strConfigURI = (String)brokerURIs.remove(0); 083 084 try { 085 setConfigUri(new URI(strConfigURI)); 086 } catch (URISyntaxException e) { 087 context.printException(e); 088 return; 089 } 090 091 startBroker(getConfigUri()); 092 } 093 } 094 095 // Prevent the main thread from exiting unless it is terminated 096 // elsewhere 097 } catch (Exception e) { 098 context.printException(new RuntimeException("Failed to execute start task. Reason: " + e, e)); 099 throw new Exception(e); 100 } 101 102 // The broker start up fine. If this unblocks it's cause they were stopped 103 // and this would occur because of an internal error (like the DB going offline) 104 waitForShutdown(); 105 } 106 107 /** 108 * Create and run a broker specified by the given configuration URI 109 * 110 * @param configURI 111 * @throws Exception 112 */ 113 public void startBroker(URI configURI) throws Exception { 114 System.out.println("Loading message broker from: " + configURI); 115 BrokerService broker = BrokerFactory.createBroker(configURI); 116 brokers.add(broker); 117 broker.start(); 118 } 119 120 /** 121 * Wait for a shutdown invocation elsewhere 122 * 123 * @throws Exception 124 */ 125 protected void waitForShutdown() throws Exception { 126 final boolean[] shutdown = new boolean[] { 127 false 128 }; 129 130 Runtime.getRuntime().addShutdownHook(new Thread() { 131 public void run() { 132 for (Iterator<BrokerService> i = brokers.iterator(); i.hasNext();) { 133 try { 134 BrokerService broker = i.next(); 135 broker.stop(); 136 } catch (Exception e) { 137 } 138 } 139 } 140 }); 141 142 final AtomicInteger brokerCounter = new AtomicInteger(brokers.size()); 143 for (BrokerService bs : brokers) { 144 bs.addShutdownHook(new Runnable() { 145 public void run() { 146 // When the last broker lets us know he is closed.... 147 if( brokerCounter.decrementAndGet() == 0 ) { 148 synchronized (shutdown) { 149 shutdown[0] = true; 150 shutdown.notify(); 151 } 152 } 153 } 154 }); 155 } 156 157 // Wait for any shutdown event 158 synchronized (shutdown) { 159 while (!shutdown[0]) { 160 try { 161 shutdown.wait(); 162 } catch (InterruptedException e) { 163 } 164 } 165 } 166 167 } 168 169 /** 170 * Sets the current configuration URI used by the start task 171 * 172 * @param uri 173 */ 174 public void setConfigUri(URI uri) { 175 configURI = uri; 176 } 177 178 /** 179 * Gets the current configuration URI used by the start task 180 * 181 * @return current configuration URI 182 */ 183 public URI getConfigUri() { 184 return configURI; 185 } 186 187 /** 188 * Print the help messages for the browse command 189 */ 190 protected void printHelp() { 191 context.printHelp(helpFile); 192 } 193 194 }