Monday, November 23, 2009

Configuring External Application with Oracle BPM (Business Process Manager) using PAPI

A lot of people wonder if there is another way of collecting form data than the normal screen flows. Or, is there a way to trigger external applications from BPM activity execution.
The answer to above questions is yes and it can be done by using interactive activities with main task set to ‘External’.

The use case that I will take to explain this approach is the following:

1. User creates an instance of a process.
2. When the instance reaches a particular activity (let us say ‘CollectFormData’) and the user executes the activity; a form page from an external application comes up.
3. User fills in the form data and submits. This updates the instance data and moves the instance to the next activity.


From Developer’s perspective, we need to do the following:
On Oracle BPM side:

1. Create a new External Resource with Type as ‘Server Configuration’.
Give in the host and port details where your external application is/will be deployed. The path takes in the servlet name that will handle the request.






2. Right click the BPM activity (‘CollectFormData’) which should execute the external application. Select the Main Task. Select the Implementation Type as ‘External’. Under the ‘Configuration’ subsection, select ‘Use Configuration’ option and select the external activity you created in step 1 above.


3. Create the Prepare and Commit Methods.
Prepare Method will be called from your external application’s servlet. This method is responsible to pass the data from Oracle BPM to your external application. Once you have access to this instance specific data, you can take whatever business specific decisions you want before loading the external application webpage.
Click the New button for the Prepare Method and create the arguments under the Arguments view on the right. Remember to change the mode of these arguments from ‘in’ to ‘out’.


Commit Method will be called from your external application’s servlet when the servlet is done with all that it wanted to do. This is also a signal for the BPM that the activity execution is complete and the instance can be moved to the next activity.
Servlet can pass in the arguments (or all the data collected on form) to Oracle BPM using the input arguments for this commit method.
Click on the new button for Commit method and create a method. Set the arguments for this method in ‘in’ mode. The values for these arguments will be set from the external application’s servlet. In the method body, you can set the instance variables using values from appropriate commit method arguments.

Oracle BPM side is all done.
Let us now have a look at the web-application side.


On Web Application side:

When the BPM interactive activity (with main task set to ‘External’) is executed, it looks up the application deployed at the url specified in the Server Configuration (step 1 above). Oracle BPM adds the following url parameters to it.
• activity
• instanceId
• taskIn
• participantId
The default handler of your servlet/bean should handle this and store the values in appropriate variables. Some of these will be used later to call the prepare and commit methods.
This external application can make use of PAPI or PAPI-WS to access the instance data from Oracle BPM. The example code below is based on the use of PAPI.

My previous blog explains how to configure PAPI to work with your Oracle BPM enterprise. Once done you can follow the following steps to work with the external tasks of BPM.

The code and text below makes use of the configuration that was set in the “On Oracle BPM side:” section above.

1. Set up your servlet to accept requests at “myHostName:8080/myBPMExternalActivityServlet”, and handle the url parameters – activity, instanceId, taskIn and participantId
2. If you like you can verify that the activity (passed in as url parameter) is “CollectFormData”
3. Call the prepare method on this instance.

getActivity(), getInstanceId() return the values that were set for activity, instanceId in step 1 above.


public Map callBPMPrepare(){
papisession = initializeOracleBPMPapi();
fuego.papi.Arguments args = fuego.papi.Arguments.create();
args = papisession.activityPrepare(getActivity(), getInstanceId(), args);
if(args == null)
return null;
Map argsMap = args.getArguments();
return argsMap;
}
catch (OperationException e) {
log.log(Level.SEVERE, "Error initializing PAPI", e);
new StripesExceptionHandler().handle(e, getContext().getRequest(), getContext().getResponse(), "Error initializing PAPI");
return null;
}
finally{
if (papisession != null) closePapi(papisession);
}
}


The ‘args’ map would contain all the arguments that were passed from the “collectFormDataPrepareMethod” set in step 3 of section ‘On Oracle BPM side’.

4. Process the arguments and have your business logic here. Show up the jsp page and collect data from user if you want.
5. Call the commit method.
Note that a call to prepare method is essential and should be called before calling the commit method. Call to prepare signifies that the activity has entered the external task execution mode.


public void commitToOracleBPM(Map parameters)
throws SOAPException {
try{
activity = getActivity();
instanceId = getInstanceId();
papisession = initializePapi();
fuego.papi.Arguments args = createPAPIArgs(parameters);
papisession.activityCommit(activity, instanceId, args);
}
catch (OperationException e) {
log.log(Level.SEVERE, "Error initializing PAPI", e);
return;
}
finally{
if (papisession != null) closePapi(papisession);
}
}


public fuego.papi.Arguments createPAPIArgs(Map parameters) {
fuego.papi.Arguments args = fuego.papi.Arguments.create();
Set s = parameters.keySet();
Iterator propNames = s.iterator();
while (propNames.hasNext()){
String key = (String)propNames.next();
String val = (String)parameters.get(key);
args.putArgument(key, val);
}
return args;
}


You can pass the arguments from web application to Oracle BPM using this method. On the Oracle BPM side you would use these arguments to set the instance variables if you need.
This will complete the execution of the activity and instance will move to the next activity.

1 comment:

  1. Hi

    I have a question when the external app finish is posible to refresh the workspace?

    ReplyDelete