Skip to main content

How to rollback/commit processing messages from WSO2 ESB when enabled JMS transaction

This blog post describes the below use-case where WSO2 ESB 4.6.0 act as the intermediate channel in-between two JMS queues.

The Use-case

  1. First messages will be de-queue to a proxy service deployed in WSO2 ESB from an queue in ActiveMQ message broker.
  2. Then inside ESB,the incoming messages will undergo with some message mediation flow and then the message will be send to another JMS queue deployed in JBoss server.
  3. Inside the ESB,following failures could be happen; 
          a) Failures during message mediation process failure inside ESB [for example if you 
              use  dbreportmediator/lookup mediator inside mediation flow,some times failures can 
              happen due to database connection failures]
         b) Message sending failure,due to endpoint is unavailability.[For example,the JBoss 
             server in which the endpoint queue deployed is down]

The requirement is if any of above failures happen,the message should not process further and send to endpoint,rather it should rollback to the queue of JMS provider [ActiveMQ].If none of failures happen the message should send to back-end endpoint.

So how to achieve above requirement with JMS?

It can be achieve via enabling JMS transactions enabled.In this scenario,there will be no more transaction resources like databases,thus here it can be used JMS local transactions enabled.To enable it ,add below property in approapriate JMS transport receiver config of axis2.xml file of ESB [{ESB}/repositry/conf/axis2]

 <parameter name="transport.jms.SessionTransacted">true</parameter>

Additionally,there should be a way to control message rollbacking/commiting based on message mediation flow status.This can be achieved via setting the correct JMS acknowledgement mode.The correct acknowledgement mode for this scenario is 'Client Acknowledgement' mode.The different acknowledgement modes support by JMS are;


Auto mode: The messages sent  from ActiveMQ are automatically acknowledged. This is the simplest mode and expresses JMS's power by enabling once-only message delivery guarantee.If we set this in above scenario,the message will de-queue as the message reach to ESB from ActiveMQ without waiting until the message processed.
 
Duplicates okay mode:The messages sent  from ActiveMQ are automatically acknowledged just like auto mode.Under rare circumstances, the messages might be delivered more than once. This mode enables at-least-once message delivery guarantee. 
 
Client mode: The messages sent from ActiveMQ are not acknowledged automatically. The application must acknowledge the message receipt. In above use-case,ESB should acknowledge ActiveMQ.This mode gives the application (rather than the JMS provider) complete control over message acknowledgement, at the cost of increased code complexity.


In above scenario the JMS message sending to the back-end is handle with ESB[JMS consumer],not by ActiveMQ [JMS provider].And until the message processed and send to backend,it need to pause de-queing the message from ActiveMQ to ESB.Thus it need to avoid JMS auto acknowledgement mode in this use-case.And based on ESB side failures/success,the message from queue in ActiveMQ should rollback or commit.For that on each failure/success statuses in message flow of ESB,it should acknowledge ActiveMQ,either to rollback or commit.And ESB need to send acknowledgement messages to ActiveMQ on its message mediation flow success/failure.In other words,its like sending 'client acknowledgement' messages to ActiveMQ.
To set 'Client Acknowledgement' in ESB,set below property inapproapriate JMS transport receiver config of axis2.xml file of ESB [{ESB}/repositry/conf/axis2]

<parameter name="transport.jms.SessionAcknowledgement"locked="true">CLIENT_ACKNOWLEDGE</parameter>

Then  as an failure occurred in message mediation flow,we need to rollback the processing message back to ActiveMQ queue, the below property SET_ROLLBACK_ONLY has to be set to true in relevant fault handler.

<property name="SET_ROLLBACK_ONLY" value="true" scope="axis2"/>

Once set as above,the above a) failure instances can be managed.Now the question comes,is it possible to cover message rollbacking to ActiveMQ queue again when the above b) failure instances also with JMS transactions and JMS client acknowledgement mode.Answer is yes,it's possible to do so.If your backend endpoint is;

