Reliability Patterns with Active MQ & Mule

Applications which use a transactional transport such as JMS, VM or JDBC are guaranteed that messages will not be lost during the course of processing. Transactional support in these transports ensures that messages are delivered reliably from an inbound endpoint to an outbound endpoint or between processors in a flow. If however you have a web application accessing your flow via a non-transactional transport such as HTTP you can ensure reliable messaging in your flow by implementing a reliability pattern. Reliability patterns couple a reliable acquisition flow with an application logic flow. A reliable acquisition flow can be combined with a series of asynchronous flows to decompose applications into decoupled, reliable segments. Applications which access multiple remote systems as part of their processing which may take a variable amount of time to respond and maybe unreliable are good candidates for this architecture.

This blog discusses this approach using a fictions example which accepts contact information over an inbound HTTP endpoint which needs to be processed by a web service and then synchronizes the contact information with multiple backend systems such as Microsoft Dynamics CRM and Salesforce. These are systems you may have no control over but we’d like to respond to the calling application as soon as possible with a confirmation that the contact information was received and is being processed. This is done by accepting the request over HTTP, generating a contact ID and transaction ally submitting this to a JMS queue for processing.  For purposes of this example we’ll be using Active MQ as our messaging broker. 

The first step is the front end data submission - the contact information is submitted in the form of a SOAP request to an HTTP inbound endpoint and generates a unique contact ID which can then be returned to the calling application for tracking. 


The contact information is transactionally transmitted to a JMS outbound endpoint which then sends it to another queue for backend processing.

<async doc:name="Async">
<jms:outbound-endpoint queue="contact.submit" connector-ref="Active_MQ" doc:name="JMS">
<jms:client-ack-transaction action="ALWAYS_BEGIN"/>
</jms:outbound-endpoint>
</async> 



This flow accepts the contact information and submits it to two separate branches of a scatter-gather router which concurrently sends this information to Microsoft Dynamic CRM and Salesforce endpoint. 

<jms:inbound-endpoint queue="contact.submit" connector-ref="Active_MQ" doc:name="JMS">
         <jms:transaction action="ALWAYS_BEGIN"/>
</jms:inbound-endpoint>

If at any point during the processing the application crashes, message is redelivered to the endpoint and processing continues. In the case of transactional rollback, a rollback exception strategy is used to redeliver the messages a pre-configured number of times. If the message cannot be processed, it will be sent to a DLQ. One thing to note is that this approach may end up causing a duplicate record to be created for the contact so it may be prudent to have an extra step to lookup the contact in the CRM as well as Salesforce before persisting it. 

<jms:outbound-endpoint queue="contact.complete" connector-ref="Active_MQ" doc:name="JMS">
         <jms:transaction action="JOIN_IF_POSSIBLE"/> 
</jms:outbound-endpoint>

Finally, once the contact has been saved, a message is sent on a queue to indicate completion of the transaction as shown in the following flow.

<jms:inbound-endpoint queue="contact.complete" connector-ref="Active_MQ" doc:name="JMS">
          <jms:transaction action="BEGIN_OR_JOIN"/>
</jms:inbound-endpoint>


Comments

Popular posts from this blog

Anypoint MQ access using POSTMAN

Legacy to API Led Connectivity with Mulesoft

Publish – Subscribe Messaging with Anypoint MQ