Using JMS queue inside of an aBPM scenario

Inside of the aBPM Framework exists a lot of features and functionalities that helps to realize a custom scenario very quickly, but in some aBPM custom scenarios a JMS Queue is necessary to store trigger messages before an aBPM process instance was persist or an aBPM/BPM process was started. Inside of the following blog you will find a solution for using JMS queues inside of an aBPM Scenario.

Use case:

The aBPM/BPM process could not be started successfully, e.g. in case of an exception or relevant data could not be read before the aBPM/BPM process could be persist or started. In such cases the initial start trigger would be swollow or get lost with no trace of an aBPM process or BPM process with the exception of a log entry inside the default trace. To prevent this behaviour the initial start trigger can be stored into a JMS queue and can be consumed by a message driven bean (MDB).

Hint: There are a lot of technical backgrounds available on help.sap.com about Using Java Message Service inside the SAP Netweaver AS Java. Please take a look into this reference before you continue with this blog.

aBPM solution environment:

The aBPM szenario of this blog is an “inquiry process” that will be started via a web service call from an external system. The implementation of this web service is a generated stateless session bean from a WSDL file that was created inside Enterprise Service Repository (ESR).

The technical implementation of the inquiry process relevant prerequisites (read inquiry data, persist and start aBPM process, etc.) are encapsulated into a “start inquiry process provider” (not part of this blog) that returns a boolean value (true/false). True if the user that should get the inquiry does not exist inside of the UME/user store otherwise false. In case of true an inquiry process cancel message will be triggered with a second JMS queue.

Solution:

The stateless session bean of the web service that receives the trigger to start the inquiry process was generated inside NWDS. A typical implementation of this EJB could look like this:

In this implementation the start provider could run into an exception and the original trigger message will be lost. To prevent this issue a JMS message can be stored into a JMS queue.

There are 2 options to get a reference to the JMS queue:

via resource injection (@Resource)
or

via JNDI lookup

Option 1 can only be used in case one JMS Queue will be used inside an EJB. In this blog two JMS queues will be used (1. to store the initial start trigger, 2. to store the process cancel trigger in case the inquiry user does not exists). That is the reason for the approach of JNDI lookups inside the following source code:

In case of an exception inside the start inquiry process provider a JMS map message will be created and send into the InquiryPrcQueue. The JMS map message contains all releavant data for the start inquiry process provider plus the marshalled payload of the original trigger message for analytics.

In case of no exception and the user doesn’t exists inside the user store another JMS map message will be created and send into the InquiryPrcCancelQueue. This JMS message contains all relevant data for a cancellation of the BPM process (values for the correlation condition).

The usage of constants inside of the map message keys is only to set and get the values in and from the map message in an elegant way.

The next step is to consume those JMS messages via a MDB. Exemplary the MDB for the InquiryPrcQueue will be shown as follows:

The default behaviour of a MDB is a listener pattern on the JMS queue to receive the JMS messages. Inside the onMessage() operation the received message will be consumed and the values of the map message will be used to execute the start inquiry process provider. In case of success the message will be automatically deleted/confirmed. In case of an exception a runtime exception will be thrown to inform the JMS server to increase the max delivery attempts counter of the JMS message. The MDB tries to consume the message after an interval again. In case the max delivery attempts limit is reached the message will automatically be moved into an error queue. Otherwise the same message with the same error will executed until the judgement day.

The implementation of the MDB is “nearly” the same like in the stateless session bean of the web service implementation to start the aBPM/BPM process. The only difference is that the web service implementation works on the original payload values of the trigger message during the MDB works an the JMS message values.

In the last steps of this blogs the snippets of the XML files of the EJB and the JMS deployment descriptor of the EAR file are shown.