Using Intermediate Events and Advanced TaskService Interactions in Oracle BPM Suite 11g

This blog post will demonstrate with the help of a basic use-case the use and importance of intermediate events in Oracle BPM based processes. A typical business process also has manual touch points that are implemented by process users through Human Task UI’s. It is evident that a very important aspect in any agile business process is the ability to interact with these in-flight human tasks based on intermediate events. This post shall also demonstrate how to modify in-flight task States in Oracle BPM Suite 11g. You can similarly do a host of other operations with the full use of the Worklist Management API’s.  Keep reading.

Intermediate Events occur in the middle of the process and are of either Catch or Throw type. The Catch Events wait or block for appropriate signals while the Throw events proceed after throwing the signal.

The Basic Use Case

XYZ Bank has a simple business process defined for a Credit Card approval flow. Below are some important activities that any card application request has to go through.

Manual Card Approval

All requests that require further investigation (i.e. applications that cannot be pre approved using the business rules) should be sent to analysts belonging to the Credit Card Approvers role. The approver can complete the review by either Approving or Rejecting the request.

Cancel Card Application Event

While a card application request is in process, a customer can indicate that they wish to cancel their request. The customer is asked to provide an optional reason for wanting to cancel the request. The result of the cancellation request can be:

  • The request was cancelled
  • The request could not be cancelled because it had already been completed.

In that case the outcome of the original request should be provided to the customer.

Note : This example doesn’t deals with the cancellation scenario. This is explained in details in my previous blog post.

https://beatechnologies.wordpress.com/2011/10/17/working-with-custom-correlation-in-oracle-bpm-suite-11g-ps4-feature-pack/

Potential Fraud

There is an external process that is evaluating increase requests to look for patterns that might signal fraud. When the pattern is matched, the process generates an Handle Fraud Event for a specific application request with a score that indicates that fraud is:

Probable ( Score =< 8 )

Possible ( Score >8 )

The process needs to listen for these events and take the following actions when the Handle Fraud Event is for the specific request that is in flight.

For Possible Fraud

When a possible fraud is recorded the existing process should be terminated. Before terminating the process the Manual Approval In-Flight task (if any) should also be withdrawn.

For Probable Fraud

An Ad-Hoc Manual Task should be created for the role FraudInvestigator. While the investigation is ongoing, the normal path of process must be suspended. The outcomes of the investigation is either APPROVE or REJECT. If the outcome is REJECT the current card application request likely represents fraud, or NO, the current increase request does not represent fraud. If the investigation result is APPROVE, the normal approval processing should be resumed unless the process has been tagged as cancelled.

Refer the business process diagram below to understand the use case better.

image

Prerequisites

The following version of software have been used to for this example and demonstration.

  • JDeveloper 11g PS4 (With BPM-SOA FP Extension)
  • PS4 FP SOA and BPM Extensions for JDeveloper
  • Oracle BPM Suite 11g PS4 Feature Pack

More information about downloading it can be found here

Implementing the Process

Oracle  SOA Suite leverages the Human Workflow Engine to implement Manual/User Tasks. The Human Workflow Engine exposes APIs (both Java and Web Service based) which can be used to interact with Tasks for specific business needs. There are Task Management Services which can be used to alter States of in-flight tasks, Task Query Service that can query for task details based on taskId, taskNumber or other task Predicates.

In this example I will show how we can use the TaskService to manipulate task states from within a business process.

Getting the Task Id for the “Approve Card Manually” user task.

The first thing to do is create a Process Data Object called manualTaskApprovalId to hold the value of the generated Task Id for the manual Task. The data object should be assigned the value of execData.systemAttributes.taskId from the Output tab in the Data Association for the task activity.

image

We will use this obtained taskId to invoke operations on the TaskService API.

Creating a Reference to the TaskService in the Composite Application

Next we will have to create a reference to the TaskService.wsdl in our composite. The TaskService.wsdl can be located in the soainfra metadata store partition.

image

The operations of the TaskService Web Service API’s now appear in the External Reference panel of the composite application.

Create a Mediator Component that acts as a Proxy to the TaskService Interface

Drop a Mediator Component into the composite and Define its interface from the TaskService.wsdl that is now copied into the project directory. In case you have chosen not to copy the wsdl and its dependent artifacts into the project you can refer it from the MDS. It is just the same. Also uncheck the Create Composite Service with SOAP bindings since we will only need to invoke it from within the composite.

Double click on the Mediator Component you just created. We will see that all operations in the TaskService interface appear in the Mediator. Go to the suspendTask operation in the Mediator and create a static routing rule  for it. The static routing rule should invoke a Service. From the wizard prompt use the suspendTask operation from the TaskService interface.

