Monday, February 15, 2016

Correlations in Oracle BPM 12c

Correlations in Oracle Business Process Management (BPM) is a special mechanism used to associate a message with a conversation between different partners in a business process.

There are two types of correlations:
  • Automatic: This is the default and out-of-the-box correlation used between two business partners which makes use of a special token called "Conversation Id" to uniquely associate a message with a conversation via Web Service Addressing (WS-Addressing) to correlate a callback message using the "Conversation Id".
  • Message Based: This type of correlation enables the definition and use of "business-friendly" information carried as part of the message payload to be used to uniquely identify and associate a message with a conversation (for example, OrderId, CustomerId, etc.). This type of correlation enables the definition of multiple attributes referred to as "Correlation Properties" into various correlation sets know as "Correlation Keys".
So let's see how you to use the two correlation types in a demo scenario. The simulated process will invoke an asynchronous process first by using the default correlations and then by using message-based correlations.

Create the basic BPM application and BPM project (I named it OracleBPM12cCorrelationsDemoApp and OracleBPM12cCorrelationsDemo respectively) and choose "Composite with BPMN Process" in step 3 of the "Create BPM Application" and click “Finish”.
This will bring up the “BPMN 2.0 Process Wizard”. Give your process a name (for example “DemoProcess” and select the “Asynchronous Service” message pattern. In the second step of the wizard I will define a single input string argument that I will name “MyId” and a single output string argument that I will name "MyStatus".

The first thing that I will do is to create two corresponding string process data objects, the first one to pass the “MyId” process input argument for reference throughout the process and the second one to be used later for assigning the process output argument.

Next using the "Start Message" data associations assign the "MyId" process input argument to the "myId" process data object.

To simulate the interruption between business partners in a business process I will create another asynchronous process which I will then invoke from the main process.

So create a new "Asynchronous Process" (named it "DemoReUsableProcess") with a single string input argument (MyId) and a single string output argument (MyId).

As as we did with the main process create a a string process data object to pass the MyId process input argument for reference throughout the process.

Using the "Start Message" data associations assign the "MyId" process input argument to the "myId" process data object.

Drag and drop an interactive human task activity onto the sequence flow that connects the message start and message end components to simulate difference approval scenarios.

Give your human task activity a name (for example "Demo User Task"). From the "Implementation" tab click on the green "Add" button to create a new definition. Specify a name, (for example DemoHT) and leave the rest on defaults.  

Before closing the properties of the first human task activity make sure you specify a title it (just as you would like it to appear in the BPM Workspace task inbox; I named it “Demo User Task”).

To simplify the assignment of tasks, open the human task definition file and in the task assignments switch from lane participants to "Names and Expressions" and define "weblogic" as the user to be assigned our order item tasks.

Based on the human task outcome (approved or rejected) the "DemoReUsableProcess" will respond using a different operation. Therefore drag an exclusive gateway right after the human task activity and name it "Outcome?".

Open the properties of the "End Message" component and change the default callback operation name from "end" to "reject".

Open the data associations of the reject "End Message" component and ensure you map the "myId" input data object to the the "MyId" argument of the "End Message". This is crucial as the custom correlation will be based on this argument.

Drag another "End Message" component and this time define it's callback operation to "approve" (ensure that you have created a string argument just like the default "End Message" operation).

Open the data associations of the approve "End Message" component and ensure you map the "myId" input data object to the the "MyId" argument of the "End Message". This is crucial as the custom correlation will be based on this argument.

Open the properties of the human task component and from the data associations go to the "Output" tab and first create a new string data object and then map the human task string output argument to your newly created string data object. The human task data association assignment should look like below.

Add a conditional sequence flow from the exclusive gateway to the second "End Message" component with the XPath expression set to bpmn:getDataObject('outcome') = 'APPROVE'


Your simulated business partner process should look as follow.

We are now ready to invoke our re-usable process from our main process. Open your main process and place a "Send" activity between the "Start" and "End" components. From the implementation tab select "Process Call" as the type and select your re-usable process.

Place an "Event-based" gateway right after the "Send" activity and rename it to "Outcome". JDeveloper should have created for you a "Message Catch" event and a "Timer Catch" event. We will use a "Receive" activity to asynchronously receive the response from our re-usable process so go ahead and remove the "Message Catch" event.

Open the "Timer Catch" event and set its time cycle to 1 minute (in case there isn't a reply from the asynchronous sub-process the "Timer Catch" event will get kick-started).

Extend the "Event-based" activity with two additional "Receive" activities. Your main process should look as follows:
The two new "Receive" activities are marked with a warning sign to indicate that no implementation is defined yet. So go to the properties of the first "Receive" activity (Approve Msg) and from the implementation type select "Process Call". Select your re-usable process and select the appropriate target node.

Do the same thing with the second "Receive" activity but this time select the other target node option (in my case it's the "Reject" target node).
We are now ready to define our custom correlation. Open the "Send" task and from the "Implementation" tab click on "Correlations". In the "Correlation Definition" window click on the "New Correlation Property" button to create a new correlation property. This will be a string correlation property which i named "myCorrelationId". Ensure that you have selected the "Initiates" check-box and assign the "MyId" argument to your correlation property.

We also need to define the same correlation properties on the two "Receive" activities. So go to your first "Receive" activity and from the "Implementation" tab click on "Correlations". From the correlation property drop-down list select the correlation property created just above. Map the "MyId" argument to your correlation property.

Apply the same correlation definition to the second "Receive" activity and deploy your process and test your process. If you inspect the audit trail you should see that the instance is waiting at the event-based split gateway activity.

Go to the BPM Workspace and submit the pending task (either approve or reject it). If you go back to the audit trail you should see the related branch being followed.


Download sample application: Correlations in Oracle BPM 12c

2 comments:

  1. Hi, Nice article.

    I have a question, how i will make call back for this request?? I did not see any testing URL link or any documentation over oracle by which oracle BPM call back can be done, Can you please let me know i have a requirement of callback.

    ReplyDelete
    Replies
    1. Hi Sandeep,
      The BPM engine handles the callback for you. Didn't quite get your use case. Maybe you would like to explain a bit more of what you are trying to achieve?
      Cheers
      Antonis

      Delete