Sunday, May 20, 2012

Getting ActiveMQ Redelivery to work with WSO2 ESB

Recently I wanted to use the redelivery mechanism available in Apache ActiveMQ while using it with WSO2 ESB. My scenario was like this.
  1. Retrieve a message from a JMS queue
  2. Write the message to a file URI (in your case you may want to send it to a given endpoint)
  3. If writing to the file is not successful due to some failure, I wanted the message to be in the queue and ActiveMQ to try repeatedly writing to the file.
Following are the properties/parameters I had to put in the axis2.xml of WSO2 ESB (under JMS transport receiver). Remember that you need to put the other parameters such as initial context factory, provider url, connection factory and connection factory type etc.
<parameter name="transport.Transactionality" locked="true">jta</parameter>
<parameter name="transport.jms.SessionTransacted" locked="true">true</parameter>
<parameter name="redeliveryPolicy.maximumRedeliveries" locked="true">-1</parameter>
<parameter name="redeliveryPolicy.redeliveryDelay" locked="true">2000</parameter>
<parameter name="transport.jms.CacheLevel" locked="true">consumer</parameter>

I will explain some of the above parameters.

  1. transport.Transactionality - This is the desired mode of transactionality. I was using distributed transactions. Therefore the value was jta. If you are using local transactions you can put it as local.
  2. transport.jms.SessionTransacted - Whether the JMS session should be transacted or not.
  3. redeliveryPolicy.maximumRedeliveries - Maximum number of retries you wish. If set to -1, ActiveMQ will infinitely retry.
  4. redeliveryPolicy.redeliveryDelay - Delay between retries. I have set it to 2 seconds (i.e. 2000 milliseconds).
  5. transport.jms.CacheLevel - This is the most important property to get the redelivery mechanism to work properly. This has to be set to "consumer". Reason for this is ActiveMQ  RedeliveryPolicy is dictated by CONSUMER, not PRODUCER.
With above configurations, you are able to get the redelivery mechanism in ActiveMQ to work when used with WSO2 ESB.

You will also need to set the SET_ROLLBACK_ONLY property in the fault sequence of your proxy service. Otherwise the transaction will not get rollbacked.
<property name="SET_ROLLBACK_ONLY" value="true" scope="axis2"/> 


Following links will provide further help.
1. WSO2 ESB documentation's JMS transport section
2. ActiveMQ redeliverPolicy configuration parameters