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 -
Monday, January 10, 2011
Subscribe to:
Post Comments (Atom)
1 comment:
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
Post a Comment