Thanks to my colleague Cosmin for the pointer.
New features HERE
Wednesday, July 31, 2013
Tuesday, July 30, 2013
#266 BPM Parallel Multi Instance sub processes
Very simple scenario here -
An order with lines is processed. The OrderProcess accepts in an order with its attendant lines. The Fulfillment process is called for each order line. We do not have many order lines, and the processing is simple, so we run this in parallel.
Let's look at the definition of the Multi Instance sub-process -
The Send and Receive Activities will require a Conversation to do the correlation between the 2 processes. This needs to be defined at Sub-process level and NOT AT PROCESS LEVEL. I made this mistake once too often!
Send Activity Definition -
Receive Activity Definition -
Full lab doc HERE
An order with lines is processed. The OrderProcess accepts in an order with its attendant lines. The Fulfillment process is called for each order line. We do not have many order lines, and the processing is simple, so we run this in parallel.
Let's look at the definition of the Multi Instance sub-process -
The Send and Receive Activities will require a Conversation to do the correlation between the 2 processes. This needs to be defined at Sub-process level and NOT AT PROCESS LEVEL. I made this mistake once too often!
Send Activity Definition -
Receive Activity Definition -
Full lab doc HERE
Thursday, July 25, 2013
Friday, July 19, 2013
#264 - BPM 11g PS6 Web Forms not displaying in Process Composer
Web Forms is a great addition to Oracle BPM, however one may hit an issue when testing these in process composer.
Here is a simple example of such a form -
One can then click on the "running man" icon to test the form.
Looks good - if yours doesn't render then check/set the following -
Make sure you set the above to your fully qualified machine name.
make sure this is in your etc/hosts.
Also check the listen address / front end host setting for your WLS server via the WLS console.
This should also be set to your fully qualified machine name
Use your fully qualified machine name when starting process composer in your browser.
e.g. http://mymachine.niall.com:7001/bpm/composer
Here is a simple example of such a form -
One can then click on the "running man" icon to test the form.
Looks good - if yours doesn't render then check/set the following -
Make sure you set the above to your fully qualified machine name.
make sure this is in your etc/hosts.
Also check the listen address / front end host setting for your WLS server via the WLS console.
This should also be set to your fully qualified machine name
Use your fully qualified machine name when starting process composer in your browser.
e.g. http://mymachine.niall.com:7001/bpm/composer
Tuesday, July 16, 2013
Wednesday, July 10, 2013
#262 BPM PS6 partner workshops...
*** For EMEA Oracle BPM Partners ***
please see the post from Juergen Kress here
please see the post from Juergen Kress here
Thursday, July 4, 2013
#261 Short Digression on the Human Task API
Scenario:
I need to update the payload of an order via the API.
My order is very simple -
The User task is called Approve.
All I want to do is add my margin to the price ( * 1.5).
I also append " on special offer " to the product name
Here is the payload before -
after -
Here is the code -
package hwjavaclient;
import java.util.ArrayList;
import java.util.HashMap;
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.task.ITaskService;
import oracle.bpel.services.workflow.task.model.Task;
import oracle.bpel.services.workflow.verification.IWorkflowContext;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class HwTask {
public HwTask() {
super();
}
public String getTaskdetails(String user) {
Map properties = new HashMap();
properties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.EJB_PROVIDER_URL,
"t3://localhost:7001");
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("weblogic", "welcome1".toCharArray(),
null);
System.out.println("CTX " + ctx.getIdentityContext());
//Set up list of columns to query
List queryColumns = new ArrayList();
queryColumns.add("TASKID");
queryColumns.add("TASKNUMBER");
queryColumns.add("TITLE");
queryColumns.add("OUTCOME");
// also get the payload
List optionalInfo = new ArrayList();
optionalInfo.add(ITaskQueryService.OptionalInfo.PAYLOAD);
//
//Query a list of all tasks
List tasks =
querySvc.queryTasks(ctx, queryColumns, optionalInfo, // Payload
ITaskQueryService.AssignmentFilter.ALL, 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, and approving any
//tasks whose outcome has not been set...
System.out.println("*** Nr of tasks " + tasks.size());
for (int i = 0; i < tasks.size(); i++) {
Task task = (Task)tasks.get(i);
int taskNumber = task.getSystemAttributes().getTaskNumber();
String title = task.getTitle();
String outcome = task.getSystemAttributes().getOutcome();
System.out.println("Task #" + taskNumber + " (" + title +
") has the outcome set to " + outcome);
// Extract and update the payload for the approve order task
if (title.equalsIgnoreCase("Approve")) {
// Get TaskDetailsByNumber so as to be able to update the payload
Task task2Update =
querySvc.getTaskDetailsByNumber(ctx, taskNumber);
System.out.println("Getting the Payload...");
Element el = task2Update.getPayloadAsElement();
Element newEl = getPayloadValues(el);
task2Update.setPayloadAsElement(newEl);
taskSvc.updateTask(ctx, task2Update);
}
}
} catch (Exception e) {
//Handle any exceptions raised here...
System.out.println("Caught workflow exception: " + e.getMessage());
}
return "done";
}
public static Element getPayloadValues(Element pElement) {
System.out.println("getPayloadValues() for Payload of type " +
pElement.getFirstChild().getNodeName());
NodeList nl = pElement.getChildNodes();
Node parentNode = nl.item(0);
NodeList nlChildren = parentNode.getChildNodes();
for (int i = 0; i < nlChildren.getLength(); i++) {
Node n = nlChildren.item(i);
String NodeName = n.getNodeName();
if (!NodeName.equalsIgnoreCase("#text")) {
Element myElement = (Element)nlChildren.item(i);
NodeList nlElement = myElement.getChildNodes();
String elName = n.getNodeName();
String elValue = nlElement.item(0).getNodeValue();
System.out.println("Element is " + elName +
" with a value of " + elValue);
if (elName.equalsIgnoreCase("ns2:product")) {
System.out.println("Updating product name to add special offer tag...");
nlElement.item(0).setNodeValue(elValue +
" on special offer");
}
if (elName.equalsIgnoreCase("ns2:price")) {
System.out.println("Updating price to add a decent margin...");
Double price = new Double(elValue);
price = price * 1.5;
String newPrice = price.toString();
nlElement.item(0).setNodeValue(newPrice);
}
}
}
return pElement;
}
}
I need to update the payload of an order via the API.
My order is very simple -
The User task is called Approve.
All I want to do is add my margin to the price ( * 1.5).
I also append " on special offer " to the product name
Here is the payload before -
after -
Here is the code -
package hwjavaclient;
import java.util.ArrayList;
import java.util.HashMap;
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.task.ITaskService;
import oracle.bpel.services.workflow.task.model.Task;
import oracle.bpel.services.workflow.verification.IWorkflowContext;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class HwTask {
public HwTask() {
super();
}
public String getTaskdetails(String user) {
Map properties = new HashMap();
properties.put(IWorkflowServiceClientConstants.CONNECTION_PROPERTY.EJB_PROVIDER_URL,
"t3://localhost:7001");
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("weblogic", "welcome1".toCharArray(),
null);
System.out.println("CTX " + ctx.getIdentityContext());
//Set up list of columns to query
List queryColumns = new ArrayList();
queryColumns.add("TASKID");
queryColumns.add("TASKNUMBER");
queryColumns.add("TITLE");
queryColumns.add("OUTCOME");
// also get the payload
List optionalInfo = new ArrayList();
optionalInfo.add(ITaskQueryService.OptionalInfo.PAYLOAD);
//
//Query a list of all tasks
List tasks =
querySvc.queryTasks(ctx, queryColumns, optionalInfo, // Payload
ITaskQueryService.AssignmentFilter.ALL, 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, and approving any
//tasks whose outcome has not been set...
System.out.println("*** Nr of tasks " + tasks.size());
for (int i = 0; i < tasks.size(); i++) {
Task task = (Task)tasks.get(i);
int taskNumber = task.getSystemAttributes().getTaskNumber();
String title = task.getTitle();
String outcome = task.getSystemAttributes().getOutcome();
System.out.println("Task #" + taskNumber + " (" + title +
") has the outcome set to " + outcome);
// Extract and update the payload for the approve order task
if (title.equalsIgnoreCase("Approve")) {
// Get TaskDetailsByNumber so as to be able to update the payload
Task task2Update =
querySvc.getTaskDetailsByNumber(ctx, taskNumber);
System.out.println("Getting the Payload...");
Element el = task2Update.getPayloadAsElement();
Element newEl = getPayloadValues(el);
task2Update.setPayloadAsElement(newEl);
taskSvc.updateTask(ctx, task2Update);
}
}
} catch (Exception e) {
//Handle any exceptions raised here...
System.out.println("Caught workflow exception: " + e.getMessage());
}
return "done";
}
public static Element getPayloadValues(Element pElement) {
System.out.println("getPayloadValues() for Payload of type " +
pElement.getFirstChild().getNodeName());
NodeList nl = pElement.getChildNodes();
Node parentNode = nl.item(0);
NodeList nlChildren = parentNode.getChildNodes();
for (int i = 0; i < nlChildren.getLength(); i++) {
Node n = nlChildren.item(i);
String NodeName = n.getNodeName();
if (!NodeName.equalsIgnoreCase("#text")) {
Element myElement = (Element)nlChildren.item(i);
NodeList nlElement = myElement.getChildNodes();
String elName = n.getNodeName();
String elValue = nlElement.item(0).getNodeValue();
System.out.println("Element is " + elName +
" with a value of " + elValue);
if (elName.equalsIgnoreCase("ns2:product")) {
System.out.println("Updating product name to add special offer tag...");
nlElement.item(0).setNodeValue(elValue +
" on special offer");
}
if (elName.equalsIgnoreCase("ns2:price")) {
System.out.println("Updating price to add a decent margin...");
Double price = new Double(elValue);
price = price * 1.5;
String newPrice = price.toString();
nlElement.item(0).setNodeValue(newPrice);
}
}
}
return pElement;
}
}
Tuesday, July 2, 2013
#260 BPM 11g PS6 Case Management continued...
Here I will describe how to create the artifacts from the design created in the previous post.
The in-depth Oracle docs are available here
In JDeveloper - create a new Application/Project of type BPM Application.
Then add a Composite With Case Management
This is what the generated composite looks like -
Let's look at the web service interface and the operations offered -
These operations are also available via the Case Management Java API.
To the right we have an Oracle Business Rules component. This will be used for defining out Policy Rules e.g. which activities are available in which phase etc.So essentially it is state driven - the rules engine deciding what should happen (or be available) when as our case progresses.
Here is the Case Component itself -
The following information can be entered here -
-Title
-Category
-Milestones or Phases
- Outcomes
I have added 6 XSDs to the project -
- TaxBill - Bill sent to the taxpayer if she has paid too little tax.
- TaxInvestigation - Investigation of tax return for possible fraud etc.
- TaxPayer - Base data describing the tax payer
- TaxRebate - Rebate sent to the taxpayer if she has overpaid
- TaxReturn - end of year return made by the taxpayer
- DocumentsRequest- request for docs sent to taxpayer. Maybe requiring original receipts etc.
I add these to the Business Catalog -
Now to the Data -
The types defined above can now be added via the Case Management Data Tab -
Now to the User Events -
I have only added one event - Docs Provided Event i.e. raised when the tax payer provides missing documentation such as receipts.
Note the checkbox - Publish Case Events - when checked, this will cause case and user events to be published via EDN. For example, the case closed event could trigger a message that is picked up by some other process.
Case events encompass -
- Lifecycle Events
- Activity Events
- Document Events
- Data Events
- Milestone (Phase) Events
and, of course, User Events.
Now to the Stakeholders -
You can define multiple stakeholders for each case you define. Only stakeholders can perform actions on case objects that are part of a case. Ergo Stakeholders = Case Workers.
For this demo, I assign jcooper as Tax Form Checker and jstein as Tax Investigator
Permissions can also be defined on this tab -
The Oracle docs state "The administrator decides which actions each stakeholder can perform. By default, during deployment Oracle BPM grants stakeholders all the available permissions. After deployment the administrator can remove non-relevant permissions."
In our case, we could apply the "Restricted" permission to the "SendRebateActivity" and "SendBillActivity".
Now to Translation -
This allows me to specify German values for the Name strings - here I have added a couple of entries.
Now to the Activities -
As you see, there is no tab for activities in the Case component.
Activities can currently be -
- BPM processes
- Human Tasks
- Custom
2 custom activities are included OOTB -
- Notification
- Simple Human Task
Activities can be conditional, repeatable, manual or automatic.
Here again is the mind map for Activities -
Conduct Initial Assessment will be implemented as a BPM process.
Input/Output is TaxReturn
I create the process and then promote it as a Case Activity.
The Case Activity dialog appears
I make it Required.
Also, note how we can set permissions here.
I do the same for the other activities and essentially then I'm finished.
More later...
The in-depth Oracle docs are available here
In JDeveloper - create a new Application/Project of type BPM Application.
Then add a Composite With Case Management
This is what the generated composite looks like -
Let's look at the web service interface and the operations offered -
These operations are also available via the Case Management Java API.
To the right we have an Oracle Business Rules component. This will be used for defining out Policy Rules e.g. which activities are available in which phase etc.So essentially it is state driven - the rules engine deciding what should happen (or be available) when as our case progresses.
Here is the Case Component itself -
The following information can be entered here -
-Title
-Category
-Milestones or Phases
- Outcomes
I have added 6 XSDs to the project -
- TaxBill - Bill sent to the taxpayer if she has paid too little tax.
- TaxInvestigation - Investigation of tax return for possible fraud etc.
- TaxPayer - Base data describing the tax payer
- TaxRebate - Rebate sent to the taxpayer if she has overpaid
- TaxReturn - end of year return made by the taxpayer
- DocumentsRequest- request for docs sent to taxpayer. Maybe requiring original receipts etc.
I add these to the Business Catalog -
Now to the Data -
The types defined above can now be added via the Case Management Data Tab -
Now to the User Events -
I have only added one event - Docs Provided Event i.e. raised when the tax payer provides missing documentation such as receipts.
Note the checkbox - Publish Case Events - when checked, this will cause case and user events to be published via EDN. For example, the case closed event could trigger a message that is picked up by some other process.
Case events encompass -
- Lifecycle Events
- Activity Events
- Document Events
- Data Events
- Milestone (Phase) Events
and, of course, User Events.
Now to the Stakeholders -
You can define multiple stakeholders for each case you define. Only stakeholders can perform actions on case objects that are part of a case. Ergo Stakeholders = Case Workers.
For this demo, I assign jcooper as Tax Form Checker and jstein as Tax Investigator
Permissions can also be defined on this tab -
The Oracle docs state "The administrator decides which actions each stakeholder can perform. By default, during deployment Oracle BPM grants stakeholders all the available permissions. After deployment the administrator can remove non-relevant permissions."
In our case, we could apply the "Restricted" permission to the "SendRebateActivity" and "SendBillActivity".
Now to Translation -
This allows me to specify German values for the Name strings - here I have added a couple of entries.
Now to the Activities -
As you see, there is no tab for activities in the Case component.
Activities can currently be -
- BPM processes
- Human Tasks
- Custom
2 custom activities are included OOTB -
- Notification
- Simple Human Task
Activities can be conditional, repeatable, manual or automatic.
Here again is the mind map for Activities -
Conduct Initial Assessment will be implemented as a BPM process.
Input/Output is TaxReturn
I create the process and then promote it as a Case Activity.
I make it Required.
Also, note how we can set permissions here.
I do the same for the other activities and essentially then I'm finished.
More later...
Monday, July 1, 2013
#259 BPM 11g PS6 Case Management - getting started
An excellent approach suggested by my colleague Prasen P. is to use a mind map when defining a case.
It fits in well with the more holistic approach required when designing such - "holistic", in comparison to the more "process oriented" approach used with standard BPM.
I will not be providing background information on Oracle's Adaptive Case Management here, as this is already available. Suffice to say, it is built on existing components within the Oracle BPM Suite - so we are not introducing more complexity here - more a case of "doing more and better with the same".
For those new to Adaptive Case Management in Oracle BPM 11g, I suggest you read Mark Foster's articles on the A-Team blog. He has written 3 excellent pieces on the above - they are available here
Another useful intro is provided by Leon Smiers - check it out here.
Anyway, back to the mind map approach - Here is a one containing the main components within Oracle's Adaptive Case Management. Remember Adaptive Case Management is only available with BPM Suite 11g PS6.
So let's go thru each of these components, explaining their raison d'ĂȘtre -
Data - data associated with the case, for example, in an income tax case, it could be your tax return, tax rebate etc.
Milestones/Phases - Milestones in Case Management should be interpreted as phases in the progression of the case. e.g. in our income tax case we may consider 3 phases - Initial Assessment of tax return, Investigation of tax return, Resolution of the tax return etc.
Outcomes - possible outcome status of the case e.g. Rebate Paid, Bill Sent for outstanding tax etc.
Events - Here we define user and case events. This could include manual actions that can occur during the lifetime of a case which trigger events inside the case. For example, the arrival of a fax including supporting documentation for a tax return could trigger a "Validate Document" event.
Stakeholders - Here we are referring primarily to the Case Workers. However, we could also include "external" parties such as the tax payers - depending on their involvement in the case.
Activities - specific Case work/tasks e.g. Conduct Initial Assessment of Tax Return, Investigate Tax Return,
Validate Document, Generate Tax Rebate etc. We can also specify whether the activity is conditional or unconditional, i.e. whether it is always executed or not.
Policies - We can consider policies for - Phase Changes and Activity Use e.g.
-- Phase Change Policies for Investigation of Tax Return Started --> "Valid Tax Return"
-- Activity Use Policy- here we can specify which activities should be available in which phase. e.g. the Generate Tax Rebate activity should not be available in the Initial Assessment phase, but only in the Resolution phase.
Documents - supplementary documents pertaining to the case, e.g. receipts etc. These will be stored per default in UCM.
Initial mind map for the simplified Tax use case -
Here are the detailed nodes -
It fits in well with the more holistic approach required when designing such - "holistic", in comparison to the more "process oriented" approach used with standard BPM.
I will not be providing background information on Oracle's Adaptive Case Management here, as this is already available. Suffice to say, it is built on existing components within the Oracle BPM Suite - so we are not introducing more complexity here - more a case of "doing more and better with the same".
For those new to Adaptive Case Management in Oracle BPM 11g, I suggest you read Mark Foster's articles on the A-Team blog. He has written 3 excellent pieces on the above - they are available here
Another useful intro is provided by Leon Smiers - check it out here.
Anyway, back to the mind map approach - Here is a one containing the main components within Oracle's Adaptive Case Management. Remember Adaptive Case Management is only available with BPM Suite 11g PS6.
So let's go thru each of these components, explaining their raison d'ĂȘtre -
Data - data associated with the case, for example, in an income tax case, it could be your tax return, tax rebate etc.
Milestones/Phases - Milestones in Case Management should be interpreted as phases in the progression of the case. e.g. in our income tax case we may consider 3 phases - Initial Assessment of tax return, Investigation of tax return, Resolution of the tax return etc.
Outcomes - possible outcome status of the case e.g. Rebate Paid, Bill Sent for outstanding tax etc.
Events - Here we define user and case events. This could include manual actions that can occur during the lifetime of a case which trigger events inside the case. For example, the arrival of a fax including supporting documentation for a tax return could trigger a "Validate Document" event.
Stakeholders - Here we are referring primarily to the Case Workers. However, we could also include "external" parties such as the tax payers - depending on their involvement in the case.
Activities - specific Case work/tasks e.g. Conduct Initial Assessment of Tax Return, Investigate Tax Return,
Validate Document, Generate Tax Rebate etc. We can also specify whether the activity is conditional or unconditional, i.e. whether it is always executed or not.
Policies - We can consider policies for - Phase Changes and Activity Use e.g.
-- Phase Change Policies for Investigation of Tax Return Started --> "Valid Tax Return"
-- Activity Use Policy- here we can specify which activities should be available in which phase. e.g. the Generate Tax Rebate activity should not be available in the Initial Assessment phase, but only in the Resolution phase.
Documents - supplementary documents pertaining to the case, e.g. receipts etc. These will be stored per default in UCM.
Initial mind map for the simplified Tax use case -
Here are the detailed nodes -
Policies/ Phase Change Policies
Policies/Activity Use Policies