Monday, November 14, 2016

Event Based Gateways and Correlations in Oracle Process Cloud Service

The latest Oracle Process Cloud Service release in September 2016 (v16.3.5) added the support of two important functionalities; the "Event Based Gateway" for process branching and "Correlations" for process communication.

These capabilities have been available for quite some time in Oracle's Process Cloud Service counterpart, the Oracle BPM Suite and have been described in detail in two of my blog posts; "Correlations in Oracle BPM 12c" and "Oracle BPM 12c Gateways (Part 5 of 5): Event-based Gateway".

Even though the functional concept is the exactly the same, whether used in an Oracle BPM Suite process or an Oracle Process Cloud Service process, there are yet some small differences, especially with the "Event Based Gateway" in Oracle Process Cloud Service.

So in this blog post we will see, in detail, how you can use the "Event-Based Gateway"to implement divergence and branching in your processes using events generated from external processes. Process communication will be implemented using "Correlations".

The scenario that I will use is quite simple and I will use two processes. The first process will simulate a warehouse inventory process that depending on the order id (supplied as a process request argument) will respond whether the stock item is available or not.

The second process will invoke the "Warehouse Inventory" mockup process using a custom correlation key and will make use of the "Event Based Gateway" to pick the generated event.

So let's start with the implementation of the "Warehouse Inventory" mockup process. Create a new application in Oracle Process Cloud Service, give it a name and file it under a space (I've named it "EventBasedGatewayAndCorrelationsDemoApp" under my personal space).

Next create a new process using the "Message" pattern

Next we will create the "Warehouse Inventory" process. From the "Create a Process" screen, select the "Message" pattern, give your process a name and click on "Create".

Edit the "Start" component, edit the interface by clicking on the "Edit" button next to the "Define Interface" type to add a new request argument called "orderId" of type string.

The "Warehouse" process, depending on the supplied order id will respond back to the caller using a different end message component. But let's first configure the default "Message End" component.

Edit the default "End" component and add two string response arguments, "orderId" and "status" and change the default operation name to "endWithNo". Change also the default label from "End" to "End with NO" (to distinguish between the two operations from the calling process).

Add another "Message End" component and again create two string arguments, "orderId" and "status" and change the default operation name to "endWithYes". Change also the default label to "End with YES".

We will need one process data object to store the incoming order id and pass it back to the response. So click on the "Data Objects" and create a new data object called "orderId" of type string.

Next assign the process input order id argument to the order id process data object. On the "Start Message" select "Open Data Associations" and drag the orderId input argument to the "Start" association input box. Expand the "Process Data" and drag the orderId process data object to the "WarehouseProcess" association input box.

