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.maven; 018 019import java.util.Properties; 020 021import org.apache.activemq.broker.TransportConnector; 022import org.apache.maven.plugin.AbstractMojo; 023import org.apache.maven.plugin.MojoExecutionException; 024import org.apache.maven.project.MavenProject; 025 026/** 027 * Goal which starts an activemq broker. 028 * 029 * @goal run 030 * @phase process-sources 031 */ 032public class StartBrokerMojo extends AbstractMojo { 033 /** 034 * Default connector property name format. 035 */ 036 public static final String DEFAULT_CONNECTOR_PROPERTY_NAME_FORMAT = "org.apache.activemq.connector.%s.uri"; 037 038 /** 039 * The maven project. 040 * 041 * @parameter property="project" default-value="${project}" 042 * @required 043 * @readonly 044 */ 045 protected MavenProject project; 046 047 /** 048 * The broker configuration uri The list of currently supported URI syntaxes 049 * is described <a 050 * href="http://activemq.apache.org/how-do-i-embed-a-broker-inside-a-connection.html">here</a> 051 * 052 * @parameter property="configUri" 053 * default-value="broker:(tcp://localhost:61616)?useJmx=false&persistent=false" 054 * @required 055 */ 056 private String configUri; 057 058 /** 059 * Indicates whether to fork the broker, useful for integration tests. 060 * 061 * @parameter property="fork" default-value="false" 062 */ 063 private boolean fork; 064 065 /** 066 * System properties to add 067 * 068 * @parameter property="systemProperties" 069 */ 070 private Properties systemProperties; 071 072 /** 073 * Skip execution of the ActiveMQ Broker plugin if set to true 074 * 075 * @parameter property="skip" 076 */ 077 private boolean skip; 078 079 /** 080 * Format of the connector URI property names. The first argument for the format is the connector name. 081 * 082 * @parameter property="connectorPropertyNameFormat" 083 */ 084 private String connectorPropertyNameFormat = DEFAULT_CONNECTOR_PROPERTY_NAME_FORMAT; 085 086 /** 087 * Broker manager used to start and stop the broker. 088 */ 089 private MavenBrokerManager brokerManager; 090 091 /** 092 * XBean File Resolver used to detect and transform xbean file URIs. 093 */ 094 private XBeanFileResolver xBeanFileResolver = new XBeanFileResolver(); 095 096 /** 097 * Retrieve the Maven project for this mojo. 098 * 099 * @return the Maven project. 100 */ 101 public MavenProject getProject() { 102 return project; 103 } 104 105 /** 106 * Set the Maven project for this mojo. 107 * 108 * @param project the Maven project. 109 */ 110 public void setProject(MavenProject project) { 111 this.project = project; 112 } 113 114 /** 115 * Retrieve the URI used to configure the broker on startup. 116 * 117 * @return the configuration URI. 118 */ 119 public String getConfigUri() { 120 return configUri; 121 } 122 123 /** 124 * Set the URI used to configure the broker on startup. 125 * 126 * @param configUri the URI used to configure the broker. 127 */ 128 public void setConfigUri(String configUri) { 129 this.configUri = configUri; 130 } 131 132 /** 133 * Determine if the mojo is configured to fork a broker. 134 * 135 * @return true => the mojo will fork a broker (i.e. start it in the background); false => start the broker and 136 * wait synchronously for it to terminate. 137 */ 138 public boolean isFork() { 139 return fork; 140 } 141 142 /** 143 * Configure the mojo to run the broker asynchronously (i.e. fork) or synchronously. 144 * 145 * @param fork true => start the broker asynchronously; true => start the broker synchronously. 146 */ 147 public void setFork(boolean fork) { 148 this.fork = fork; 149 } 150 151 /** 152 * Determine if the mojo is configured to skip the broker startup. 153 * 154 * @return true => the mojo will skip the broker startup; false => the mojo will start the broker normally. 155 */ 156 public boolean isSkip() { 157 return skip; 158 } 159 160 /** 161 * Configure the mojo to skip or normally execute the broker startup. 162 * 163 * @param skip true => the mojo will skip the broker startup; false => the mojo will start the broker normally. 164 */ 165 public void setSkip(boolean skip) { 166 this.skip = skip; 167 } 168 169 /** 170 * Retrieve properties to add to the System properties on broker startup. 171 * 172 * @return properties to add to the System properties. 173 */ 174 public Properties getSystemProperties() { 175 return systemProperties; 176 } 177 178 /** 179 * Set properties to add to the System properties on broker startup. 180 * 181 * @param systemProperties properties to add to the System properties. 182 */ 183 public void setSystemProperties(Properties systemProperties) { 184 this.systemProperties = systemProperties; 185 } 186 187 /** 188 * Retrieve the format used to generate property names when registering connector URIs. 189 * 190 * @return the format used to generate property names. 191 */ 192 public String getConnectorPropertyNameFormat() { 193 return connectorPropertyNameFormat; 194 } 195 196 /** 197 * Set the format used to generate property names when registering connector URIs. 198 * 199 * @param connectorPropertyNameFormat the new format to use when generating property names. 200 */ 201 public void setConnectorPropertyNameFormat(String connectorPropertyNameFormat) { 202 this.connectorPropertyNameFormat = connectorPropertyNameFormat; 203 } 204 205 /** 206 * Retrieve the manager used to create and retain the started broker. 207 * 208 * @return the manager. 209 */ 210 public MavenBrokerManager getBrokerManager() { 211 return brokerManager; 212 } 213 214 /** 215 * Set the manager used to create and retain the started broker. 216 * 217 * @param brokerManager the new manager to use. 218 */ 219 public void setBrokerManager(MavenBrokerManager brokerManager) { 220 this.brokerManager = brokerManager; 221 } 222 223 /** 224 * Retrieve the XBeanFileResolver used to detect and transform XBean URIs. 225 * 226 * @return the XBeanFileResolver used. 227 */ 228 public XBeanFileResolver getxBeanFileResolver() { 229 return xBeanFileResolver; 230 } 231 232 /** 233 * Set the XBeanFileResolver to use when detecting and transforming XBean URIs. 234 * 235 * @param xBeanFileResolver the XBeanFileResolver to use. 236 */ 237 public void setxBeanFileResolver(XBeanFileResolver xBeanFileResolver) { 238 this.xBeanFileResolver = xBeanFileResolver; 239 } 240 241 /** 242 * Perform the mojo operation, which starts the ActiveMQ broker unless configured to skip it. Also registers the 243 * connector URIs in the maven project properties on startup, which enables the use of variable substitution in 244 * the pom.xml file to determine the address of the connector using the standard ${...} syntax. 245 * 246 * @throws MojoExecutionException 247 */ 248 @Override 249 public void execute() throws MojoExecutionException { 250 if (skip) { 251 getLog().info("Skipped execution of ActiveMQ Broker"); 252 return; 253 } 254 255 addActiveMQSystemProperties(); 256 257 getLog().info("Loading broker configUri: " + configUri); 258 if (this.xBeanFileResolver.isXBeanFile(configUri)) { 259 getLog().debug("configUri before transformation: " + configUri); 260 configUri = this.xBeanFileResolver.toUrlCompliantAbsolutePath(configUri); 261 getLog().debug("configUri after transformation: " + configUri); 262 } 263 264 this.useBrokerManager().start(fork, configUri); 265 266 // 267 // Register the transport connector URIs in the Maven project. 268 // 269 this.registerTransportConnectorUris(); 270 271 getLog().info("Started the ActiveMQ Broker"); 272 } 273 274 /** 275 * Set system properties 276 */ 277 protected void addActiveMQSystemProperties() { 278 // Set the default properties 279 System.setProperty("activemq.base", project.getBuild().getDirectory() + "/"); 280 System.setProperty("activemq.home", project.getBuild().getDirectory() + "/"); 281 System.setProperty("org.apache.activemq.UseDedicatedTaskRunner", "true"); 282 System.setProperty("org.apache.activemq.default.directory.prefix", project.getBuild().getDirectory() + "/"); 283 System.setProperty("derby.system.home", project.getBuild().getDirectory() + "/"); 284 System.setProperty("derby.storage.fileSyncTransactionLog", "true"); 285 286 // Overwrite any custom properties 287 System.getProperties().putAll(systemProperties); 288 } 289 290 /** 291 * Register all of the broker's transport connector URIs in the Maven project as properties. Property names are 292 * formed from the connectorPropertyNameFormat using String.format(), with the connector name as the one and only 293 * argument. The value of each property is that returned by getPublishableConnectString(). 294 */ 295 protected void registerTransportConnectorUris () { 296 Properties props = project.getProperties(); 297 298 // 299 // Loop through all of the connectors, adding each. 300 // 301 for ( TransportConnector oneConnector : this.useBrokerManager().getBroker().getTransportConnectors() ) { 302 try { 303 // 304 // Format the name of the property and grab the value. 305 // 306 String propName = String.format(this.connectorPropertyNameFormat, oneConnector.getName()); 307 String value = oneConnector.getPublishableConnectString(); 308 309 getLog().debug("setting transport connector URI property: propertyName=\"" + propName + 310 "\"; value=\"" + value + "\""); 311 312 // 313 // Set the property. 314 // 315 props.setProperty(propName, value); 316 } catch (Exception exc) { 317 // 318 // Warn of the issue and continue. 319 // 320 getLog().warn("error on obtaining broker connector uri; connector=" + oneConnector, exc); 321 } 322 } 323 } 324 325 /** 326 * Use the configured broker manager, if defined; otherwise, use the default broker manager. 327 * 328 * @return the broker manager to use. 329 */ 330 protected MavenBrokerManager useBrokerManager () { 331 if ( this.brokerManager == null ) { 332 this.brokerManager = new MavenBrokerSingletonManager(); 333 } 334 335 return this.brokerManager; 336 } 337}