Skip to content
June 19, 2012 / danielsoaresmartins

How to cancel a sequence of BPM processes

Today we will demonstrate how to cancel a sequence of BPM process instances typically seen in the audit trail. This is useful when BPM processes invoke other BPM processes (and so on) creating a sequence of active BPM processes under the same execution context.

Instead of modeling a cancelation interface in all BPM processes (e.g. event sub process) complicating the process flows we used two Oracle APIs.

The SOA Infrastructure API was used to query for BPM SOA components under the same execution context, that is, all BPM components with the same ECID (execution context id).

After this we used the BPM API to acquire and cancel the corresponding BPM Process instances.

Here is a code sample:

 package pt.link.middleware.demo;

import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import javax.naming.Context;

import oracle.bpel.services.bpm.common.IBPMContext;
import oracle.bpel.services.workflow.client.IWorkflowServiceClientConstants;

import oracle.bpm.client.BPMServiceClientFactory;
import oracle.bpm.services.client.IBPMServiceClient;
import oracle.bpm.services.instancemanagement.IInstanceManagementService;
import oracle.bpm.services.instancemanagement.model.IProcessInstance;

import oracle.soa.management.facade.ComponentInstance;
import oracle.soa.management.facade.Locator;
import oracle.soa.management.facade.LocatorFactory;
import oracle.soa.management.util.ComponentInstanceFilter;

public class CancelBpmProcess {
public CancelBpmProcess() {
super();
}

public static void cancelProcess(String hostname, String port, String username, String password, String processID)
throws IllegalArgumentException, Exception
{
//Basic validations
if(hostname == null || hostname.isEmpty()){
throw new IllegalArgumentException("Invalid hostname");
}
if(port == null || port.isEmpty()){
throw new IllegalArgumentException("Invalid port");
}
if(username == null || username.isEmpty()){
throw new IllegalArgumentException("Invalid username");
}
if(password == null || password.isEmpty()){
throw new IllegalArgumentException("Invalid password");
}
if(processID == null || processID.isEmpty()){
throw new IllegalArgumentException("Invalid processID");
}

/**
* Step 1 - Retrieve the SOA Component instance representing the BPM process using the SOA Infrastructure API.
*
* SOA Infrastructure API Javadoc: http://docs.oracle.com/cd/E28389_01/apirefs.1111/e10659/index.html
*
**/
//Set up the SOA API connection properties
Hashtable jndiConfigProperties = new Hashtable();
jndiConfigProperties.put(Context.PROVIDER_URL, "t3://" + hostname + ":" + port + "/soa-infra");
jndiConfigProperties.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
jndiConfigProperties.put(Context.SECURITY_PRINCIPAL, username);
jndiConfigProperties.put(Context.SECURITY_CREDENTIALS, password);
jndiConfigProperties.put("dedicated.connection", "true");

//Acquire the locator service
Locator locatorService = LocatorFactory.createLocator(jndiConfigProperties);

//Create the bpm component search filter
ComponentInstanceFilter searchFilter = new ComponentInstanceFilter();
searchFilter.setEngineType(Locator.SE_BPMN); //only BPM processes
searchFilter.setId("bpmn:" + processID);

//Retrieve the bpm component instance
List<ComponentInstance> bpmSoaComponents = locatorService.getComponentInstances(searchFilter);
if(bpmSoaComponents == null || bpmSoaComponents.isEmpty()){
throw new Exception("Bpm process " + processID + " was not found");
}

/**
* Step 2 - Find all BPM components (BPM Processes) under the same execution context as visually presented in the process audit trail.
*
* Using the SOA Infrastructure API we can find all BPM Components under the same execution context.
* This requires the execution  context id (ECID) which in this case will be retrived from the BPM component
* fetched in the previous step. There are other possibilities like a Human Task
* instance or a Composite instance (SOA Components).
*
*/
String ecid = bpmSoaComponents.get(0).getECID();

//BPM Component Instance Filter
searchFilter = new ComponentInstanceFilter();
searchFilter.setECID(ecid);
searchFilter.setEngineType(Locator.SE_BPMN); //only BPM processes
searchFilter.setStates(new int[]{ComponentInstance.STATE_FAULTED,
ComponentInstance.STATE_RECOVERY_REQUIRED,
ComponentInstance.STATE_RUNNING});
searchFilter.setOrderBy(ComponentInstanceFilter.ORDER_BY_CREATION_DATE_DESC);

//Get the BPM components that can be cancelled (states above)
bpmSoaComponents = locatorService.getComponentInstances(searchFilter);

/**
* Step 3 - Cancel the BPM processes using the BPM API
*
* BPM API Javadoc: http://docs.oracle.com/cd/E23943_01/apirefs.1111/e25378/toc.htm)
*/
if(bpmSoaComponents != null && !bpmSoaComponents.isEmpty()){
//Set up the BPM API connection properties
Map<IWorkflowServiceClientConstants.CONNECTION_PROPERTY, String> properties = new HashMap<IWorkflowServiceClientConstants.CONNECTION_PROPERTY, String>();
properties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.CLIENT_TYPE, IWorkflowServiceClientConstants.CLIENT_TYPE_REMOTE);
properties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.EJB_PROVIDER_URL, "t3://" + hostname + ":" + port);
properties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.EJB_SECURITY_PRINCIPAL, username);
properties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.EJB_SECURITY_CREDENTIALS, password);

//Aquire the service factory
BPMServiceClientFactory bpmSvcCliFactory = BPMServiceClientFactory.getInstance(properties, null, null);
if (bpmSvcCliFactory == null) {
throw new Exception("Bpm services unavailable.");
}

//Acquire the service client
IBPMServiceClient bpmSvcCli = bpmSvcCliFactory.getBPMServiceClient();

//Get the user BPM Context for the BPM API requests
IBPMContext userBpmContext = bpmSvcCliFactory.getBPMUserAuthenticationService().getBPMContextForAuthenticatedUser();

//Get the InstanceManagementService used to managed BPM process instances
IInstanceManagementService bpmInstanceManagementSvc = bpmSvcCli.getInstanceManagementService();

for(ComponentInstance bpmComponent : bpmSoaComponents){
//Get the BPM Process ID from the BPM component
int indexOfSeparator = bpmComponent.getId().indexOf(":"); //index of ':' => "bpmn:12345678"
processID = bpmComponent.getId().substring(indexOfSeparator + 1);

//Fetch the BPM Process Instance to cancel
IProcessInstance processInstance = bpmSvcCli.getInstanceQueryService().getProcessInstance(userBpmContext, processID);

//Cancel the instance
bpmInstanceManagementSvc.cancelProcessInstance(userBpmContext, processInstance);

System.out.println("BPM process " + processID + " was cancelled successfully");
}
}else{
System.out.println("No processes to cancel");
}

}

public static void main(String args[]){
String hostname = "";
String port = "";

//ser with admin privileges
String username = "";
String password = "";

String processID = "";

try{
CancelBpmProcess.cancelProcess(hostname, port, username, password, processID);
}catch(Exception e){
e.printStackTrace();
}
}
}

 

You can also find the project here. It uses libraries from Middleware 11.1.1.6 but also works the ones from 11.1.1.4 or 11.1.1.5

Best Regards

Advertisements

3 Comments

Leave a Comment
  1. Pushpenrda / Jun 20 2012 9:36 pm

    If I have any doubt where I can ask/post it.

    • danielsoaresmartins / Jun 21 2012 10:23 am

      Just comment the post

      • noob / Jan 19 2014 7:29 am

        Hi, i tried the above example but faced concurrentmodificationexception while traversing the list. am i missing anything?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: