JBoss.orgCommunity Documentation

Chapter 14. Business Process Model and Notation (BPMN 2.0)

14.1. Current limitations

The Business Process Model and Notation (BPMN) 2.0 specification is steadily moving forward on its way to become a great standard, and we are adopting it for our process modeling in Drools Flow. BPMN 2.0 not only defines a standard on how to graphically represent a business process (like BPMN 1.1), but now also includes execution semantics for the elements defined, and an XML format on how to store (and share) process definitions.

Drools Flow allows you to execute processes defined using the BPMN 2.0 XML format, just the same way as it allows you to execute processes using the custom RuleFlow format. That means that you can use the same API, engine and components like Guvnor and the gwt-console, to execute and manage your BPMN 2.0 processes.

We do yet implement all node types and attributes as defined in the BPMN 2.0 specification, but we already support a very significant subset, which includes all common node types. The following list gives an overview of the various elements that can already be executed using the BPMN 2.0 XML format:

For example, consider the following BPMN process for performing evaluations. Whenever an evaluation process is started for a specific employee, that employee must first perform a self-evaluation, after which the project manager and human resource manager must also fill in their evaluation, as shown in the figure below.

An executable version of this process expressed using BPMN 2.0 XML would look something like this (note that the process needs to contain all the details to make it execuble, including all the parameters for each of the tasks present, hence the large process definition):


