As discusses in part 1, the Workflow Patterns Initiative (WPI) was established with the aim of delineating the fundamental requirements that arise during business process modeling on a recurring basis and describe them in an imperative way. It is widely used or referenced when enterprises want to model their workflow. In the first WPI version, 20 patterns were delivered in 2003. The number increased to 43 in the latest release. Those patterns post a big challenge to all kinds of BPEL engines. It is very difficult to support all of them. In another word, one BPEL engine which can support those patterns well should gain more customers as its power.
In part 2 of this article, we will introduce 2 categories patterns (Multiple Instance Patterns and Iteration Patterns) in detail.
Advanced branching and synchronization patterns
There are 9 patterns in this category, including:
- Multiple Instances without Synchronization,
- Multiple Instances with a Priori Design-Time Knowledge,
- Multiple Instances with a Priori Run-Time Knowledge,
- Multiple Instances without a Priori Run-Time Knowledge,
- Static Partial Join for Multiple Instances,
- Cancelling Partial Join for Multiple Instances,
- Dynamic Partial Join for Multiple Instances,
- Arbitrary Cycles,
- Structured Loop
These patterns are related with branching and merging concept and widely used in real business process. Some of them can be implemented in WID 7 BPC editor easily, and some involve WID 7 SCA assembly structures.
Multiple instances without synchronization
Multiple instances of a task are created in a given process instance. And there is no need to synchronize them upon completion.
For example, suppose we have a task named approveVacationRequest. Multiple instances can be created and handled in the same time. No Synchronization is needed.
Analysis
The focus of this pattern is:
- Multiple instances of a task can be created independently.
- No need to synchronize upon completion.
- Each of them must execute independently
Implementation
Figure 1. Multiple Instances without Synchronization
This pattern is Supported by <invoke> statement within <foreach>.
Listing 1. The operation1 in MultiInstancesInvokeeImpl
addCounter();
System.out.println("[MultiInstancesInvokee] invoked time is: " + counter);
input1.setInt("field3", counter );
return input1;
|
Test Data
field2=2; Expected result: the SCA component will be invoked twice.
Multiple instances with a priori design-time knowledge
This pattern requires multiple instances which are created within a given process instance to be synchronized upon their completion. And the number of the instances can be known at the design time.
For example, the test plan should be approved by the test lead, component developer, the architect and the peer tester.
Analysis
The focus of this pattern is:
- Multiple instances are created.
- The required number is known at design time.
- Synchronization is required at completion.
Implementation
Figure 2. Multiple Instances with a Priori Design-Time Knowledge
In the scope, we initialize a variable named dataCollection for collecting the
data in setTheResultintoDataCollection activity. We use ForEach activity to
invoke other activity in parallel.
The next two listings below provide a snippet of the InitDataCollection and setTheResultintoDataCollection activity.
Listing 2. InitDataCollection
commonj.sdo.DataObject __result__1;
{// create DataCollection
com.ibm.websphere.bo.BOFactory factory =
(com.ibm.websphere.bo.BOFactory) new com.ibm.websphere.sca.ServiceManager().
locateService("com/ibm/websphere/bo/BOFactory");
__result__1 = factory.create("http://PatternsDemo","DataCollection");
}
dataCollection = __result__1;
|
Listing 3. setTheResultintoDataCollection
List list = dataCollection.getList("ProcessDataArray");
list.add(output1);
|
Test Data
field2=2; Expected result: the SCA component will be invoked twice, and the invoke response data are collected in an Array.
Multiple instances with a priori run-time knowledge
This pattern requires multiple instances which are created within a given process instance to be synchronized upon their completion. And the number of the instances can be affected by some run time factors.
For example, the test plan should be approved by the required reviewers. The number of reviewers is different case by case.
Analysis
The focus of this pattern is:
- Multiple instances are created.
- The required number is affected by some runtime factor.
- Synchronization is required at completion.
Implementation
Figure 3. Multiple Instances with a Priori Run-Time Knowledge
The implementation is familiar with Multiple Instances with a Priori Design-Time Knowledge except that we have a humantask named ManualSetIndex through which we can set the
value to output1/field2 and in AssignIndex activity we transfer this value to a variable named indexnumber.
Test Data
- Input any value to start the process,
- Next go to My to-dos, and claim the ManualSetIndex task ,and provide the field2=2,
- Expected result: the SCA component will be invoked twice, and the invoke response data are collected in an Array.
Multiple instances without a priori run-time knowledge
This pattern requires multiple instances which are created within a given process instance to be synchronized upon their completion. And the number of the instances can be affected by some run time factors. More important, more instances can be added at run time.
For example, usually approving a team outing plan will only request half of the team members. However in some special case, more members will be involved to approve the case.
Analysis
The focus of this pattern is:
- Multiple instances are created.
- The required number is affected by some runtime factor.
- More instances can be added at run time
- Synchronization is required at completion.
Implementation
Figure 4. Multiple Instances without a Priori Run-Time Knowledge
We use subtask to implement this pattern. For detail on subtask, please refer to: http://publib.boulder.ibm.com/bpcsamp/v6r2/humanTaskFeatures/subtask.html. Notes: We should enable Enable subtask creation attribute of HumanTask2CreateSubtask activity.
Static partial join for multiple instances
This pattern requires multiple instances which are created within a given process instance to be synchronized upon their completion. The next task in the process is triggered when part of the instances complete.
For example, we can complete survey when we get feedback from 70 percent of the members. We will not care the result from the rest.
The focus of this pattern is:
- Multiple instances are created.
- The required number is known when the first task commences.
- The next task can be triggered when n instances of m completes.
- The results of the rest instances are inconsequential.
Figure 5. Static Partial Join for Multiple Instances
We use EventHandler to implement this pattern. In Scope1 which contains ForEach
activity, we control the numbers of the newly created task instances. In HumanTask
activity, we initialize the input1 variable. After the completion of HumanTask, an Invoke activity is triggered which will lead the process to the OnEvent scope.
In OnEvent Scope, we count the numbers of the tasks with variable count. If the count reaches iteration, the process goes to the next activity
Note: Since there is more then one receiving activity be completed, the correlation set should be defined.
Test Data
For input data, we should input an array of type P34BO1 and an integer for iteration. It is recommended that the number of array is larger than the iteration. After claim and complete 2 human task activities, we can see in the log:
[10-10-3 10:38:42:921 CST] 0000004c SystemOut O Index: 1 [10-10-3 10:38:44:500 CST] 0000004c SystemOut O Index: 2 [10-10-3 10:38:44:718 CST] 0000004c SystemOut O Index: 3 [10-10-3 10:39:16:234 CST] 0000004c SystemOut O count: 1 [10-10-3 10:39:16:234 CST] 0000004c SystemOut O iteration: 2 [10-10-3 10:39:16:234 CST] 0000004c SystemOut O iteration > count [10-10-3 10:39:23:218 CST] 0000004c SystemOut O into next activity |
Cancelling partial join for multiple instances
This pattern requires multiple instances which are created within a given process instance to be synchronized upon their completion. The next task in the process is triggered when part of the instances complete. And in the same time, other instances are cancelled.
For example, suppose we are voting in a decision. If we have reached the threshold, there is no need for the rest to submit. So the rest submit task can be cancelled.
Analysis
The focus of this pattern is:
- Multiple instances are created.
- The required number is known when the first task commences.
- The next task can be triggered when n instances of m completes.
- The results of the rest instances are cancelled.
Implementation
Figure 6. Cancelling Partial Join for Multiple Instances
We use the new feature from both WPS v7.0 and WID v7.0 named parallel task to implement this pattern.
Test Data
When a process instance is initialized, 3 human tasks are created. When 2 of them complete, the process goes to the next activity. We can see the left task is cancelled.
Dynamic partial join for multiple instances
This pattern requires multiple instances which are created within a given process instance to be synchronized upon their completion. And the number of the instances can be affected by some run time factors. More important, more instances can be added at run time. The completion condition is specified at each time when an instance of the task completes.
For example, suppose we are voting in a decision in a group. The team lead can decide if it is necessary to involve members from other team or disable involving others.
The focus of this pattern is:
- Multiple instances are created.
- The required number is affected by some runtime factor.
- More instances can be added at run time
- Adding switch can be turned off.
- The completion condition is specified at each time when an instance of the task completes
Figure 6. Dynamic Partial Join for Multiple Instance
We implement this pattern with EventHandler and FaultHandler feature of WPS. In the
FaultHandler (see Catch activity), we simulate the completion of the task instances.
If the user wants to move to the activity, we throw an exception named UserChooseToFinishFault and then the process will go to Snippet7 to continue.
We have got 3 scopes here. In ForEach scope, we initialize the input parameter and other variables. We create task instances in ForEach activity.
In Scope1, we wait for the command to add or disable adding activity. WhetherToAddTask is
the activity to receive such command. The Invoke activity will invoke the same human task as the one in Foreach scope. The onEvent scope performs the familiar function as in pattern Static Partial Join for Multiple Instances in which we will not synchronize when the task completes.
Note: Since there is more than one receiving activity, the correlation set must be defined.
Test Data
For input parameter of the process, we provide a BO array with 3 element and the
processId is set to 11111. We can see 4 human tasks are created. 3 Human tasks and 1 WhetherToAddTask.
[10-10-3 11:00:15:484 CST] 0000004c SystemOut O Initialize [10-10-3 11:00:15:500 CST] 0000004c SystemOut O AddNewTask [10-10-3 11:00:17:906 CST] 0000006d SystemOut O Entry HumanTask [10-10-3 11:00:19:687 CST] 0000006d SystemOut O Entry HumanTask [10-10-3 11:00:19:921 CST] 0000004c SystemOut O Entry HumanTask [10-10-3 11:00:25:656 CST] 0000004b SystemOut O into while loop |
We can attempt to complete a human task. Note that we should set processId to 11111 and field3 to false.
[10-10-3 11:05:14:546 CST] 0000003f SystemOut O Exit HumanTask [10-10-3 11:05:15:750 CST] 0000006d SystemOut O User choose NOT to finish |
We are still in waiting status for adding new task. Now we can attempt to add a new task. We should set field1 of output1 to true.
[10-10-3 11:06:43:468 CST] 0000003e SystemOut O User choose to add more tasks [10-10-3 11:06:43:468 CST] 0000003e SystemOut O processId:11111 [10-10-3 11:06:43:859 CST] 0000004c SystemOut O Event triggered [10-10-3 11:06:46:781 CST] 0000004c SystemOut O into while loop [10-10-3 11:06:47:265 CST] 0000006d SystemOut O Adding new HumanTask [10-10-3 11:06:47:796 CST] 0000004c SystemOut O Entry HumanTask |
We can see that we have 3 human tasks again and WhetherToAddTask is still there for the following up command. If we set field1 in WhetherToAddTask to false, we can see WhetherToAddTask is no longer existing.
[10-10-3 11:06:47:796 CST] 0000004c SystemOut O Entry HumanTask [10-10-3 11:09:51:046 CST] 0000003c SystemOut O User choose NOT add any task |
Now we can move to next activity by working on a human task and set field3 to true. Now the process goes to Snippet7.
[10-10-3 11:11:49:171 CST] 0000003c SystemOut O Exit HumanTask [10-10-3 11:11:49:828 CST] 0000004c SystemOut O User choose to finish |
This pattern is about the cycles in a process. Some activities can be entered and exited several time according to the cycle.
Figure 8. Arbitrary Cycles
We implement this pattern with the Generalized Flow feature in WPS v7.0 and WID v7.0
Test Data1:
- Input any value to start the process,
- then go to My to-dos, and claim the ArbitraryCyclesTask1, input any value for field1
- then go to My to-dos, and claim the ArbitraryCyclesTask2, input any value for field1
- Expected result: the following activity should be invoked sequentially
- Snippet1, Snippet2, Snippet3, Snippet4, Snippet5
Test Data2:
- Input any value to start the process,
- then go to My to-dos, and claim the ArbitraryCyclesTask1, input "redo1" for field1
- then go to My to-dos, and claim the new ArbitraryCyclesTask1, input any value for field1
- then go to My to-dos, and claim the ArbitraryCyclesTask2, input any value for field1
- Expected result: the following activity should be invoked sequentially:
- Snippet1, Snippet2, Snippet3, Snippet2, Snippet3, Snippet4, Snippet5
Test Data3:
- Input any value to start the process,
- then go to My to-dos, and claim the ArbitraryCyclesTask1, input any value for field1.
- then go to My to-dos, and claim the ArbitraryCyclesTask2, input any "redo2" for field1.
- then go to My to-dos, and claim the new ArbitraryCyclesTask1, input any value for field1.
- then go to My to-dos, and claim the new ArbitraryCyclesTask2, input any value for field1.
- Expected result: the following activity should be invoked sequentially:
- Snippet1, Snippet2, Snippet3, Snippet2, Snippet3,Snippet4, Snippet3,Snippet4, Snippet5
This pattern is about the loops in a process. We can have the re-test or post-test condition in the process. That is, the for loop and the while loop
We use ForEach feature to implement the Structured Loop as below:
Figure 9. Structured Loop
We use While Loop feature to implement the Structured Loop (Pre-Test) as below:
Figure 10. Structured Loop Pre Test
We use Repeat Until Loop feature to implement the Structured Loop (Post-Test) as below:
Figure 11. Structured Loop Post Test
In this article, we introduce 7 multiple instance patterns and 2 iteration patterns with related WID implementation. With those workflow control patterns, we can construct complex business process graciously.
| Description | Name | Size | Download method |
|---|---|---|---|
| PI files for this article | Part2PI.zip | 178KB | HTTP |
Information about download methods
Learn
- Learn more about the Workflow Patterns Initiative.
- Access Business
Process Management samples.
- Access WebSphere
Process Server Information Center.
- Read further about the Multiple
Instances without Synchronization pattern.
- Read further about the Multiple Instances with a Priori Design-Time Knowledge pattern.
- Read further about the Multiple Instances with a Priori Run-Time Knowledge pattern.
- Read further about the Multiple
Instances without a Priori Run-Time Knowledge pattern.
- Read further about the Static Partial Join for Multiple Instances pattern.
- Read further about the Cancelling Partial Join for Multiple Instances pattern.
- Read further about the Dynamic Partial Join for Multiple Instances pattern.
- Read further about the Arbitrary Cycles pattern.
- Read further about the Structured Loop pattern.
Get products and technologies
-
Evaluate IBM products in the
way that suits you best: Download a product trial, try a product online,
use a product in a cloud environment, or spend a few hours in the SOA Sandbox learning how to
implement Service Oriented Architecture efficiently.
Discuss
- Get involved in the My developerWorks community.
Connect with other developerWorks users while exploring the
developer-driven blogs, forums, groups, and wikis.