image

In a similar way create the static routing for other two operations i.e withdrawTask and resumeTask.

Fraud Check Event Subprocess

Coming to the Fraud check event sun-process the first thing we need to do is define correlation for the Handle Fraud start event. This is required as this is an intermediate event and this need to correlate with the desired in-flight process instance.
image

To know more about the use of correlation in Oracle BPM 11g read my previous post here.

When there is a Probable Fraud i.e fraud check score is less than 8 the process needs to be suspended in case it is awaiting for manual approval.

This can be achieved quite easily. All that we have to do is create a Service Task Activity and invoke the suspendTask operation of the TaskFlowMediator.

To keep this absolutely simple the only input required for suspendTask operation is the taskId for the Approve Card Manually Task that we had captured earlier in a process data object.

image

This will suspend the Manual Approval task and hence the process instance cannot  move ahead unless it is withdrawn or resumed and subsequently Approved or Rejected.

Depending upon the outcome of the Ad Hoc Approval by the FraudInvestigator role the process can either be Resumed and the original process flow continue (as the Handle Fault Event was defined as a non Interrupting Event) or it can be withdrawn the process Terminated.

This is pretty much it about the defining the main tasks and services in the process. You can find the Composite Application attached here to be more acquainted with the process flow.

Testing the Process and Verifying the Results

Post deployment of the composite application to a running server we cam test it. The composite exposes three operations (approveCard, cancelCardRequest and handleFraudEvent). Let us start to test the composite by invoking the approveCard operation that will start the card application approval process.

image

As you observed the instance has moved to the ManualCardApproval touch point and is awaiting for a response from a user with CreditCardApprover role.

image

Now let say a Fraud Event is reported now for this instance while the CreditCardApprover still hasn’t dealt with this task. In this case the Fraud Event Subprocess should kick off and the FraudInvestigator is involved for Ad Hoc Approval in case the fraud is probable.

We can emulate this scenario by unit testing the composite once again. But this time we will invoke the handleFraudEvent opetation of the composite. One important point to note here is that since we are using the customer contact number to correlate the fraudEvent with the in-flight instance, we need to have the same customer contact number in the request of this operation.

image

The effect of a fraud intermediate event is that the original task assigned to the CreditCardApprover role will be suspended and hence the process instance is stalled.

The FraudInvestigator has to provide an ad hoc response to confirm/reject this probable fault. So an Ad Hoc Approval Task awaits his response in his worklist.

image

If the FraudInvestigator approves the application then the original task is once again resumed and appears in the Assigned state in the CreditCardApprover’s worklist. Once it is approved once again (this time the approval is based on things like applicant’s eligibility, credit score, limit requested etc) the process is successfully completed.

image

The entire process flow diagram will give a picture of the path that the process took during its Happy-Path completion.

image

Testing the Unhappy Path – FraudInvestigator Confirms a Probable Fraud

To test this follow a couple of steps that we did earlier i.e. invoking an approveCard operation and then invoking the intermediate fraud check event operation for the same customer.

The flow will be similar to the above till here. The Fraud Investigator will have an Ad Hoc Approval Task and the original task will be suspended.

Now if the FraudInvestigator confirms a fraud in the application then the process instance is terminated and the original Manual Card Approval task is withdrawn.

image

A look at the process flow will now reveal that the process instance doesn’t moves back to the original instance (Since it is Terminated).

image

That’s is with the process.

Conclusion

This article deals with some advanced concepts around Oracle BPM Suite 11g. Hope it explains how we can effectively use intermediate events (of both Interrupting and Non-Interrupting Type). It also explains how we can interact with the Worklist API’s using the TaskService interface to interact with Human Workflow tasks from within a BPM process.

The composite used for the demonstration can be downloaded from this location or from here

Please send across your questions, commends and feedback and i will be eager to answer them.

.

Persisting Component Preferences in Oracle SOA Suite 11g

This is supposed to be a very short post on overcoming a problem with BPEL Properties/Preferences that we set at design time so that we have the option of changing their values at runtime from the Enterprise Manager.

Preferences are very useful and the following blogpost by Eric Elzinga demonstrates how we can use them

http://eelzinga.wordpress.com/2009/10/28/oracle-soa-suite-11g-setting-and-getting-preferences/

However these Preference values does not withstand a server bounce . They are rest back to the old values automatically after the bounce.This was not the case in 10g.

