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

CORS support from WSO2 API Manager 2.0.0

Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources  on a web page to be requested from another domain outside the domain from which the first restricted resource was served. For example, an HTML page of a web application served from http://domain-a.com makes an <img src >  request for a different domain as 'domain-b.com' to get an image via an API request.  For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts as in above example and only allows to make HTTP requests to its own domain. To avoid this limitation modern browsers have been used CORS standard to allow cross domain requests. Modern browsers use CORS in an API container - such as  XMLHttpRequest  or Fetch - to mitigate risks of cross-origin HTTP requests.Thing to  note is it's not only sufficient that the browsers handle client side of cross-origin sharing,but also the servers from which these resources getting need to handl

[WSO2 AM] APIStore User Signup as an approval process

In previous versions of WSO2 APIManager before 1.6.0, it was allowed any user who's accessible the running APIStore come and register to the app.But there will be requirement like,without allowing any user to signup by him/her self alone,first get an approve by a privileged user and then allow to complete app registration.Same requirement can be apply to application creation and subscription creation as well.To fulfill that,we have introduced workflow extension support for  WSO2 APIManager  and you can find the introductory post on this feature from my previous blog post on " workflow-extentions-with-wso2-am-160 " . From this blog-post,I'll explain how to achieve simple workflow integration with default shipped resources with  WSO2 APIManager 1.6.0 and WSO2 Business Process Server 3.1.0 with targeting "user-signup" process. Steps First download the WSO2 APIManager 1.6.0[AM] binary pack from product download page . Extract it and navigate to