Monday, January 10, 2011

Canceling a running composite instance - example

Firstly I wish all of you - Health, Wealth and Happiness for 2011 and beyond!

Now it's back to work...

Scenario
File Adapter(read) --> Mediator --> BPEL --> human workflow --> DB
Adapter(write).

Step 1 - create the composite
- I started with a simple Mediator, to begin with.




- Here is the XSD I used



- As you can see, I created a composite sensor on the OrderNr.



Ok, let’s add the BPEL & Human Workflow components to the composite



- Define the Human Workflow ( I simply assign the approval task to jcooper)
- Autogenerate task form etc.


Deploy and Test
- Here is my test input XML.




- Login to sqlplus as dev_soainfra
- execute the following
-- select substr(composite_instance_id,1,15),
substr( component_instance_id,1,20),
substr( component_name, 1,20),
substr(sensor_name,1,20),
substr( string_value,1,20)
from composite_sensor_value
/



- So the composite instance id = 180001

- I can now use this value to execute the following query
-- select substr(composite_dn,1,25), state, live_instances from composite_instance where id = 180001
/



- The STATE = 0 which indicates that the instances is open and running.
- Other state values are -->



- We can now access the cube_instance table to get the details of the running bpel instance –

-- Select cikey, state from cube_instance where cmpst_id = 180001;



- State = 1 means bpel instance is open and running –
- Other state values are -->



- Now I check the Human Workflow tables
-- select
substr( title, 1,20),
tasknumber,
taskid,
substr(state,1,10),
substr(assignees,1,20)
from wftask
where compositeinstanceid = 180001;



-- The taskid = 44b2adae-c347-48c4-b5d9-0b76ba722c1d
-- The task number = 200180

Step 2 - Leveraging the Java API to find a particular human task

- To begin with, let's get all the tasks for jcooper -
-- Method getAllTasks()



The task 200180 is the last one in the list.

- Then I look for a specific task - getSpecificTask()



-------------------------------------------------------------------

package processmyorderapi;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;

import java.util.Map;

import oracle.bpel.services.workflow.client.IWorkflowServiceClient;
import oracle.bpel.services.workflow.client.IWorkflowServiceClientConstants;
import oracle.bpel.services.workflow.client.WorkflowServiceClientFactory;
import oracle.bpel.services.workflow.query.ITaskQueryService;

import oracle.bpel.services.workflow.repos.TableConstants;
import oracle.bpel.services.workflow.task.ITaskService;
import oracle.bpel.services.workflow.task.model.Task;
import oracle.bpel.services.workflow.verification.IWorkflowContext;

import oracle.bpel.services.workflow.repos.Predicate;

public class HwTask {

public HwTask() {
super();
}

public String getAllTasks(String user){

Map properties = new HashMap();
properties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.EJB_PROVIDER_URL, "t3://localhost:8001");
properties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.EJB_SECURITY_CREDENTIALS, "welcome1");
properties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.EJB_SECURITY_PRINCIPAL, "weblogic");

try
{
//Create JAVA WorkflowServiceClient
IWorkflowServiceClient wfSvcClient =
WorkflowServiceClientFactory.getWorkflowServiceClient(WorkflowServiceClientFactory.REMOTE_CLIENT, properties, null);

//Get the task query service
ITaskQueryService querySvc = wfSvcClient.getTaskQueryService();
//Login as jcooper
IWorkflowContext ctx = querySvc.authenticate("jcooper","welcome1".toCharArray(),null);
//Set up list of columns to query
List queryColumns = new ArrayList();
queryColumns.add("TASKID");
queryColumns.add("TASKNUMBER");
queryColumns.add("TITLE");
queryColumns.add("OUTCOME");
//Query a list of tasks assigned to jcooper
List tasks = querySvc.queryTasks(ctx,
queryColumns,
null, //Do not query additional info
ITaskQueryService.AssignmentFilter.MY,
null, //No keywords
null, //No custom predicate
null, //No special ordering
0, //Do not page the query result
0);

//Get the task service
ITaskService taskSvc = wfSvcClient.getTaskService();
//Loop over the tasks, outputting task information,

for(int i = 0 ; i < tasks.size() ; i ++)
{

Task task = (Task)tasks.get(i);
int taskNumber = task.getSystemAttributes().getTaskNumber();
String title = task.getTitle();
String taskId = task.getSystemAttributes().getTaskId();
String outcome = task.getSystemAttributes().getOutcome();
/* now we could auto-approve tasks, if required!
/* if(outcome == null)
{
outcome = "APPROVED";
taskSvc.updateTaskOutcome(ctx,taskId,outcome);
}*/

System.out.println("Task ID#"+ taskId + "Task Nr#" + taskNumber+" ("+title+") is "+outcome);
}
}
catch (Exception e)
{
//Handle any exceptions raised here...
System.out.println("Caught workflow exception: "+e.getMessage());
}

return "done";
}

public String getSpecificTask(String taskid){
System.out.println("*** getSpecificTask() looking for taskId " + taskid);
Map properties = new HashMap();
properties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.EJB_PROVIDER_URL, "t3://localhost:8001");
properties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.EJB_SECURITY_CREDENTIALS, "welcome1");
properties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.EJB_SECURITY_PRINCIPAL, "weblogic");

