Monday, July 6, 2015

Oracle BPM 12c Events (Part 3 of 3): Intermediate Events

The third and last set of events are referred to as "Intermediate Events" and as the name implies they can occur between the start events and end events.

"Intermediate Events" are sub-classified into two groups, "Catch Events" and "Throw Events".

"Catch Events" can occur anywhere in the middle of the process and what they do is that they block the process for specific conditions. We do have a variety of "Catch Event" activities such as a "Catch Message", a "Catch Timer" and a "Catch Signal" activity.

The "Catch Timer" event provides a delay mechanism in a process flow. The delay can be based on a specific date and time or on a recurring interval, for example, every day at a specific time.

The "Catch Message" activity is also used to model a request-response and receive-reply patterns. It is equivalent to a BPEL receive, so instead of having a "Send Activity" to call a service or a process and a "Receive Activity" to receive the response from a service or a process, you can use a "Throw Message" and a "Catch Message" respectively.

"Catch Events" also have a really nice capability as they can be attached as boundary catch events. What this means is that you can configure a task or a sub-process to listen to internal or external triggers.

For example, if a specific service does not respond back within a specified time frame to resume process execution.

Boundary events are either interrupting or non-interrupting. In the case of an interrupting boundary event the normal flow is interrupted and the exception path is taken. In the case of a non-interrupting boundary event then both normal flow and exception paths are executed. We usually use boundary events to handle exceptions.

"Throw Events" on the other hand can throw a message or a signal to another participant or process.

The "Throw Message" activity is used to send a message and is typically used to invoke an other BPMN process, a BPEL process, a SOA service adapter or a mediator that is exposed as a service.

The "Throw Signal" event activity is used to publish or broadcast a signal. You can use a combination of signal throw and signal start events to invoke multiple processes simultaneously.

So let's see how you can use a boundary event, more specifically the timer catch event as a boundary event, to wait for a service response. If the service doesn't reply back within a specified time-frame the process should terminate (but I will also be showing the non-interrupting feature of a boundary event).

For this demo I will need a service to simulate the order validation service. So i created a Java method to mock the order validation service and exposed it as a web service.

The order validation service is really simple; it accepts two parameters, an order id and another int representing the thread delay. The service just returns a boolean. The process will call this service and will pass it the delay. The service will wait for the supplied delay and return back a boolean based on the supplied order id.

Create the basic BPM application and BPM project with an asynchronous BPMN process that takes two integer parameters, orderId and serviceDelayInSeconds.

Create two integer process data objects to store the process arguments for reference throughout the process.

Assign the process arguments to the process data objects (on the "Start Message" select "Properties", "Implementation", "Data Associations" and drag source argument to target data object).

Next we will have to call the "Validate Order" service and to do so we need to first include an external reference to the service. To do so I will use a "SOAP Adapter" and I will drop it onto the "External References" swim-lane.

Enter a name for your service reference and in the "WSDL URL" enter the WSDL URL of your service.

In the "Localize Files" screen uncheck both copy options.

We will next use a "Service" activity in our BPMN process to call the service via the reference created above. So drop a "Service" activity between the "Start" and "End" events and give your service activity a name (i named it " Validate Order Service").

In the "Implementation" tab, from the "Type" drop down select "Service Call" and using the browse button next to the "Service" field select the validate order service.

The "Validate Order Service" requires two parameters to be passed; the order id and a delay in seconds. So using the "Data Associations" map the orderId and serviceDelayInSeconds data objects to the service's arguments.

Let's assume that if the service responds back in less than 5 seconds then the process should follow the normal path, otherwise the process should follow a different path. To simulate this alternative path I will use a script task.

The script activity is marked as error-ed; that's because it doesn't have an incoming or outgoing sequence flow.

Next we will define the timer boundary activity. Select the "Catch Timer" event and drop it onto the service task. Give your boundary event a name (for example; "Response SLA") and in the implementation tab define an appropriate timer definition (in my case I defined a timer expression of 5 seconds).

Please note that just below the "Implementation Type" there are two checkboxes; "Interrupting Event" and "Suspending Event". I chose the "Interrupting Event" option, meaning that when this event fires the token will leave the main process and follow the flow the timer defines.

Next add a default sequence flow from your "Catch Timer" boundary event to the script task and a default sequence flow from the script task to the "Message End" activity.

Deploy your process and instantiate a new instance of your process using the Enterprise Manager. Enter an order id (for example 12345) and in the serviceDelayInSeconds enter a number that is less than the configuration of your "Catch Timer", for example, 2.

Go to the flow instances and inspect your instance; the "Catch Timer" boundary event didn't fire and the process followed the normal path.

Run another test but this time enter a delay that is greater than the configuration of your "Catch Timer", for example 7. Inspect your instance, you should notice that the boundary event fired and that the process left the main path and followed the path defined by the boundary event.

Download sample application: Intermediate Events

No comments:

Post a Comment