A http/https endpoint -Then you need to use 'callout mediator' to send the messages to backend.NOTE-If you use 'send mediator',you cannot achieve,JMS message rollbacking /commiting based on endpoint failure,due to http and https transports are asynchronous.

A JMS endpoint- You can use one from both 'callout' and 'send' mediator to send the messages to backend as JMS is a blocking transport.NOTE -If you are using the 'send' mediator,make sure you have remove below axis2 level property by your proxy service configuration.

<property name="ClientApiNonBlockingaction="remove" scope="axis2"/>
Axis2 will spawn a new thread to handle each outgoing message. To change this behavior,
remove this property from the message.A sample proxy service configuration,would be as below;
To learn about JMS transactions and acknowledgement modes,please refer;

Comments

  1. HI sureshika,
    I have one query same like above ,could you please look into this..
    http://stackoverflow.com/questions/19860431/in-wso2-esb-4-7-0-can-we-do-jms-rollback-in-receiving-sequence

    ReplyDelete
  2. Hi,

    Need your help. I setup my proxy service and its working fine.
    However; as soon as I put the Active MQ down OR switch off the endpoint AND send the message to a sourceQueue (where proxy service is listening); the WSO2 start writing the unlimited log files that are growing so quickly. Can you please suggest what might have gone wrong here.





















    GFQueue
    proxy



    The extract from log file;

    2014-05-07 16:22:52,451 [-] [jms-Worker-9] INFO JMS2JMSProxy Transaction Action = Rollbacked
    2014-05-07 16:22:52,451 [-] [jms-Worker-9] INFO JMS2JMSProxy Transaction Action = Committed
    2014-05-07 16:22:52,457 [-] [jms-Worker-9] INFO JMS2JMSProxy FaultHandler executing impl: org.apache.synapse.mediators.MediatorFaultHandler
    2014-05-07 16:22:52,458 [-] [jms-Worker-9] WARN JMS2JMSProxy Executing fault sequence mediator : org.apache.synapse.mediators.base.SequenceMediator
    2014-05-07 16:22:52,458 [-] [jms-Worker-9] INFO JMS2JMSProxy Transaction Action = Rollbacked
    2014-05-07 16:22:52,459 [-] [jms-Worker-9] INFO JMS2JMSProxy Transaction Action = Committed
    2014-05-07 16:22:52,467 [-] [jms-Worker-9] INFO JMS2JMSProxy FaultHandler executing impl: org.apache.synapse.mediators.MediatorFaultHandler
    2014-05-07 16:22:52,467 [-] [jms-Worker-9] WARN JMS2JMSProxy Executing fault sequence mediator : org.apache.synapse.mediators.base.SequenceMediator
    2014-05-07 16:22:52,468 [-] [jms-Worker-9] INFO JMS2JMSProxy Transaction Action = Rollbacked
    2014-05-07 16:22:52,468 [-] [jms-Worker-9] INFO JMS2JMSProxy Transaction Action = Committed
    2014-05-07 16:22:52,476 [-] [jms-Worker-9] INFO JMS2JMSProxy FaultHandler executing impl: org.apache.synapse.mediators.MediatorFaultHandler
    2014-05-07 16:22:52,476 [-] [jms-Worker-9] WARN JMS2JMSProxy Executing fault sequence mediator : org.apache.synapse.mediators.base.SequenceMediator
    2014-05-07 16:22:52,477 [-] [jms-Worker-9] INFO JMS2JMSProxy Transaction Action = Rollbacked
    2014-05-07 16:22:52,477 [-] [jms-Worker-9] INFO JMS2JMSProxy Transaction Action = Committed
    2014-05-07 16:22:52,485 [-] [jms-Worker-9] INFO JMS2JMSProxy FaultHandler executing impl: org.apache.synapse.mediators.MediatorFaultHandler
    2014-05-07 16:22:52,485 [-] [jms-Worker-9] WARN JMS2JMSProxy Executing fault sequence mediator : org.apache.synapse.mediators.base.SequenceMediator
    2014-05-07 16:22:52,486 [-] [jms-Worker-9] INFO JMS2JMSProxy Transaction Action = Rollbacked
    2014-05-07 16:22:52,486 [-] [jms-Worker-9] INFO JMS2JMSProxy Transaction Action = Committed
    2014-05-07 16:22:52,494 [-] [jms-Worker-9] INFO JMS2JMSProxy FaultHandler executing impl: org.apache.synapse.mediators.MediatorFaultHandler
    2014-05-07 16:22:52,494 [-] [jms-Worker-9] WARN JMS2JMSProxy Executing fault sequence mediator : org.apache.synapse.mediators.base.SequenceMediator
    2014-05-07 16:22:52,495 [-] [jms-Worker-9] INFO JMS2JMSProxy Transaction Action = Rollbacked
    2014-05-07 16:22:52,495 [-] [jms-Worker-9] INFO JMS2JMSProxy Transaction Action = Committed
    2014-05-07 16:22:52,500 [-] [jms-Worker-9] INFO JMS2JMSProxy FaultHandler executing impl: org.apache.synapse.mediators.MediatorFaultHandler

    ReplyDelete
  3. This is an excellent article and helped me to configure the service. However; getting some log errors. Already raised in stack overflow, please help.
    http://stackoverflow.com/questions/23532845/wso2-proxy-writing-unlimited-log-files

    ReplyDelete
  4. Can you please help me out with this question. Thanks for your help in advance.
    http://stackoverflow.com/questions/26993573/jms-transaction-rollback-property-not-working-in-wso2-4-8-1-esb

    ReplyDelete

