The order flow

describe
  • A sequential flow is a wire that connects two process nodes
  • After a process completes execution of a node, it continues execution along all outgoing sequential flows of the node
  • The default behavior of BPMN 2.0 is concurrent: two outgoing sequential flows create two separate, concurrent process branches

    Graphic tag
  • The sequential flow is shown as an arrow from the beginning to the end. The arrow always points to the end

    The XML content
  • A sequential flow requires an ID that is unique within the scope of the process and a reference to the start and end elements

    <sequenceFlow id="flow1" sourceRef="theStart" targetRef="theTask" />

    Conditional sequential flow

    describe
  • Define a condition for the sequential flow
  • When leaving a BPMN 2.0 node, conditions for outgoing sequential flows are calculated by default

    • If the condition results in true, the outbound sequential flow is selected to continue execution
    • When multiple sequential flows are selected, multiple branches are created and the process continues to execute in parallel
  • == Note :== does not include gateways, which handle conditions in sequential flows in a particular way, depending on the type of gateway

    Graphic tag
  • The conditional sequential flow is shown as a normal sequential flow, with one at the starting pointThe diamond.Conditional expressions are also displayed on the sequential stream

    The XML content
  • ConditionExpression a conditional order stream is defined as a normal order stream that contains conditionExpression child elements
  • Currently only tFormalExpressions are supported. If xSI :type=”” is not set, the currently supported expression types are supported by default

    <sequenceFlow id="flow" sourceRef="theStart" targetRef="theTask"> <conditionExpression xsi:type="tFormalExpression"> <! [CDATA[${order.price > 100 && order.price < 250}]]> </conditionExpression> </sequenceFlow>
  • The current conditional expression can only be UEL. The expression to be used must return a Boolean value. Otherwise, an exception will be raised during expression parsing

    • The JavaBean is called through the getter for the data that references the process variable

      <conditionExpression xsi:type="tFormalExpression"> <! [CDATA[${order.price > 100 && order.price < 250}]]> </conditionExpression>
      • Returns a Boolean value by calling a method

        <conditionExpression xsi:type="tFormalExpression"> <! [CDATA[${order.isStandardOrder()}]]> </conditionExpression>
  • In the Activiti distribution package, the following process instances are included, using values and method expressions

    Default sequential flow

    describe
  • All BPMN 2.0 tasks and gateways can be set to a default sequential flow
  • Execution is continued as an outgoing sequential flow only if other outgoing sequential flows of the node cannot be selected
  • Conditions for the default sequential flow do not take effect

    Graphic tag
  • The default sequential flow is displayed asOrdinary sequential flow,The starting point is marked by an oblique line

    The XML content
  • The default order flows through the default attribute definition of the corresponding node
  • The following XML code demonstrates that the exclusive gateway sets the default order flow flow 2. ConditionA is selected as the outbound line to continue execution only if both conditionA and conditionB return false:

    <exclusiveGateway id="exclusiveGw" name="Exclusive Gateway" default="flow2" />
    <sequenceFlow id="flow1" sourceRef="exclusiveGw" targetRef="task1">
    <conditionExpression xsi:type="tFormalExpression">${conditionA}</conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow2" sourceRef="exclusiveGw" targetRef="task2"/>
    <sequenceFlow id="flow3" sourceRef="exclusiveGw" targetRef="task3">
    <conditionExpression xsi:type="tFormalExpression">${conditionB}</conditionExpression>
    </sequenceFlow>
  • Corresponding graph:

    The gateway

  • The gateway is used to control the flow of the process (the tokens of the process). The gateway can consume or generate tokens
  • The gateway is shown in a diamond with a small icon inside. The icon indicates the gateway type.

    Exclusive gateway

    describe
  • Exclusive gateway: XOR or gateway, used to implement decisions in the process
  • When the process executes to the gateway, all outgoing sequential flows are processed once. Sequential flows where the condition resolves to true (or where no condition is set and a [true] is conceptually defined on the sequential flow) are selected, allowing the process to continue
  • == Note :== Normally, all sequential flows with true results will be selected and executed in parallel, but the exclusive gateway will only select one sequential flow for execution. That is, even if the conditional result for multiple sequential flows is true, the first sequential flow (and only this one) in the XML is selected and used to continue the process. If no sequential stream is selected, an exception is thrown

    Graphic tag
  • The exclusive gateway is shown as a normal gateway (for example, a diamond) with an X icon inside that represents XOR semantics.
  • A gateway with no internal icon is an exclusive gateway by default
  • The BPMN 2.0 specification does not allow the use of diamond graphs with and without X in the same process definition

    The XML content
  • The gateway is defined in a single line, and the conditional expression is defined in the outgoing sequential flow
  • Model example:

    <exclusiveGateway id="exclusiveGw" name="Exclusive Gateway" />
    
    <sequenceFlow id="flow2" sourceRef="exclusiveGw" targetRef="theTask1">
    <conditionExpression xsi:type="tFormalExpression">${input == 1}</conditionExpression>
    </sequenceFlow>
    
    <sequenceFlow id="flow3" sourceRef="exclusiveGw" targetRef="theTask2">
    <conditionExpression xsi:type="tFormalExpression">${input == 2}</conditionExpression>
    </sequenceFlow>
    
    <sequenceFlow id="flow4" sourceRef="exclusiveGw" targetRef="theTask3">
    <conditionExpression xsi:type="tFormalExpression">${input == 3}</conditionExpression>
    </sequenceFlow>

    A parallel gateway

    describe
  • Gateways can also represent parallelism in a process
  • It allows the process to be divided into multiple branches or to be aggregated into multiple branches
  • The functionality of the parallel gateway is based on incoming and outgoing sequential flows:

    • Branch: All outgoing sequential flows after parallelization, creating a concurrent branch for each sequential flow
    • Aggregation: All incoming branches that arrive at the parallel gateway and wait there until all branches that enter the sequential flow arrive, then the process passes through the aggregation gateway
  • The same parallel gateway has multiple incoming and outgoing sequential flows with branching and aggregation functions
  • The gateway aggregates all incoming sequential streams and then cuts into multiple parallel branches
  • Parallel gateways do not resolve conditions: unlike other gateways, conditions are ignored even if they are defined in the sequential flow

    Graphic tag
  • The parallel gateway is shown as a common gateway (diamond) with an internal one+Icon, indicatingAND (AND)The semantic

    The XML content
  • A single line of XML is required to define the parallel gateway

    <parallelGateway id="myParallelGateway" />
  • The actual behavior (branch, aggregate, and branch aggregate at the same time) is determined by the sequential flow of the parallel gateways

     <startEvent id="theStart" />
      <sequenceFlow id="flow1" sourceRef="theStart" targetRef="fork" />
    
      <parallelGateway id="fork" />
      <sequenceFlow sourceRef="fork" targetRef="receivePayment" />
      <sequenceFlow sourceRef="fork" targetRef="shipOrder" />
    
      <userTask id="receivePayment" name="Receive Payment" />
      <sequenceFlow sourceRef="receivePayment" targetRef="join" />
    
      <userTask id="shipOrder" name="Ship Order" />
      <sequenceFlow sourceRef="shipOrder" targetRef="join" />
    
      <parallelGateway id="join" />
      <sequenceFlow sourceRef="join" targetRef="archiveOrder" />
    
      <userTask id="archiveOrder" name="Archive Order" />
      <sequenceFlow sourceRef="archiveOrder" targetRef="theEnd" />
    
      <endEvent id="theEnd" />
  • After the process starts, two tasks are created:

    ProcessInstance pi = runtimeService.startProcessInstanceByKey("forkJoin");
    TaskQuery query = taskService.createTaskQuery()
                           .processInstanceId(pi.getId())
                           .orderByTaskName()
                           .asc();
    
    List<Task> tasks = query.list();
    assertEquals(2, tasks.size());
    
    Task task1 = tasks.get(0);
    assertEquals("Receive Payment", task1.getName());
    Task task2 = tasks.get(1);
    assertEquals("Ship Order", task2.getName());

    When both tasks are completed, the second parallel gateway converges the two branches. Because it has only one outgoing line, no parallel branch is created, only the archive order task is created

  • Note that parallel gateways do not need to be “balanced “(the number of incoming and outgoing nodes corresponding to parallel gateways is equal). Parallel gateways are justWaiting for theAll enter the sequential flow and create concurrent branches for each outgoing sequential flow without being affected by other process nodes

    Contains the gateway

    describe
  • A combination of exclusive and parallel gateways:

    • As with exclusive gateways, conditions can be defined on outgoing sequential flows, and inclusive gateways resolve the conditions
    • As with parallel gateways, containment gateways can select more than one sequential flow
  • The functionality that contains the gateway is based on incoming and outgoing sequential flows:

    • Branching: All conditions for outgoing sequential flows are resolved, and sequential flows that result in true continue to execute in parallel, creating a branch for each sequential flow
    • Aggregation: All parallel branches arriving at the containing gateway enter a wait state until each branch entering the sequential flow containing the process token has arrived. This is the biggest difference with parallel gateways. The containment gateway will only wait for selected and executed entries into the sequential flow. After the aggregation, the process continues through the containment gateway
  • If the same containing node has multiple incoming and outgoing sequential flows, it will have both branching and aggregation capabilities
  • The gateway will first gather all the incoming sequential flows that have the process token, then judge the outgoing sequential flows whose results are true according to the condition, and generate multiple parallel branches for them

    Graphic tag
  • The parallel gateway appears as a normal gateway (diamond) with a circle icon inside

    The XML content
  • Defining a containment gateway requires a single line of XML

    <inclusiveGateway id="myInclusiveGateway" />
  • The actual behavior (branching, converging, and branching converging) is determined by the sequential flow connected to the containing gateway

     <startEvent id="theStart" />
      <sequenceFlow id="flow1" sourceRef="theStart" targetRef="fork" />
    
      <inclusiveGateway id="fork" />
      <sequenceFlow sourceRef="fork" targetRef="receivePayment" >
      <conditionExpression xsi:type="tFormalExpression">${paymentReceived == false}</conditionExpression>
      </sequenceFlow>
      <sequenceFlow sourceRef="fork" targetRef="shipOrder" >
      <conditionExpression xsi:type="tFormalExpression">${shipOrder == true}</conditionExpression>
      </sequenceFlow>
    
      <userTask id="receivePayment" name="Receive Payment" />
      <sequenceFlow sourceRef="receivePayment" targetRef="join" />
    
      <userTask id="shipOrder" name="Ship Order" />
      <sequenceFlow sourceRef="shipOrder" targetRef="join" />
    
      <inclusiveGateway id="join" />
      <sequenceFlow sourceRef="join" targetRef="archiveOrder" />
    
      <userTask id="archiveOrder" name="Archive Order" />
      <sequenceFlow sourceRef="archiveOrder" targetRef="theEnd" />
    
      <endEvent id="theEnd" />
  • Once the process starts

    • If the process variables are paymentReceived== false and shipOrder == true, two tasks are created
    • If only one process variable is true, only one task will be created
    • If no condition is true, an exception is thrown
    • If you want to avoid exceptions, you can define a default sequential stream
  • Include gateway example: Create a shipping task

    HashMap<String, Object> variableMap = new HashMap<String, Object>();
            variableMap.put("receivedPayment", true);
            variableMap.put("shipOrder", true);
            ProcessInstance pi = runtimeService.startProcessInstanceByKey("forkJoin");
    TaskQuery query = taskService.createTaskQuery()
                           .processInstanceId(pi.getId())
                           .orderByTaskName()
                           .asc();
    
    List<Task> tasks = query.list();
    assertEquals(1, tasks.size());
    
    Task task = tasks.get(0);
    assertEquals("Ship Order", task.getName());
  • When the task is complete, the second containing gateway aggregates the two branches, and since there is only one outgoing sequential flow, no parallel branches are created, and only the archive order task is activated
  • Inclusion gateways do not need to be balanced (the number of entries and exits corresponding to inclusion gateways needs to be equal). The containment gateway waits for all incoming sequential flows to complete and creates parallel branches for each outgoing sequential flow, unaffected by other elements in the process

    Event-based gateway

    describe
  • Event-based gateways allow flow direction to be determined based on events

    • Each outbound sequential flow of the gateway is connected to an intermediate capture event
    • When the process reaches an event-based gateway, the gateway enters a wait state: execution is suspended
    • Create an event subscription for each outbound sequential flow
  • Event gateway-based outbound sequential flows are different from normal sequential flows: These sequential flows do not actually “execute “, leaving the process engine to decide which events to subscribe to for the process to execute to the event gateway-based process, taking into account the following conditions:

    • Event-based gateways must have two or more outbound sequential flows
    • Only the intermediateCatchEvent type can be used after event gateway (Activiti does not support connecting ReceiveTask after event gateway)
    • Only one of the intermediatecatchEvents connected to the event-based gateway can enter the sequential flow

      Graphic tag
  • The event-based gateway, like the other BPMN gateways, appears as a diamond and contains the specified icon inside

    The XML content
  • The XML element used to define the event-based gateway is eventBasedGateway

    The instance
  • Example event-based gateways:

    • When the process is executed to the event-based gateway, the process is suspended
    • At the same time, the process instance subscribers to the warning signal event and creates a timer that is triggered after 10 minutes. Produces the effect of the process engine waiting 10 minutes for a signal event
    • If the signal is emitted within 10 minutes, the timer is cancelled and the process executes along the signal
    • If the signal does not appear, the process moves in the direction of the timer and the signal subscription is cancelled

      <definitions id="definitions"
         xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
         xmlns:activiti="http://activiti.org/bpmn"
         targetNamespace="Examples">
      
         <signal id="alertSignal" name="alert" />
      
         <process id="catchSignal">
      
                 <startEvent id="start" />
      
                 <sequenceFlow sourceRef="start" targetRef="gw1" />
      
                 <eventBasedGateway id="gw1" />
      
                 <sequenceFlow sourceRef="gw1" targetRef="signalEvent" />
                 <sequenceFlow sourceRef="gw1" targetRef="timerEvent" />
      
                 <intermediateCatchEvent id="signalEvent" name="Alert">
                         <signalEventDefinition signalRef="alertSignal" />
                 </intermediateCatchEvent>
      
                 <intermediateCatchEvent id="timerEvent" name="Alert">
                         <timerEventDefinition>
                                 <timeDuration>PT10M</timeDuration>
                         </timerEventDefinition>
                 </intermediateCatchEvent>
      
                 <sequenceFlow sourceRef="timerEvent" targetRef="exGw1" />
                 <sequenceFlow sourceRef="signalEvent" targetRef="task" />
      
                 <userTask id="task" name="Handle alert"/>
      
                 <exclusiveGateway id="exGw1" />
      
                 <sequenceFlow sourceRef="task" targetRef="exGw1" />
                 <sequenceFlow sourceRef="exGw1" targetRef="end" />
      
                 <endEvent id="end" />
      </process>
      </definitions>