<?xml version="1.0" encoding="UTF-8"?> 
<definitions id="Definition"
             targetNamespace="http://www.jboss.org/drools"
             typeLanguage="http://www.java.com/javaTypes"
             expressionLanguage="http://www.mvel.org/2.0"
             xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
             xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
             xs:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd"
             xmlns:g="http://www.jboss.org/drools/flow/gpd"
             xmlns:tns="http://www.jboss.org/drools">

  <process processType="Private" isExecutable="true" id="com.sample.evaluation" name="Evaluation Process" >

    <!-- process variables -->
    <property id="employee" itemSubjectRef="_employeeItem"/>

    <!-- nodes -->
    <startEvent id="_1" name="StartProcess" g:x="16" g:y="56" g:width="48" g:height="48" />
    <userTask id="_2" name="Self Evaluation" g:x="96" g:y="56" g:width="143" g:height="48" >
      <ioSpecification>
        <dataInput id="_2_CommentInput" name="Comment" />
        <dataInput id="_2_SkippableInput" name="Skippable" />
        <dataInput id="_2_TaskNameInput" name="TaskName" />
        <dataInput id="_2_ContentInput" name="Content" />
        <dataInput id="_2_PriorityInput" name="Priority" />
        <inputSet>
          <dataInputRefs>_2_CommentInput</dataInputRefs>
          <dataInputRefs>_2_SkippableInput</dataInputRefs>
          <dataInputRefs>_2_TaskNameInput</dataInputRefs>
          <dataInputRefs>_2_ContentInput</dataInputRefs>
          <dataInputRefs>_2_PriorityInput</dataInputRefs>
        </inputSet>
        <outputSet>
        </outputSet>
      </ioSpecification>
      <dataInputAssociation>
        <targetRef>_2_CommentInput</targetRef>
        <assignment>
          <from xs:type="tFormalExpression">You need to perform a self-evaluation</from>
          <to xs:type="tFormalExpression">_2_CommentInput</to>
        </assignment>
      </dataInputAssociation>
      <dataInputAssociation>
        <targetRef>_2_SkippableInput</targetRef>
        <assignment>
          <from xs:type="tFormalExpression">false</from>
          <to xs:type="tFormalExpression">_2_SkippableInput</to>
        </assignment>
      </dataInputAssociation>
      <dataInputAssociation>
        <targetRef>_2_TaskNameInput</targetRef>
        <assignment>
          <from xs:type="tFormalExpression">Performance Evaluation</from>
          <to xs:type="tFormalExpression">_2_TaskNameInput</to>
        </assignment>
      </dataInputAssociation>
      <dataInputAssociation>
        <targetRef>_2_ContentInput</targetRef>
        <assignment>
          <from xs:type="tFormalExpression"></from>
          <to xs:type="tFormalExpression">_2_ContentInput</to>
        </assignment>
      </dataInputAssociation>
      <dataInputAssociation>
        <targetRef>_2_PriorityInput</targetRef>
        <assignment>
          <from xs:type="tFormalExpression">1</from>
          <to xs:type="tFormalExpression">_2_PriorityInput</to>
        </assignment>
      </dataInputAssociation>
      <potentialOwner>
        <resourceAssignmentExpression>
          <formalExpression>#{employee}</formalExpression>
        </resourceAssignmentExpression>
      </potentialOwner>
    </userTask>
    <parallelGateway id="_3" name="Diverge" g:x="271" g:y="56" g:width="49" g:height="49" gatewayDirection="Diverging" />
    <userTask id="_4" name="HR Manager Evaluation" g:x="352" g:y="96" g:width="225" g:height="48" >
      <ioSpecification>
        <dataInput id="_4_CommentInput" name="Comment" />
        <dataInput id="_4_SkippableInput" name="Skippable" />
        <dataInput id="_4_TaskNameInput" name="TaskName" />
        <dataInput id="_4_ContentInput" name="Content" />
        <dataInput id="_4_PriorityInput" name="Priority" />
        <inputSet>
          <dataInputRefs>_4_CommentInput</dataInputRefs>
          <dataInputRefs>_4_SkippableInput</dataInputRefs>
          <dataInputRefs>_4_TaskNameInput</dataInputRefs>
          <dataInputRefs>_4_ContentInput</dataInputRefs>
          <dataInputRefs>_4_PriorityInput</dataInputRefs>
        </inputSet>
        <outputSet>
        </outputSet>
      </ioSpecification>
      <dataInputAssociation>
        <targetRef>_4_CommentInput</targetRef>
        <assignment>
          <from xs:type="tFormalExpression">You need to perform an evaluation for #{employee}</from>
          <to xs:type="tFormalExpression">_4_CommentInput</to>
        </assignment>
      </dataInputAssociation>
      <dataInputAssociation>
        <targetRef>_4_SkippableInput</targetRef>
        <assignment>
          <from xs:type="tFormalExpression">false</from>
          <to xs:type="tFormalExpression">_4_SkippableInput</to>
        </assignment>
      </dataInputAssociation>
      <dataInputAssociation>
        <targetRef>_4_TaskNameInput</targetRef>
        <assignment>
          <from xs:type="tFormalExpression">Performance Evaluation</from>
          <to xs:type="tFormalExpression">_4_TaskNameInput</to>
        </assignment>
      </dataInputAssociation>
      <dataInputAssociation>
        <targetRef>_4_ContentInput</targetRef>
        <assignment>
          <from xs:type="tFormalExpression"></from>
          <to xs:type="tFormalExpression">_4_ContentInput</to>
        </assignment>
      </dataInputAssociation>
      <dataInputAssociation>
        <targetRef>_4_PriorityInput</targetRef>
        <assignment>
          <from xs:type="tFormalExpression">1</from>
          <to xs:type="tFormalExpression">_4_PriorityInput</to>
        </assignment>
      </dataInputAssociation>
      <potentialOwner>
        <resourceAssignmentExpression>
          <formalExpression>mary</formalExpression>
        </resourceAssignmentExpression>
      </potentialOwner>
    </userTask>
    <userTask id="_5" name="Project Manager Evaluation" g:x="352" g:y="16" g:width="225" g:height="48" >
      <ioSpecification>
        <dataInput id="_5_CommentInput" name="Comment" />
        <dataInput id="_5_SkippableInput" name="Skippable" />
        <dataInput id="_5_TaskNameInput" name="TaskName" />
        <dataInput id="_5_ContentInput" name="Content" />
        <dataInput id="_5_PriorityInput" name="Priority" />
        <inputSet>
          <dataInputRefs>_5_CommentInput</dataInputRefs>
          <dataInputRefs>_5_SkippableInput</dataInputRefs>
          <dataInputRefs>_5_TaskNameInput</dataInputRefs>
          <dataInputRefs>_5_ContentInput</dataInputRefs>
          <dataInputRefs>_5_PriorityInput</dataInputRefs>
        </inputSet>
        <outputSet>
        </outputSet>
      </ioSpecification>
      <dataInputAssociation>
        <targetRef>_5_CommentInput</targetRef>
        <assignment>
          <from xs:type="tFormalExpression">You need to perform an evaluation for #{employee}</from>
          <to xs:type="tFormalExpression">_5_CommentInput</to>
        </assignment>
      </dataInputAssociation>
      <dataInputAssociation>
        <targetRef>_5_SkippableInput</targetRef>
        <assignment>
          <from xs:type="tFormalExpression">false</from>
          <to xs:type="tFormalExpression">_5_SkippableInput</to>
        </assignment>
      </dataInputAssociation>
      <dataInputAssociation>
        <targetRef>_5_TaskNameInput</targetRef>
        <assignment>
          <from xs:type="tFormalExpression">Performance Evaluation</from>
          <to xs:type="tFormalExpression">_5_TaskNameInput</to>
        </assignment>
      </dataInputAssociation>
      <dataInputAssociation>
        <targetRef>_5_ContentInput</targetRef>
        <assignment>
          <from xs:type="tFormalExpression"></from>
          <to xs:type="tFormalExpression">_5_ContentInput</to>
        </assignment>
      </dataInputAssociation>
      <dataInputAssociation>
        <targetRef>_5_PriorityInput</targetRef>
        <assignment>
          <from xs:type="tFormalExpression">1</from>
          <to xs:type="tFormalExpression">_5_PriorityInput</to>
        </assignment>
      </dataInputAssociation>
      <potentialOwner>
        <resourceAssignmentExpression>
          <formalExpression>john</formalExpression>
        </resourceAssignmentExpression>
      </potentialOwner>
    </userTask>
    <parallelGateway id="_6" name="Converge" g:x="603" g:y="55" g:width="49" g:height="49" gatewayDirection="Converging" />
    <endEvent id="_7" name="EndProcess" g:x="690" g:y="56" g:width="48" g:height="48" >
      <terminateEventDefinition/>
    </endEvent>

    <!-- connections -->
    <sequenceFlow id="_1-_2" sourceRef="_1" targetRef="_2" />
    <sequenceFlow id="_2-_3" sourceRef="_2" targetRef="_3" />
    <sequenceFlow id="_3-_4" sourceRef="_3" targetRef="_4" g:bendpoints="[295,120]" />
    <sequenceFlow id="_3-_5" sourceRef="_3" targetRef="_5" g:bendpoints="[295,39]" />
    <sequenceFlow id="_5-_6" sourceRef="_5" targetRef="_6" g:bendpoints="[627,40]" />
    <sequenceFlow id="_4-_6" sourceRef="_4" targetRef="_6" g:bendpoints="[627,121]" />
    <sequenceFlow id="_6-_7" sourceRef="_6" targetRef="_7" />

  </process>

