August 18, 2013

Configure Redelivery for ActiveMQ 5.8 Resource Adapter in JBoss EAP 6

In this blog I will show you how to setup ActiveMQ resource adapter in JBoss EAP 6 and then test different redelivery policies.

Before we begin, we need to download the latest Apache ActiveMQ binaries and unzip it. To start, stop and check status we use the activemq script located in the bin folder.

$ ACTIVEMQ_HOME/bin/activemq [start|stop|status]

After started the ActiveMQ, we can test the installation by open a web browser and open http://localhost:8161/admin/. The default username is admin and default password is admin.

Now we need to configure JBoss. In this blog we will use JBoss EAP 6.1.0. Download it and unzip it.

The next thing we need to do is to download the Apache ActiveMQ resource adapter. You can find it from maven central repo – http://search.maven.org/remotecontent?filepath=org/apache/activemq/activemq-rar/5.8.0/activemq-rar-5.8.0.rar.

JBoss EAP 6 can be run in two different modes – standalone and domain mode. In this blog we will be using standalone mode, but if you need to run JBoss in domain the below configuration is basically the same.

Now deploy the resource adapter to $JBOSS_HOME/standalone/deployment

Now we are ready to configure JBoss. Open $JBOSS_HOME/standalone/configuration/standalone.xml

        <subsystem xmlns="urn:jboss:domain:resource-adapters:1.1">
            <resource-adapters>
                <resource-adapter id="activemq-rar-5.8.0.rar">
                    <archive>
                        activemq-rar-5.8.0.rar
                    </archive>
                    <transaction-support>LocalTransaction</transaction-support>
                    <config-property name="InitialRedeliveryDelay">
                        1000
                    </config-property>
                    <config-property name="MaximumRedeliveries">
                        5
                    </config-property>
                    <config-property name="RedeliveryUseExponentialBackOff">
                        false
                    </config-property>
                    <config-property name="RedeliveryBackOffMultiplier">
                        5
                    </config-property>
                    <config-property name="ServerUrl">
                        failover:(tcp://127.0.0.1:61616)
                    </config-property>
                    <connection-definitions>
                        <connection-definition class-name="org.apache.activemq.ra.ActiveMQManagedConnectionFactory" jndi-name="java:jboss/activemq/ConnectionFactory" enabled="true" use-java-context="true" pool-name="ConnectionFactory">
                            <pool>
                                <min-pool-size>10</min-pool-size>
                                <max-pool-size>100</max-pool-size>
                                <prefill>true</prefill>
                            </pool>
                        </connection-definition>
                    </connection-definitions>
                    <admin-objects>
                        <admin-object class-name="org.apache.activemq.command.ActiveMQQueue" jndi-name="java:jboss/activemq/queue/FooQueue" enabled="true" use-java-context="true" pool-name="FooQueue">
                            <config-property name="PhysicalName">
                                FooQueue
                            </config-property>
                        </admin-object>
                    </admin-objects>
                </resource-adapter>
            </resource-adapters>
        </subsystem>

The last thing we also need is to configure mdb support for the standalone configuration.

        <subsystem xmlns="urn:jboss:domain:ejb3:1.4">
            ...
            </session-bean>
            <mdb>
                <resource-adapter-ref resource-adapter-name="activemq-rar-5.8.0.rar"/>
                <bean-instance-pool-ref pool-name="mdb-strict-max-pool"/>
            </mdb>
            <pools>
            ...
        </subsystem>

Now we are to test the installation. We do that by creating a simple MDB, that prints out incoming JMS messages and then rollbacks the MDB transaction.

package se.msc.example.mdb;

import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;

@MessageDriven(name = "FooMDB", activationConfig = {
        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
        @ActivationConfigProperty(propertyName = "destination", propertyValue = "FooQueue"),
        @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge") })
public class FooMDB implements MessageListener {

    @Resource
    private MessageDrivenContext mdc;

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void onMessage(Message msg) {
        try {
            System.out.println("mdb recieved, redelivered="
                    + msg.getJMSRedelivered());
        } catch (JMSException e) {
            e.printStackTrace();
        }

        mdc.setRollbackOnly();
    }

}

As test client we can send jms message from the ActiveMQ web console

Below follows different test results for different redelivery configuration

InitialRedeliveryDelay=1000
MaximumRedeliveries=5
RedeliveryUseExponentialBackOff=false
RedeliveryBackOffMultiplier=5
                    
18:57:51,140 INFO  [stdout] (default-threads - 2) mdb recieved, redelivered=false
18:57:52,220 INFO  [stdout] (default-threads - 3) mdb recieved, redelivered=true
18:57:53,256 INFO  [stdout] (default-threads - 4) mdb recieved, redelivered=true
18:57:54,296 INFO  [stdout] (default-threads - 5) mdb recieved, redelivered=true
18:57:55,334 INFO  [stdout] (default-threads - 6) mdb recieved, redelivered=true
18:57:56,365 INFO  [stdout] (default-threads - 7) mdb recieved, redelivered=true

-----------------------------------------------------------------------------------------------

InitialRedeliveryDelay=1000
MaximumRedeliveries=5
RedeliveryUseExponentialBackOff=true
RedeliveryBackOffMultiplier=5

19:55:21,453 INFO  [stdout] (default-threads - 2) mdb recieved, redelivered=false
19:55:26,495 INFO  [stdout] (default-threads - 3) mdb recieved, redelivered=true
19:55:51,503 INFO  [stdout] (default-threads - 4) mdb recieved, redelivered=true
19:57:56,510 INFO  [stdout] (default-threads - 5) mdb recieved, redelivered=true
20:08:21,516 INFO  [stdout] (default-threads - 6) mdb recieved, redelivered=true
21:00:26,523 INFO  [stdout] (default-threads - 7) mdb recieved, redelivered=true

delta1 = 5s (calculated value 1*5)
delta2 = 25s (calculated value 5*5)
delta3 = 125s (calculated value 25*5)
delta4 = 625s (calculated value 125*5)
delta5 = 3125s (calculated value 625*5)

-----------------------------------------------------------------------------------------------

InitialRedeliveryDelay=2000
MaximumRedeliveries=5
RedeliveryUseExponentialBackOff=true
RedeliveryBackOffMultiplier=5
                    
22:28:52,542 INFO  [stdout] (default-threads - 2) mdb recieved, redelivered=false
22:29:02,598 INFO  [stdout] (default-threads - 3) mdb recieved, redelivered=true
22:29:52,604 INFO  [stdout] (default-threads - 4) mdb recieved, redelivered=true
22:34:02,609 INFO  [stdout] (default-threads - 5) mdb recieved, redelivered=true

delta1 = 10s (calculated value 2*5)
delta2 = 50s (calculated value 10*5)
delta3 = 250s (calculated value 50*5)
-----------------------------------------------------------------------------------------------    

References

No comments: