Open Documentation Menu

Using gateways

When modeling your own processes, you can use the BPMN item Gateway of the exclusive type (branching point of exclusive type) to create dynamic processes with a decision logic.

When getting started with exclusive gateways, it is useful to create a simple process with one user activity first. This process will e.g. look like this:

process_example.png

The BPMN model of this sample process is structured as follows:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" targetNamespace="" exporter="d.velop process modeler">
  <process id="exclusive_gateway_process" name="Exclusive Gateway Process" isExecutable="true">
    <startEvent id="start" />     
        <userTask id="task_hello_world" name="Hello World" camunda:camundaUsers="${variables.get('dv_initiator')}" />
    <endEvent id="end" />
    <sequenceFlow id="s1" sourceRef="start" targetRef="task_hello_world" />
    <sequenceFlow id="s2" sourceRef="task_hello_world" targetRef="end" />
  </process>
</definitions>

You now expand this sample process with a gateway. Based on the value of a process variable, this process will either lead to the user activity or will be ended directly.

Adding a gateway

First add the BPMN item exclusiveGateway to the process. The item exclusiveGateway represents a branching point with only one possible start path. Then replace the existing sequence flows with the following sequence flows:

...
<process id="exclusive_gateway_process" name="Exclusive Gateway Process" isExecutable="true">
  <startEvent id="start" />
  <exclusiveGateway id="gateway" default="gateway-option-b" />   
  <userTask id="task_hello_world" name="Hello World" camunda:camundaUsers="${variables.get('dv_initiator')}" />
  <exclusiveGateway id="join" />
  <endEvent id="end" />
  <sequenceFlow id="s1" sourceRef="start" targetRef="gateway" />
  <sequenceFlow id="gateway-option-a" sourceRef="gateway" targetRef="task_hello_world" />
  <sequenceFlow id="gateway-option-b" sourceRef="gateway" targetRef="join" />
  <sequenceFlow id="s2" sourceRef="task_hello_world" targetRef="join" />
  <sequenceFlow id="s3" sourceRef="join" targetRef="end" />
</process>

Explanation of the properties:

  • id: The property is used as a unique identifier for the gateway.

  • default: The property defines the ID of the sequence flow to be selected as the default start path of the gateway.

The process will then e.g. look like this:

image2020-11-6_8-34-42.png

Adding a condition

All start paths of an exclusive gateway must contain a condition. The application uses this condition to determine which path the process is to take. For the sample process, add the condition to the sequence flow gw-option-a that this path is selected depending on the variable amount. If this variable corresponds to a value greater than 1000, the sequence flow gw-option-a is to be selected.

...
<sequenceFlow id="gw-option-a" sourceRef="gateway" targetRef="task_hello_world" > 
  <conditionExpression xsi:type="tFormalExpression">#{variables.get("amount") > 1000}</conditionExpression>
<sequenceFlow>
...

To be able to use a process variable, you need to add it to the process definition. In the process definition, you add the BPMN items extensionElements and camunda:properties to the BPMN item process. To define the process variable, then add the item camunda:property to the BPMN item camunda:properties. In this example, you add the variable amount of the Number type. This is a mandatory variable which must be provided at the start.

...
<process id="exclusive_gateway_process" name="Exclusive Gateway Process" isExecutable="true">
  <extensionElements>
    <camunda:properties>
      <camunda:property name="variable:amount*" value="Number!" />
    </camunda:properties>
  </extensionElements>
  ...
</process>

In order for the BPMN diagram to be displayed correctly in the modeling tool as well as the user interface, diagram information has been added. The final BPMN definition looks as follows:

<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" targetNamespace="" exporter="d.velop process modeler">
  <process id="exclusive_gateway_process" name="Exclusive Gateway Process" isExecutable="true">
    <extensionElements>
      <camunda:properties>
        <camunda:property name="variable:amount*" value="Number!" />
      </camunda:properties>
    </extensionElements>
    <startEvent id="start" />
    <exclusiveGateway id="gateway" default="gateway-option-b" />
    <userTask id="task_hello_world" name="Hello World" camunda:candidateUsers="${variables.get('dv_initiator')}" />
    <exclusiveGateway id="join" />
    <endEvent id="end" />
    <sequenceFlow id="s1" sourceRef="start" targetRef="gateway" />
    <sequenceFlow id="gateway-option-a" sourceRef="gateway" targetRef="task_hello_world">
      <conditionExpression xsi:type="tFormalExpression">#{variables.get("amount") > 1000}</conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="gateway-option-b" sourceRef="gateway" targetRef="join" />
    <sequenceFlow id="s2" sourceRef="task_hello_world" targetRef="join" />
    <sequenceFlow id="s3" sourceRef="join" targetRef="end" />
  </process>
  
  <!-- Diagram information -->
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="exclusive_gateway_process">
      <bpmndi:BPMNShape id="start_di" bpmnElement="start">
        <dc:Bounds x="179" y="199" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="gateway_di" bpmnElement="gateway" isMarkerVisible="true">
        <dc:Bounds x="275" y="192" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="task_hello_world_di" bpmnElement="task_hello_world">
        <dc:Bounds x="410" y="80" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="join_di" bpmnElement="join" isMarkerVisible="true">
        <dc:Bounds x="595" y="192" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="end_di" bpmnElement="end">
        <dc:Bounds x="702" y="199" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="s1_di" bpmnElement="s1">
        <di:waypoint x="215" y="217" />
        <di:waypoint x="275" y="217" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="gateway-option-a_di" bpmnElement="gateway-option-a">
        <di:waypoint x="300" y="192" />
        <di:waypoint x="300" y="120" />
        <di:waypoint x="410" y="120" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="gateway-option-b_di" bpmnElement="gateway-option-b">
        <di:waypoint x="325" y="217" />
        <di:waypoint x="595" y="217" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="s2_di" bpmnElement="s2">
        <di:waypoint x="510" y="120" />
        <di:waypoint x="620" y="120" />
        <di:waypoint x="620" y="192" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="s3_di" bpmnElement="s3">
        <di:waypoint x="645" y="217" />
        <di:waypoint x="702" y="217" />
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

You can now define the value of the variable amount e.g. for the start of the process and impact the process sequence this way.