/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.activemq.maven; import java.util.Properties; import org.apache.activemq.broker.TransportConnector; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.MavenProject; /** * Goal which starts an activemq broker. * * @goal run * @phase process-sources */ public class StartBrokerMojo extends AbstractMojo { /** * Default connector property name format. */ public static final String DEFAULT_CONNECTOR_PROPERTY_NAME_FORMAT = "org.apache.activemq.connector.%s.uri"; /** * The maven project. * * @parameter property="project" default-value="${project}" * @required * @readonly */ protected MavenProject project; /** * The broker configuration uri The list of currently supported URI syntaxes * is described <a * href="http://activemq.apache.org/how-do-i-embed-a-broker-inside-a-connection.html">here</a> * * @parameter property="configUri" * default-value="broker:(tcp://localhost:61616)?useJmx=false&persistent=false" * @required */ private String configUri; /** * Indicates whether to fork the broker, useful for integration tests. * * @parameter property="fork" default-value="false" */ private boolean fork; /** * System properties to add * * @parameter property="systemProperties" */ private Properties systemProperties; /** * Skip execution of the ActiveMQ Broker plugin if set to true * * @parameter property="skip" */ private boolean skip; /** * Format of the connector URI property names. The first argument for the format is the connector name. * * @parameter property="connectorPropertyNameFormat" */ private String connectorPropertyNameFormat = DEFAULT_CONNECTOR_PROPERTY_NAME_FORMAT; /** * Broker manager used to start and stop the broker. */ private MavenBrokerManager brokerManager; /** * XBean File Resolver used to detect and transform xbean file URIs. */ private XBeanFileResolver xBeanFileResolver = new XBeanFileResolver(); /** * Retrieve the Maven project for this mojo. * * @return the Maven project. */ public MavenProject getProject() { return project; } /** * Set the Maven project for this mojo. * * @param project the Maven project. */ public void setProject(MavenProject project) { this.project = project; } /** * Retrieve the URI used to configure the broker on startup. * * @return the configuration URI. */ public String getConfigUri() { return configUri; } /** * Set the URI used to configure the broker on startup. * * @param configUri the URI used to configure the broker. */ public void setConfigUri(String configUri) { this.configUri = configUri; } /** * Determine if the mojo is configured to fork a broker. * * @return true => the mojo will fork a broker (i.e. start it in the background); false => start the broker and * wait synchronously for it to terminate. */ public boolean isFork() { return fork; } /** * Configure the mojo to run the broker asynchronously (i.e. fork) or synchronously. * * @param fork true => start the broker asynchronously; true => start the broker synchronously. */ public void setFork(boolean fork) { this.fork = fork; } /** * Determine if the mojo is configured to skip the broker startup. * * @return true => the mojo will skip the broker startup; false => the mojo will start the broker normally. */ public boolean isSkip() { return skip; } /** * Configure the mojo to skip or normally execute the broker startup. * * @param skip true => the mojo will skip the broker startup; false => the mojo will start the broker normally. */ public void setSkip(boolean skip) { this.skip = skip; } /** * Retrieve properties to add to the System properties on broker startup. * * @return properties to add to the System properties. */ public Properties getSystemProperties() { return systemProperties; } /** * Set properties to add to the System properties on broker startup. * * @param systemProperties properties to add to the System properties. */ public void setSystemProperties(Properties systemProperties) { this.systemProperties = systemProperties; } /** * Retrieve the format used to generate property names when registering connector URIs. * * @return the format used to generate property names. */ public String getConnectorPropertyNameFormat() { return connectorPropertyNameFormat; } /** * Set the format used to generate property names when registering connector URIs. * * @param connectorPropertyNameFormat the new format to use when generating property names. */ public void setConnectorPropertyNameFormat(String connectorPropertyNameFormat) { this.connectorPropertyNameFormat = connectorPropertyNameFormat; } /** * Retrieve the manager used to create and retain the started broker. * * @return the manager. */ public MavenBrokerManager getBrokerManager() { return brokerManager; } /** * Set the manager used to create and retain the started broker. * * @param brokerManager the new manager to use. */ public void setBrokerManager(MavenBrokerManager brokerManager) { this.brokerManager = brokerManager; } /** * Retrieve the XBeanFileResolver used to detect and transform XBean URIs. * * @return the XBeanFileResolver used. */ public XBeanFileResolver getxBeanFileResolver() { return xBeanFileResolver; } /** * Set the XBeanFileResolver to use when detecting and transforming XBean URIs. * * @param xBeanFileResolver the XBeanFileResolver to use. */ public void setxBeanFileResolver(XBeanFileResolver xBeanFileResolver) { this.xBeanFileResolver = xBeanFileResolver; } /** * Perform the mojo operation, which starts the ActiveMQ broker unless configured to skip it. Also registers the * connector URIs in the maven project properties on startup, which enables the use of variable substitution in * the pom.xml file to determine the address of the connector using the standard ${...} syntax. * * @throws MojoExecutionException */ @Override public void execute() throws MojoExecutionException { if (skip) { getLog().info("Skipped execution of ActiveMQ Broker"); return; } addActiveMQSystemProperties(); getLog().info("Loading broker configUri: " + configUri); if (this.xBeanFileResolver.isXBeanFile(configUri)) { getLog().debug("configUri before transformation: " + configUri); configUri = this.xBeanFileResolver.toUrlCompliantAbsolutePath(configUri); getLog().debug("configUri after transformation: " + configUri); } this.useBrokerManager().start(fork, configUri); // // Register the transport connector URIs in the Maven project. // this.registerTransportConnectorUris(); getLog().info("Started the ActiveMQ Broker"); } /** * Set system properties */ protected void addActiveMQSystemProperties() { // Set the default properties System.setProperty("activemq.base", project.getBuild().getDirectory() + "/"); System.setProperty("activemq.home", project.getBuild().getDirectory() + "/"); System.setProperty("org.apache.activemq.UseDedicatedTaskRunner", "true"); System.setProperty("org.apache.activemq.default.directory.prefix", project.getBuild().getDirectory() + "/"); System.setProperty("derby.system.home", project.getBuild().getDirectory() + "/"); System.setProperty("derby.storage.fileSyncTransactionLog", "true"); // Overwrite any custom properties System.getProperties().putAll(systemProperties); } /** * Register all of the broker's transport connector URIs in the Maven project as properties. Property names are * formed from the connectorPropertyNameFormat using String.format(), with the connector name as the one and only * argument. The value of each property is that returned by getPublishableConnectString(). */ protected void registerTransportConnectorUris () { Properties props = project.getProperties(); // // Loop through all of the connectors, adding each. // for ( TransportConnector oneConnector : this.useBrokerManager().getBroker().getTransportConnectors() ) { try { // // Format the name of the property and grab the value. // String propName = String.format(this.connectorPropertyNameFormat, oneConnector.getName()); String value = oneConnector.getPublishableConnectString(); getLog().debug("setting transport connector URI property: propertyName=\"" + propName + "\"; value=\"" + value + "\""); // // Set the property. // props.setProperty(propName, value); } catch (Exception exc) { // // Warn of the issue and continue. // getLog().warn("error on obtaining broker connector uri; connector=" + oneConnector, exc); } } } /** * Use the configured broker manager, if defined; otherwise, use the default broker manager. * * @return the broker manager to use. */ protected MavenBrokerManager useBrokerManager () { if ( this.brokerManager == null ) { this.brokerManager = new MavenBrokerSingletonManager(); } return this.brokerManager; } }