Post a Comment

Popular posts from this blog

Convert an InputStream to XML

For that we can use DocumentBuilder class in java. By using the method parse(InputStream) ; A new DOM Document object will return. InputStream input; DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder parser = factory.newDocumentBuilder(); Document dc= parser.parse(input); In the above code segment,by using the created Document object,the corresponding XML file for the inputStream can be accessed. References: http://www.w3schools.com/dom/dom_intro.asp http:// download.oracle.com/javase/1.4.2/docs/api/javax/xml/parsers/DocumentBuilder.html

Concat two xml values with XSLT

The use-case described in this blog-post,is there's an WSO2 ESB node setup to proxy an incoming message to a particular back-end endpoint.  Before delivering the message to the back-end endpoint,from the ESB node itself,this incoming message need to processed and change its inside xml payload format. For eg: Below is the incoming message <?xml version="1.0" encoding="UTF-8"?> <CinemaHall name="liberty"> <OwnerData> <Name>John Smith</Name> <openedDate>12/12/80</openedDate> <quality>good</quality> </OwnerData> <CinemaHallData> <rows>100</rows> <seats> <seat>50</seat> <seat>60</seat> </seats> </CinemaHallData> </CinemaHall> This message need to be changed as  below; <?xml version="1.0" encoding="UTF-8"?> <CinemaHall name="liberty"...

Passing end-user details from client to real backend endpoint via JWT token

In real-world business system,WSO2 API Manager useful on exposing company APIs, in a secured and controlled manner with the features provided by APIManager as; OAuth support [To secure API invocations] Throttling support [To control API invocations] Monitoring support [To track API usage] More technically what happening is when a user sends a particular API request,it will goes to WSO2 APIManager node and from there,the request will route to the real implemented back-end endpoint of the particular API and get back the response and returned it to the API invoked user. There can be a use-case,that this back-end endpoint may expect the details of API invoked user as to pass those details to some internal company usage  as; Additional authentication/authorization Track usage data from an internal system. So how to support above requirement from WSO2 AM. There comes the use of JSON Web Token[JWT] implementation done inside WSO2 AM. JWT is a means of representing claims to...