try
{
//Create JAVA WorflowServiceClient
IWorkflowServiceClient wfSvcClient =
WorkflowServiceClientFactory.getWorkflowServiceClient(WorkflowServiceClientFactory.REMOTE_CLIENT, properties, null);

//Get the task query service
ITaskQueryService querySvc = wfSvcClient.getTaskQueryService();
//Login as jcooper
IWorkflowContext ctx = querySvc.authenticate("jcooper","welcome1".toCharArray(),null);
//Set up list of columns to query
List queryColumns = new ArrayList();
queryColumns.add("TASKID");
queryColumns.add("TASKNUMBER");
queryColumns.add("TITLE");
queryColumns.add("OUTCOME");

// add predicate for particular taskid

Predicate predicate = new Predicate(TableConstants.WFTASK_TASKID_COLUMN,
Predicate.OP_EQ,
taskid);
System.out.println("*** getSpecificTask() Predicate added for taskId " + taskid);

//Query a list of tasks assigned to jcooper
List tasklist = querySvc.queryTasks(ctx,
queryColumns,
null, //Do not query additional info
ITaskQueryService.AssignmentFilter.MY,
null, //No keywords
predicate, //add custom predicate
null, //No special ordering
0, //Do not page the query result
0);

if (tasklist != null) { // There are tasks
System.out.println("Total number of tasks: " + tasklist.size());
System.out.println("Tasks List: ");
Task task = null;
for (int i = 0; i < tasklist.size(); i++) {
task = (Task) tasklist.get(i);
System.out.println("Task Number: " + task.getSystemAttributes().getTaskNumber());
System.out.println("Task Id: " + task.getSystemAttributes().getTaskId());
System.out.println("Title: " + task.getTitle());
System.out.println("Priority: " + task.getPriority());
System.out.println("State: " + task.getSystemAttributes().getState());
System.out.println();
// Retrive any Optional Info specified
// Use task service, to perform operations on the task
}
}
}
catch (Exception e)
{
//Handle any exceptions raised here...
System.out.println("Caught workflow exception: "+e.getMessage());
}

return "done";
}


}

------------------

Step 2 - Leveraging the Java API to find and purge composite instances

- see method - findComposite()
-- here we call locator.purgeInstance() to purge the instance
--------------------------------------------

package compositeapi;

import java.util.Hashtable;
import java.util.List;
import javax.naming.Context;

import oracle.soa.management.facade.ComponentInstance;
import oracle.soa.management.facade.Composite;
import oracle.soa.management.facade.CompositeInstance;
import oracle.soa.management.facade.Locator;
import oracle.soa.management.facade.LocatorFactory;
import oracle.soa.management.facade.ServiceEngine;
import oracle.soa.management.facade.bpel.BPELServiceEngine;
import oracle.soa.management.util.ComponentInstanceFilter;
import oracle.soa.management.util.CompositeInstanceFilter;


public class CompositeAPI {

private Locator locator = null;

public CompositeAPI() {
super();
}

public void findComposite(){

java.util.Hashtable props = new java.util.Hashtable();
props.put(javax.naming.Context.PROVIDER_URL, "t3://localhost:8001/soa-infra");
props.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
props.put(javax.naming.Context.SECURITY_PRINCIPAL, "weblogic");
props.put(javax.naming.Context.SECURITY_CREDENTIALS, "welcome1");
props.put("dedicated.connection", "true");

try{
locator = LocatorFactory.createLocator(props);
CompositeInstanceFilter coif = new CompositeInstanceFilter();
coif.setId("180001");
List list = locator.getCompositeInstances(coif);
System.out.println("Nr. of Composites found = " + list.size());

for(int i = 0 ; i < list.size() ; i ++){
CompositeInstance coi = (CompositeInstance)list.get(i);
System.out.println("Composite Instance Domain Name = " +coi.getCompositeDN());
System.out.println("Composite Instance State = " +coi.getState());
System.out.println("Composite Instance Status = " +coi.getStatus());

locator.purgeInstance(coif);

}


// Component Instance Filter usage

ComponentInstanceFilter cif = new ComponentInstanceFilter();
cif.setCompositeInstanceId("180001");
List l = locator.getComponentInstances(cif);

System.out.println("Instance found = " + l.size());

for(int i = 0 ; i < l.size() ; i ++){
ComponentInstance ci = (ComponentInstance)l.get(i);
System.out.println("Component Instance ID = " +ci.getCompositeInstanceId());
ServiceEngine se = ci.getServiceEngine();
System.out.println("*** Engine Type " + se.getEngineType());
System.out.println("DN = " + ci.getCompositeDN());
}

String compositeDN = "default/ProcessMyOrder!1.0";
Composite composite = locator.lookupComposite(compositeDN);
System.out.println("*** got composite "+ composite.toString());

// Purge

}
catch(Exception e){
e.printStackTrace();
}

}
}

-------------------------------------------------------------------------------

Step 3 - Check the DB

I run the selects again -

1 comment:

Harry Dinh said...

Hi,

Thank you for your extremely helpful post. I can purge the composite instance quite easily. However, I have a scenario that I hope it is achievable.

In case that I have a main process, which will in turn references a number of sub-process and human task. I do not want to kill the main process, because I still need it to return something. But I need to kill all sub-processes and human tasks. From CompositeInstance, I can get the list of componentInstances belong to this compositeInstances. For Human Task, I can use ITaskService to kill it, with the workflowId References in the componentInstance. But with sub-processes, I cannot find the sub-processes instance to kill it. I wonder if my approach is correct, or we have another better solution for it?

Thank you so much.

Best regards,

Harry