The ActiveMQ Provider

The Fabric3 ActiveMQ extension provides connectivity to ActiveMQ brokers for the JMS binding. Two modes are supported: connecting to an external broker (or cluster); and running an embedded broker. An external broker setup is recommended for production use.

Connecting to an External Broker

To connect to an external broker, the ActiveMQ embedded broker must be disabled and an ActiveMQ connection factory must be configured in the runtime systemConfig.xml. The following illustrates how disable the embedded broker and create a connection factory (ConnectionFactory1) that connects to the default ActiveMQ broker configuration:

<jms>
   <activemq broker.disabled="true"/>
   <connection.factories>
      <connection.factory name="ConnectionFactory1" broker.url="tcp://localhost:61616" type="xa"/>
   </connection.factories>
</jms>

Valid ActiveMQ broker URL schemes are supported. The type attribute indicates the connection factory type to create: XA, local, or pooled.

The connection factory can then be used by a JMS binding configuration in a composite as follows:

<channel name="TestChannel">
   <binding.jms>
      <connectionFactory jndiName="ConnectionFactory1"/>
      <destination jndiName="TestTopic"/>
   </binding.jms>
</channel>

If a topic or queue does not exist, the default behavior is to create it on the broker.

Default XA and non-XA connection factories can be setup in systemConfig.xml. If no connection factory is specified in a binding configuration, either the default XA or non-XA factory will be used depending on whether global or local transacted messaging is required for a particular operation. Below is an example of how to set up default ActiveMQ connection factories:

<jms>
   <connection.factories>
      <connection.factory name="xaDefault" broker.url="vm://broker" type="xa"/>
      <connection.factory name="default" broker.url="vm://broker"/>
   </connection.factories>
</jms>

Using the Embedded External Broker

ActiveMQ brokers can be hosted in Fabric3 to provide distributed messaging capabilities between runtimes. The broker infrastructure is integrated with the JMS binding to enable automated creation configuration of JMS queues and topics.

ActiveMQ connection factories are configured in the runtime systemConfig.xml using the in-process broker URL as follows:

<jms>
   <connection.factories>
      <connection.factory name="TheFactory" broker.url="vm://broker" type="xa"/>
   </connection.factories>
</jms>

The connection factories can then be used in binding configurations as illustrated below:

<component name="TheComponent">
   <implementation.java .../>
   <reference name="service">
      <binding.jms>
         <connectionFactory name="TheFactory"/>
         <destination name="ServiceQueue"/>
      </binding.jms>
   </reference>
</component>

Using the DSL

The following is an example provider that configures a channel with an ActiveMQ connection factory. Note the use of an environment variable - 'local' - to set the broker URL:

public class ServiceCompositeProvider {
 
    @Provides
    public static Composite createComposite(@Environment String environment) {
        CompositeBuilder compositeBuilder = CompositeBuilder.newBuilder(SERVICE_COMPOSITE_QNAME);
        createConnectionFactory(compositeBuilder);
        createChannel(compositeBuilder);
        return compositeBuilder.build();
    }

    private static void createChannel(CompositeBuilder compositeBuilder) {
        JmsBindingDefinitionBuilder bindingBuilder = JmsBindingDefinitionBuilder.newBuilder();
        bindingBuilder.destination(MESSAGE_TOPIC, TOPIC);
        bindingBuilder.localDelivery(true);
        bindingBuilder.connectionFactoryName("ConnectionFactory");
        bindingBuilder.durable(true);
        bindingBuilder.cacheLevel(CacheLevel.ADMINISTERED_OBJECTS);
        BindingDefinition binding = bindingBuilder.build();
        ChannelDefinitionBuilder channelBuilder = ChannelDefinitionBuilder.newBuilder(MESSAGE_CHANNEL);
        channelBuilder.binding(binding);
        compositeBuilder.channel(channelBuilder.build());
    }
    private static void createConnectionFactory(CompositeBuilder compositeBuilder) {
        ConnectionFactoryResourceBuilder resourceBuilder = ConnectionFactoryResourceBuilder.newBuilder("ConnectionFactory");
        resourceBuilder.username("test");
        resourceBuilder.password("test");
        boolean isLocal = Boolean.parseBoolean(System.getProperty("local"));
        if (isLocal) {
            resourceBuilder.attribute("broker.uri", URI.create("tcp://localhost:61616"));
        } else {
            resourceBuilder.attribute("broker.uri", URI.create("ssl://broker:61616"));
        }
        resourceBuilder.clientId("{runtime}");
        resourceBuilder.type(ConnectionFactoryType.LOCAL);
        compositeBuilder.resource(resourceBuilder.build());
    }
}

Configuring the Embedded ActiveMQ Broker

The default configuration using by the embedded ActiveMQ broker may be overridden in systemConfig.xml to specify custom ActiveMQ network and transport connectors:

<jms>
   <activemq>
      <networkConnectors>
         <networkConnector uri="multicast://default"/>
      </networkConnectors>
      <transportConnectors>
         <transportConnector name="openwire" uri="tcp://localhost:61616"/>
      </transportConnectors>
   </activemq>
</jms>

Configuring Connection Factories

JMS connection factories are configured as resources in a composite. The following example demonstrates how this is done using XML:

<composite ...>   
	<f3:connection.factory name="DurableConnectionFactory" binding.uri="vm://durable" client.id="TestClient" username=".." password="..">
        <factory.properties>
            <pool.size.min>1</pool.size.min>
        </factory.properties>
    </f3:connection.factory>
</composite>

The factory.properties element contains a list of key/value properties that are specific to the JMS provider. Client ID is used for durable connections. If the value '{runtime}' is specified, the Fabric3 runtime name will be used.

ActiveMQ also supports the type attribute with LOCAL or XA as values.

Configuring Connection Templates

Connection Templates are no longer supported as of Fabric3 2.5.0.

Binding.SCA

In addition, the ActiveMQ extension is also a binding.sca provider. This means components can be wired and connected to remote channels without configuring transports or physical endpoint information – basically as if they were components locally wired. The ActiveMQ extension will manage queue setup and connections transparently.

Connection factories can be configured for use with binding.sca in systemConfig.xml using the binding.sca element. Specifically, the xa.factory and factory attributes point to an XA and non-XA connection factory configuration. When binding.sca is use for a wire or remote channel either the XA or non-XA connection factory will be used. The following demonstrates how to configure the binding.sca connection factories:

<jms>
   <connection.factories>
      <connection.factory name="xaFactory" broker.url="vm://broker" type="xa"/>
      <connection.factory name="nonXaFactory" broker.url="vm://broker" type="local"/>
   </connection.factories>

   <binding.sca xa.factory="xaFactory" factory= "nonXaFactory"/>
</jms>