The Problem with BPEL Preferences

  • Connect to Fusion Middleware Control.
  • Expand SOA -> soa-infra -> default and highlight “default”.
  • Navigate to SOA Infrastructure -> Administration -> System MBean Browser.
  • Navigate to Application Defined MBeans -> oracle.soa.config -> Server: soa_server1 -> SCAComposite.

Pic1

  • Expand the <SCA composite> -> SCAComposite.SCAComponent and highlight the BPEL Component.
  • Click on the Attribute Properties.
  • Expand Element_N and change value key for name bpel.preference.<PREFERENCE_NAME>.
  • Click Apply.
  • Restart the SOA server and now PREFERENCE_NAME contains the orginal initial value instead of the expected updated value.

Pic2

The Solution to Persist the Changed Values of Preferences

  • After you Apply the change to bpel.preference.<PREFERENCE_NAME>, click Return.
  • Click Operations tab.
  • Click on the Attribute Save.
  • Click the Invoke button.
  • Click Return.

Pic3

When the server is restarted, the System MBean updated value is maintained.

.

Where did my SAF Queue go? JMS Adapter in JDeveloper unable to Locate SAF Queues

I observed a strange behavior while configuring JMS Adapter in a JDeveloper composite recently. I had created a SAF Destination with some SAF queues. However while creating a JMS Adapter service to produce a message into this queue I noticed that the JDeveloper Adapter creation wizard is unable to locate these queues.

SAF Queues were however added to the SAF Imported Destination

SAFQueue

However while creating a JMS adapter to produce message to this queue from JDeveloper, to my surprise I wasn’t able to locate it.

SAFQueueNotFound

First apprehension that i feared about was whether JMS Adapter supports Activation and Interaction specs with SAF queues. However there is actually no difference between a normal queue and a queue configured on SAF. It has a subdeployment, is targeted to a valid managed server, has a persistent store and a valid JNDI.

Fortunately I had a solution. And it came when I tried locating the JNDI of the queues configured on SAF.

QueueJNDI

The JNDI name of the queue is prefixed with saf. (saf with period) because this is how i had configured my SAF Imported Destination

queueJNDI

In the JMS Adapter JCA file use this name (or the JNDI Binding name of the queue) after having configured the Adapter in JDeveloper. It would still give the “Queue Could not be Found” warning but ignore it.

Deployed the application and produced a message to the JMS Adapter service.

I was able to see the message produced from my composite application by monitoring the SAF agent.

queueMessage

.

Oracle SOA Suite JMS Adapter : Setting/Getting Custom JMS Properties

Oracle SOA Suite provides for a variety of technology adapters based on the JCA framework that we can leverage while designing business processes in either Oracle SOA or BPM Suite.

There are a wide variety of adapters for processing messages in and out from DB, JMS, File Systems, AQs, socket etc.

Although Oracle has a seemingly exhaustive documentation on how to use each one of them, I recently found out that there are some very important things that are missing from Oracle Fusion Middleware documentation.

While working with the JMS adapter in my business process I was required to get and set some custom properties in my JMS message. I was truly disappointed when even after searching the technology specifications i wasn’t able to find a way to do it.

I finally managed to get it working and in this blog post i will show how we can set or get custom JMS properties to a message while inserting it into a JMS queue or reading from it.

Let me start with a very basic order booking composite application that saves orders to a jms queue. The need is to pass some custom user headers along with the order payload.

image

The Custom JMS Headers/Properties is passed from the Mediator component to the JMS Adapter service.

Open on the Mediator .mplan file in JDeveloper. In the Static Routing pane click on the Assign Values icon that opens the assignment wizard.

Custom JMS Headers can be get/set by using the following expression in Mediator

$in.property.jca.jms.JMSProperty.<CustomPropertyName>

is where you set/get the name of custom JMS Property

The property value can be assigned to any variable in the component and similarly a value can be assigned to the property from any component variable

image

Compile, deploy and then invoke the composite with an HTTP SOAP request. Once the message is enqueued in the JMS queue.

Login to the weblogic console and check the queue for the order booking jms message.

You’ll notice that the Custom Properties are set in the JMS message along with the standard JMS Headers

image

If you want to use a JMS Adapter to consume message inside a composite you can get the custom properties in a similar way.

.

Oracle BPM Human Task Management : Using Human Task Events to Invoke Microsoft Exchange Web Services

Recently while working on a specific use case for an enterprise where I had to develop a mechanism of notifying organizational users in case a human workflow task is assigned to them. The enterprise in consideration here had a need to create an Microsoft Exchange Task for the user once he is assigned with a BPM Human Task and need to act on it.

In this blog post I would be covering as how we can achieve this. This may also be useful in case you are required to use Exchange Web Services in Oracle SOA Suite. Before i begin I would like to cover a little bit of rationale behind this approach.

The Rationale to this Approach

Oracle Human Workflow Tasks allow us to configure Notification settings through which we can can Email/SMS notifications through the Notification service. For a human task we can choose to set reminders at preset intervals, send actionable links in notification emails, attach task attachments, add custom headers etc.

image

However our need was quite simple. What we needed was to simply create a Outlook Task for the assigned user that will take care of Reminders. Imagine a task in which we have some bulky attachments. Retrying from the Notification Service by leveraging the Oracle Taskflow Messaging mechanism is quite expensive as this leads to multiple emails being sent.

Creating a Recurring Task saves us from repetitive emails. We can use recurring Outlook Task for reminders.

image

Readying the Backbone

A bit about Exchange Web Service APIs

Microsoft provides a very rich and exhaustive set of API as well as Developer SDK’s for Exchange web services.

You can see the whole list of operations provided by the API in the link below

http://msdn.microsoft.com/en-us/library/bb409286%28v=EXCHG.140%29.aspx

In this post however i will be demonstrating how to invoke the “CreateItem” operation to create a user Task in outlook.

The WSDL for the exchange web services can be obtained at by typing the following in your browser.

https://exchangeServerURL/EWS/Services.wsdl

image

You can obtain the Exchange Service URL by opening Outlook->File->Account Settings

image

I was able to get this web service running from a web service client like SOAPUI to see it in action.

The Exchange Web Services are on HTTPS and require HTTP Basic Authentication credential to invoke the caller. They are no different from your NT Credentials.

image

However Off course we would need to invoke this service from within our SOA Suite domain. But this gives us a heads up about the working of Exchange web services.

Oracle Service Bus Plumbing to Invoke The Exchange Web Services

This part is somehow tricky. We would need to invoke the Exchange service from the Human Task Service. Since Oracle Service Bus is the place where we organize our enterprise wide reusable services i choose to implement the service call to the Exchange endpoint from within the bus.

That shouldn’t be difficult.

Create a  Proxy Service in OSB based on the Exchange service WSDL. Also copy the dependent XSD’s in the service bus project.

image

This is the place I had hit my first roadblock. The Exchange Web Services need a NTLM Authentication mechanism where as OSB doesn’t support NTLM out of the box. The workaround for this is that we have to create a custom Java class for doing this which can be invoked from OSB by a Java Callout action.

Create a simple Java Project in Eclipse and use the Java Class below. It works like a treat to get this thing done.

package blog.soatech;
import java.io.IOException;</pre>
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NTCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;

public class ExchangeServices {
private static final String userAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13";
@SuppressWarnings("unused")
public static String invokeExService(String endPoint, String messageHeader, String messageBody, String userName, String password, String operation) throws HttpException, IOException
{
StringBuffer soapMessage = new StringBuffer();
soapMessage.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
soapMessage.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:typ=\"http://schemas.microsoft.com/exchange/services/2006/types\" xmlns:mes=\"http://schemas.microsoft.com/exchange/services/2006/messages\">\n");
soapMessage.append(messageHeader);
soapMessage.append(messageBody);
soapMessage.append("</soapenv:Envelope>\n");
//System.out.print("Request : " + soapMessage.toString());
HttpClient client = new HttpClient();
String soapAction ="http://schemas.microsoft.com/exchange/services/2006/messages/"+operation;</a>
PostMethod postMethod = new PostMethod(endPoint.trim());
postMethod.setRequestHeader("SOAPAction", soapAction);
postMethod.setRequestHeader("Content-Type", "text/xml; charset=UTF-8");
postMethod.setRequestHeader("SOAPAction", soapAction);
postMethod.setRequestHeader("User-Agent", userAgent);
postMethod.setRequestEntity(new StringRequestEntity(soapMessage.toString().trim(), "text/xml; charset=UTF-8", null));
String errorMessage ="";
String responseBodyString ="";
NTCredentials ntCredentials = new NTCredentials(userName, password, "hostName", "domainName");
client.getState().setCredentials(new AuthScope(null,-1,null), ntCredentials);
int status = client.executeMethod(postMethod);
if(status != HttpStatus.SC_OK)
{
errorMessage = "Method Failed :" + postMethod.getStatusLine();
// System.out.println(errorMessage);
}
responseBodyString= postMethod.getResponseBodyAsString();
//System.out.println("Response Message ;" +responseBodyString);
return responseBodyString;
}
}

The above class is needs a few Apache Jar’s as dependent jars in the build path.

image