</definitions>

To create your own process using BPMN 2.0 format, you can

The following code fragment shows you how to load a BPMN process into your knowledge base ...

private static KnowledgeBase readKnowledgeBase() throws Exception {
  KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
  kbuilder.add(ResourceFactory.newClassPathResource("sample.bpmn"), ResourceType.BPMN2);
  return kbuilder.newKnowledgeBase();
}

... and how to execute this process.

KnowledgeBase kbase = readKnowledgeBase();
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");
ksession.getWorkItemManager().registerWorkItemHandler("Human Task", new WSHumanTaskHandler());
// start a new process instance
Map<String, Object> params = new HashMap<String, Object>();
params.put("employee", "krisv");
ksession.startProcess("com.sample.evaluation", params);

Since the BPMN 2.0 specification is still being finalized, the BPMN 2.0 execution is still an experimental feature. It uses the same execution engine and constructs as the RuleFlow format however (it's just another XML serialization format). Therefore, all features and components that are available using the RuleFlow format also work for BPMN 2.0 processes. You simply have to use the right ResourceType when adding BPMN 2.0 processes to your knowledge base. Since the specification hasn't been finalized yet, it is possible that the XSD that defines the format might still change (slightly) due to updates of the specification, so keep this in mind if you decide to start using the BPMN 2.0 format.

The use of a specification should give you a lot of advantages, as it allows you to share your processes across tools and possibly even engines as the specification defines the exact format (and even execution semantics) for each of the elements. At this point however, it is likely that different tools are using different intermediate versions of the specification. We believe that this issue will automatically resolve itself over time once the specification is finalized and everyone is using the same version of the specification, but until then, you can encounter compatibility issues related to this problem. Please be a little patient with this.

Finally, the BPMN 2.0 specification defines a lot of node types and attributes, but nevertheless it is not possible to express everything using the constructs offered by the BPMN 2.0 specification only. However, the specification is designed to allow additional node types, attributes, etc. While we try to limit the use of custom extensions to a minimum, we sometimes have to define custom attributes to express features that we believe are important but cannot be expressed as core BPMN 2.0 syntax. The following table gives an overview of which features of the RuleFlow language have already been ported to the BPMN 2.0 XML format. A green check mark means that the functionality can be expressed using the features defined in the BPMN 2.0 specification. In those cases where we extend the BPMN 2.0 specification with additional attributes and/or elements, we show these using an orange check mark. As shown in the table below, most of the basic BPMN 2.0 nodes are already supported. We decided to not yet implement some of the features that cannot be expressed in BPMN 2.0 by default, like for example the on-entry / on-exit actions or the state node. We will decide later whether we want to support these features for BPMN 2.0 processes in the future, and how.

Table 14.1. Keywords

FeatureDrools BPMNDrools Flow
A. Process-level  
   
Imports 
Function Imports 
Variable
- primitive Java types
- Java object types
- default value 
Swimlanes
Exception handlers 
- fault name 
- bind to variable 
- action 
   
B. Nodes  
   
1. Start Node
- rule trigger
- signal trigger
- parameter mapping
   
2. End Node
- terminate
   
3. Action Node
- Java dialect
* access to variables, global, context
- MVEL dialect
* access to variables, global, context
   
4. RuleSet Node
- timers 
   
5. Split Node
- AND
- XOR
- OR
- Java code constraints
- MVEL code constraints
- rule constraints
- constraint names
- constraint priorities 
   
6. Join Node
AND
XOR
Discriminator 
n-of-m 
   
7. State Node 
- timers 
- on entry actions 
- on exit actions 
- automatic transition constraints 
- manual transition signal 
   
8. SubProcess Node
- timers 
- on entry actions 
- on exit actions 
- wait for completion
- independant
- parameter mapping (in/out)
- dynamic process id
   
9. WorkItem Node
- parameters
- parameter mapping (in/out)
- timers 
- on entry actions 
- on exit actions 
- wait for completion 
   
10. Timer Node
- delay
- period 
   
11. Human Task Node (also see WorkItem Node)
- swimlane
   
12. Composite Node
- timers 
- on entry actions 
- on exit actions 
- variables
- exception handlers 
- multiple entry points 
- multiple exit points 
   
13. ForEach Node
- bind to variable
- wait for completion 
- multiple entry points 
- multiple exit points 
   
14. Event Node
- bind to variable
- internal / external 
- event filters 
   
15. Fault Node
- fault name
- fault data
   
Graphical information (x, y, width, height)
   
C. Connections  
From, To
From type 
To type 
Graphical information (bendpoints)