Now that we have the process data objects defined, we can process with providing the data associations on the two "Message End" components. Therefore open the data associations of the "End With YES" task and map the order id process data object to the orderId response argument and a static string (let's say "YES") to the status response argument.

Do the same thing with the "End With NO" task but this time mapping a different static string to the status response argument (for example "NO").

Next we will add an "Exclusive Gateway" between the "Start" and default end message component (if you followed my instructions it should be the "End with NO" message end component). Optionally rename the default "Exclusive Gateway" label to something more meaningful (for example, "Stock is Available?") and add a conditional flow from the "Exclusive Gateway" to the second end message component ("End with YES"). For better readability of the process you can add labels to the default and conditional flows.

If you click on the "Validation" button you should notice that there is a validation error. That's because we have created a conditional flow with an empty condition. So open the conditional flow and define a condition (for example, take that path if the orderId is "123").

Our "Warehouse Inventory" mockup process is now complete. We can now move on with creating our main process, the process that will be calling the "Warehouse Inventory" process.

Create a new process using again the "Message" pattern (I've named this new process "OrderProcess").

This new process will accept and order id and will return a status (both arguments will be of type string). Therefore on the "Start" message component, go its properties, click on the "Edit" button next to the "Define Interface" implementation and create a string argument called orderId.

Using the exact same steps, create a "status" response argument on the "End" message component.

Both arguments will have to be carried along the main process, therefore create two new data objects, using the same names and types.

Just like we did with the "Warehouse Inventory" process, we need to assign the request argument to its respective process data object so that it can be used along the process. So open the "Start" data associations and drag the orderId input argument to the "Start" association input box. Expand the "Process Data" and drag the orderId process data object to the "OrderProcess" association input box.

Using the same approach, we need to map the "status" process data object to the response argument. Open the "End" data associations, expand the "Process Data" and drag the status process data object to the "OrderProcess" association input box. drag the status output argument to the "End" association input box.

We will be invoking the "Warehouse Inventory" process using a "Message Send" component and we will be using the new correlation capabilities support in Oracle Process Cloud Service to define the conversation association between the calling and callee process.

Drag and drop a "Message Send" task between the "Start" and "End" tasks and name it "Invoke Warehouse Process". Open its properties and from the "Type" drop down select "Process Call". Click on the "Edit" pencil button and from the "Process" search box select your "Warehouse" process. The "Target Node" should be automatically populated with the "Start" message.

If you recall, the "Warehouse" process requires an order id to be passed as input. So open the "Message Send" data associations and map the orderId process data object to the orderId send task argument.

Drag and drop an "Event Based Gateway" just after the "Invoke Warehouse Process" send message task and name it "Catch Warehouse Event". Delete the default sequence flow from the "Event Based Gateway" to the "End" task and add two "Message Catch" events and name them "Catch No Event" and "Catch Yes Event" respectively. Add a default sequence flow from the "Event Based Gateway" to the two new "Message Catch" tasks and add a default sequence flow from each of the two "Message Catch" tasks to the "End" task.

We need to define the implementation details of each of the "Message Catch" events. Go to the "Catch No Event", open its properties and from the implementation type drop down select "Process Call" and click on the "Edit" pencil button. From the "Process" search box select your "Warehouse" process and in the "Target Node"select the "End with NO" end message.

The "Warehouse" process, depending on the order id will return a different status (mapped via it's status response argument). So go to the data associations of each of the "Message Catch" tasks and map the status response argument to the status process data object.

The only thing left before we deploy and test our processes is to define the correlations between the calling process (OrderProcess) and callee (WarehouseProcess). Custom correlations, also known as "message-based" correlations 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. This type of correlation enables the definition of multiple attributes referred to as "Correlation Properties" into various correlation sets know as "Correlation Keys".

We will be using only one correlation property and that will be the order id. Click on the "Correlations" button (located above your process on the button toolbar), create a new correlation key and a new string correlation property called orderId. Please make sure you shuffle the correlation property to your correlation key, otherwise you will not be able to use it.

With custom correlations you have the concept of an initializer, the task that set's up the message association agreement and we also have the notion of a correlator, tasks that wait to receive a message using the correlation definition instantiated by the initializer.

In our case the initializer will be the "Message Send" task while the two "Message Catch" tasks will be the correlators. So go the "Invoke Warehouse Process" message send properties, select "Correlations" and click on the "Add" button to add the correlation key you created in the previous step. It should automatically detect the orderId correlation key property. You just need to assign a value to it and this will be the order id process data object.

On each of the "Message Catch" tasks, go to "Properties", then "Correlations" and make sure to switch to the "Correlate" tab and add your correlation key. Again assign the orderId process data object to the orderId correlation property.

One last step before we can deploy is that we have to publish our work. So click on the "Publish" button and in the "Publish Application" popup add a comment and click "Publish".

We are now ready to deploy and test our application. Click on "Deploy" and select "Deploy new version". In the "Select Version" train stop select "Last Published Version" and click "Customize". Leave all defaults on the "Customize" screen and click on the "Validate" button. Ensure that your application is successfully validated and click on "Options". Set a revision id and click on "Deploy".

Since our main order process can only be started using a message, we need to get the endpoint URL and invoke it via SoapUI. To do so click on the "Management" link, locate your application from the list of deployed applications and scroll to the right. Click on the "Actions" button and select "Web Services".

You should have two endpoint URLs, one for the order process and one for the warehouse process. Ensure you copy the order endpoint and using SoapUI invoke an instance of the order process. I will go with the happy path so I've enter order id "123" (please note that you will need to pass your credentials and a timestamp in the header, otherwise you will get a security exception from Oracle Cloud).

From the Oracle Process Cloud Service dashboard click on the "Track Instances" banner to go to instance tracking. Ensure from the filters you've selected "Completed". You should see two instances completed, one from the "Warehouse Process" and one from the "Order Process".

Go to the details of the "Order" process (click on the green arrow) and expand the history view. You should see that the order process followed the "happy" path.

Invoke the process again this time providing an different order id. Go to instance tracking and again you should see a pair of instances. Open the "Order" instance details and you should now see that the process followed the alternative path.

No comments:

Post a Comment