Package this as a JAR file by exporting it as a JAR from eclipse. Next we will have to import this JAR in our OSB project so that the ExchangeService.class inside it can be used for Java Callout.

image

Add a line the setDomainEnv.cmd file in the OSB Domain so that it can locate these classpath entries at runtime.

set POST_CLASSPATH=%DOMAIN_HOME%\lib\commons-codec-1.5.jar;%DOMAIN_HOME%\lib\commons-httpclient-3.1.jar;%DOMAIN_HOME%\lib\commons-logging-1.1.1.jar;%POST_CLASSPATH%

The second thing that we need to do is add the Exchange service certificate to the Keystore of the OSB domain. Remember the Exchange services are https services.

Obtain the X.509 certificate from the exchange server and save it as a .pem file. Locate the location of the DemoKeyStore from the weblogic server console.

image

The X.509 certificate from the exchange server can be imported in the keystore by running the Keytool command below

keytool -import -trustcacerts -file <FileLoc>\cert.pem -keystore <KeyStoreLoc>\DemoTrust.jks

The default keystore password is DemoTrustKeyStorePassPhrase

Reboot the OSB Domain after applying these changes for them to take affect.

Lastly export the OSB Proxy Service as a WSDL so that it can be used in our BPM composite.

image

We can now move on to create the BPM process with a Human task that will invoke this OSB service.

Creating the BPM Composite with a Human Task

For the purpose of demonstration here I will be creating the most basic BPM process that has one message start event, one user task event (implemented as an Oracle Human Task) and an end event.

image

The process can be exposed as a web service since it has a Message Start event. This is a simple Card Approval Process in which a Credit Card Approver is presented with a Credit Card request that he has to either approve or reject.

The Task Activity is implemented as a Human Workflow Task. Open the .task for this task in JDeveloper.

We can enter additional task details from here like Task Title, Task Deadlines, Assignees, Notification Setting etc.

Add a Fixed Duration Deadline to this Task in the Deadlines tab.

image

This will set the expirationDate element in the task payload.

This is also where lies the crux of this article.

Since we want to create an Exchange Task for the assignee as soon as the Human Task is assigned to him we have to create and implement an onAssigned Event for this task.

image

You are allowed to create different events based on the task status from here. For now we are only interested in the first event i.e onAssigned event.

When a workflow event is triggered the in build EDN (Event Delivery Network) framework throws an event that contains the assigned Task Message payload containing the complete task information.

Learn more about EDN in Oracle SOA Suite here.

https://beatechnologies.wordpress.com/2011/06/14/lightweight-introduction-to-oracle-soa-suite-11g/

http://blogs.oracle.com/soabpm/entry/event_delivery_network_chapter

Creating a Mediator to Subscribe to Workflow Events

We have raised an event from the Human Task. We now have to implement a listener for this event that can listen to it and do something (calling the Exchange Service operations in this case).

Doing this couldn’t have been much simpler. What you need to do is create a composite application that has a Mediator component listening to this event.

image

The Event Definition File (EDL) for subscribing to Human Workflow events can be found in the MDS Repository under soa/shared/workflow/HumanTaskEvent.edl.

The mediator can subscribe to any one or all of the events and will fan out the process depending upon the event it receives.

image

Next create a Web service reference in the composite that is based on the Exchange Service OSB Proxy and wire the Mediator to Create Item of this service.

image

Open the Mediator Routing Definition to see that the a Static Routing Rule has been created for OnTaskAssigned event.

We can use the an XSL based Transformation to transform a task request to the CreateItemRequest message for the Exchange webservice.

image

Deploy the BPM Application for Card Approval Process and also the composite application containing the Event Subscribing Mediator component to a running soa server so see everything in action together.

Seeing Everything in Action

Go to the Enterprise Manager console where the Card Approval BPM composite is deployed.

Test the composite with a card approval request message from the composite. You will see that a running instance of the composite is created.

image

Looking at the Audit Trail of this instance will reveal an interesting thing. You will see that as soon as the the process flow reaches the ApproveCard user activity an OnTaskAssigned event is fired.

A WorkflowEventSubcriber Mediator Component that is listening to this type of event processes the event and calls the external web service. Opening the trace will further reveal that the service has returned a success response.

image

An outlook Task with a recurring reminder has now been created in the user inbox.

image

The Ending Conclusion

Another thing we did was to delete this Outlook task once a Human Workflow participant has acted on the it.

This is quite simple and achievable by raising an OnTaskCompleted event from the Human Task, extending the composite to subscribe to this type of event as well and call the DeleteItem operation on the Exchange web service.

Please feel free to post your questions and suggestions here.

.