Camunda如何使用條件事件(條件coe)
Camunda條件事件(Conditional Events):定義了一個(gè)事件,該事件在給定條件被求值為true時(shí)被觸發(fā)。它可以作為事件子流程的起始事件、中間事件和邊界事件。開(kāi)始和邊界事件可以是中斷的和不中斷的。在Camunda中,條件事件是在流程變量的幫助下觸發(fā)的。
Camunda條件事件包括:Conditional Start Event(啟動(dòng)條件事件)、Intermediate Conditional Catch Event(中間捕獲條件事件)、Conditional Boundary Event(邊界條件事件)、Conditional Start Event for Event Sub Process(子流程條件事件)。
本文重點(diǎn)介紹Conditional Start Event(啟動(dòng)條件事件)和T Conditional Boundary Event(邊界條件事件),其它事件請(qǐng)參考camunda官方文檔:https://docs.camunda.org/manual/7.15/reference/bpmn20/events/
一、設(shè)計(jì)流程圖
測(cè)試場(chǎng)景:通過(guò)報(bào)銷(xiāo)流程模擬條件事件流程自動(dòng)發(fā)起,如果報(bào)銷(xiāo)金額大于10000元,將自動(dòng)發(fā)起報(bào)銷(xiāo)審批子流程,在財(cái)務(wù)審批環(huán)節(jié),如果報(bào)銷(xiāo)金額金額發(fā)生變化,自動(dòng)觸發(fā)邊界條件事件,退后給審批人。
報(bào)銷(xiāo)主流程:
報(bào)銷(xiāo)事件節(jié)點(diǎn)配置:
代理類(lèi)代碼如下:
package com.example.demo1;import org.camunda.bpm.engine.RuntimeService;import org.camunda.bpm.engine.delegate.DelegateExecution;import org.camunda.bpm.engine.delegate.javaDelegate;import org.camunda.bpm.engine.runtime.ProcessInstance;import java.util.List;/** * 觸發(fā)條件事件啟動(dòng)子流程 */public class InstantiateProcessByConditionDelegate implements JavaDelegate { public void execute(DelegateExecution execution) { Integer money = (int)execution.getVariable("money"); RuntimeService runtimeService = execution.getProcessEngineServices().getRuntimeService(); List<ProcessInstance> instances = runtimeService .createConditionEvaluation() .setVariable("money", money) .evaluateStartConditions(); }}
BPMN流程模型文件:
<?xml version="1.0" encoding="UTF-8"?><bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1ktuxzn" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.8.1" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0"> <bpmn:process id="Process_10z1wy2" name="報(bào)銷(xiāo)主流程" isExecutable="true"> <bpmn:startEvent id="StartEvent_1"> <bpmn:outgoing>Flow_0f0u4dp</bpmn:outgoing> </bpmn:startEvent> <bpmn:sequenceFlow id="Flow_0f0u4dp" sourceRef="StartEvent_1" targetRef="Activity_02e4hhc" /> <bpmn:sequenceFlow id="Flow_0ckn1r7" sourceRef="Activity_02e4hhc" targetRef="Activity_1lkdefp" /> <bpmn:endEvent id="Event_1iic3x0"> <bpmn:incoming>Flow_04z0quc</bpmn:incoming> </bpmn:endEvent> <bpmn:sequenceFlow id="Flow_04z0quc" sourceRef="Activity_1lkdefp" targetRef="Event_1iic3x0" /> <bpmn:serviceTask id="Activity_02e4hhc" name="報(bào)銷(xiāo)事件" camunda:class="com.example.demo1.InstantiateProcessByConditionDelegate"> <bpmn:incoming>Flow_0f0u4dp</bpmn:incoming> <bpmn:outgoing>Flow_0ckn1r7</bpmn:outgoing> </bpmn:serviceTask> <bpmn:userTask id="Activity_1lkdefp" name="通知報(bào)銷(xiāo)人" camunda:assignee="demo"> <bpmn:incoming>Flow_0ckn1r7</bpmn:incoming> <bpmn:outgoing>Flow_04z0quc</bpmn:outgoing> </bpmn:userTask> </bpmn:process> <bpmndi:BPMNDiagram id="BPMNDiagram_1"> <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_10z1wy2"> <bpmndi:BPMNEdge id="Flow_0f0u4dp_di" bpmnElement="Flow_0f0u4dp"> <di:waypoint x="215" y="117" /> <di:waypoint x="270" y="117" /> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="Flow_0ckn1r7_di" bpmnElement="Flow_0ckn1r7"> <di:waypoint x="370" y="117" /> <di:waypoint x="430" y="117" /> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="Flow_04z0quc_di" bpmnElement="Flow_04z0quc"> <di:waypoint x="530" y="117" /> <di:waypoint x="592" y="117" /> </bpmndi:BPMNEdge> <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1"> <dc:Bounds x="179" y="99" width="36" height="36" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="Event_1iic3x0_di" bpmnElement="Event_1iic3x0"> <dc:Bounds x="592" y="99" width="36" height="36" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="Activity_09rzn3u_di" bpmnElement="Activity_02e4hhc"> <dc:Bounds x="270" y="77" width="100" height="80" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="Activity_1khoz85_di" bpmnElement="Activity_1lkdefp"> <dc:Bounds x="430" y="77" width="100" height="80" /> </bpmndi:BPMNShape> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram></bpmn:definitions>
報(bào)銷(xiāo)審批子流程:
Conditional Start Event(啟動(dòng)條件事件)節(jié)點(diǎn)配置:
${money>=10000} 表示報(bào)銷(xiāo)金額大于等于1萬(wàn)元,流程自動(dòng)啟動(dòng)。
Conditional Boundary Event(邊界條件事件)節(jié)點(diǎn)配置:
${money>=20000}表示報(bào)銷(xiāo)金額大于等于2萬(wàn)元,自動(dòng)觸發(fā)邊界條件事件。
BPMN流程模型文件:
<?xml version="1.0" encoding="UTF-8"?><bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1n4m8dk" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.8.1" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0"> <bpmn:process id="Process_0uf5zc5" name="條件事件流程" isExecutable="true"> <bpmn:sequenceFlow id="Flow_1f7cdrv" sourceRef="StartEvent_1" targetRef="Activity_15fulz2" /> <bpmn:sequenceFlow id="Flow_0p7c5lt" sourceRef="Activity_15fulz2" targetRef="Activity_0xikne3" /> <bpmn:endEvent id="Event_152527w"> <bpmn:incoming>Flow_1l03vwj</bpmn:incoming> </bpmn:endEvent> <bpmn:sequenceFlow id="Flow_1l03vwj" sourceRef="Activity_0xikne3" targetRef="Event_152527w" /> <bpmn:startEvent id="StartEvent_1"> <bpmn:outgoing>Flow_1f7cdrv</bpmn:outgoing> <bpmn:conditionalEventDefinition id="ConditionalEventDefinition_0lzdf7y" camunda:variableName="money"> <bpmn:condition xsi:type="bpmn:tFormalExpression">${money>=10000}</bpmn:condition> </bpmn:conditionalEventDefinition> </bpmn:startEvent> <bpmn:userTask id="Activity_15fulz2" name="經(jīng)理審批" camunda:assignee="demo"> <bpmn:incoming>Flow_1f7cdrv</bpmn:incoming> <bpmn:incoming>Flow_08he9tn</bpmn:incoming> <bpmn:outgoing>Flow_0p7c5lt</bpmn:outgoing> </bpmn:userTask> <bpmn:userTask id="Activity_0xikne3" name="財(cái)務(wù)審批" camunda:assignee="demo"> <bpmn:incoming>Flow_0p7c5lt</bpmn:incoming> <bpmn:outgoing>Flow_1l03vwj</bpmn:outgoing> </bpmn:userTask> <bpmn:boundaryEvent id="Event_0mnbhru" name="報(bào)銷(xiāo)費(fèi)修改事件" attachedToRef="Activity_0xikne3"> <bpmn:outgoing>Flow_08he9tn</bpmn:outgoing> <bpmn:conditionalEventDefinition id="ConditionalEventDefinition_19eu007" camunda:variableName="money"> <bpmn:condition xsi:type="bpmn:tFormalExpression">${money>=20000}</bpmn:condition> </bpmn:conditionalEventDefinition> </bpmn:boundaryEvent> <bpmn:sequenceFlow id="Flow_08he9tn" sourceRef="Event_0mnbhru" targetRef="Activity_15fulz2" /> </bpmn:process> <bpmndi:BPMNDiagram id="BPMNDiagram_1"> <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_0uf5zc5"> <bpmndi:BPMNEdge id="Flow_1f7cdrv_di" bpmnElement="Flow_1f7cdrv"> <di:waypoint x="215" y="117" /> <di:waypoint x="270" y="117" /> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="Flow_0p7c5lt_di" bpmnElement="Flow_0p7c5lt"> <di:waypoint x="370" y="117" /> <di:waypoint x="500" y="117" /> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="Flow_1l03vwj_di" bpmnElement="Flow_1l03vwj"> <di:waypoint x="600" y="117" /> <di:waypoint x="662" y="117" /> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="Flow_08he9tn_di" bpmnElement="Flow_08he9tn"> <di:waypoint x="550" y="175" /> <di:waypoint x="550" y="195" /> <di:waypoint x="320" y="195" /> <di:waypoint x="320" y="157" /> </bpmndi:BPMNEdge> <bpmndi:BPMNShape id="Event_1d290h0_di" bpmnElement="StartEvent_1"> <dc:Bounds x="179" y="99" width="36" height="36" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="Activity_1hwmimx_di" bpmnElement="Activity_15fulz2"> <dc:Bounds x="270" y="77" width="100" height="80" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="Event_152527w_di" bpmnElement="Event_152527w"> <dc:Bounds x="662" y="99" width="36" height="36" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="Activity_10pf0x5_di" bpmnElement="Activity_0xikne3"> <dc:Bounds x="500" y="77" width="100" height="80" /> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="Event_0bjat0x_di" bpmnElement="Event_0mnbhru"> <dc:Bounds x="532" y="139" width="36" height="36" /> <bpmndi:BPMNLabel> <dc:Bounds x="451" y="166" width="77" height="14" /> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram></bpmn:definitions>
二、部署流程并測(cè)試驗(yàn)證
流程部署后,查看數(shù)據(jù)庫(kù)流程訂閱事件表act_ru_event_subscr,發(fā)現(xiàn)Conditional Start Event(條件啟動(dòng)事件)已持久化到數(shù)據(jù)庫(kù)中。
通過(guò)demo用戶(hù)登錄camunda平臺(tái)http://localhost:8080/camunda/app/tasklist/default/#/login,啟動(dòng)主流程模擬測(cè)試。
由于報(bào)銷(xiāo)金額滿(mǎn)足條件,所以子流程被自動(dòng)觸發(fā)啟動(dòng):
手動(dòng)子流程提交到下一節(jié)點(diǎn):
此時(shí),流程流轉(zhuǎn)到了Conditional Boundary Event(邊界條件事件)節(jié)點(diǎn)上,查看數(shù)據(jù)庫(kù)表記錄:
為了模擬觸發(fā)Conditional Boundary Event,在camunda后臺(tái)修改money變量值:
由于流程變量money變成了20000,滿(mǎn)足了Conditional Boundary Event觸發(fā)條件,所以流程自動(dòng)流程到對(duì)應(yīng)節(jié)點(diǎn)。
三、條件事件使用說(shuō)明
- Conditional Start Event(啟動(dòng)條件事件)
條件啟動(dòng)事件(Conditional Start Event)可以通過(guò)計(jì)算某些條件來(lái)啟動(dòng)流程。一個(gè)流程可以有一個(gè)或多個(gè)條件啟動(dòng)事件。
如果滿(mǎn)足了多個(gè)條件,則會(huì)觸發(fā)相應(yīng)數(shù)量的進(jìn)程。
部署帶有條件啟動(dòng)事件的流程定義時(shí),需要考慮以下事項(xiàng):
在給定的流程定義中,條件啟動(dòng)事件的條件必須是唯一的,也就是說(shuō),流程定義不能有多個(gè)條件相同的條件啟動(dòng)事件。如果兩個(gè)或多個(gè)條件啟動(dòng)事件包含相同的條件,則引擎會(huì)在部署流程定義時(shí)拋出異常。
流程版本控制:在部署流程定義的新版本時(shí),將取消前一個(gè)版本的條件訂閱。新版本中沒(méi)有出現(xiàn)的條件事件也是如此。
當(dāng)啟動(dòng)一個(gè)流程實(shí)例時(shí),可以在RuntimeService上使用以下方法觸發(fā)一個(gè)條件啟動(dòng)事件:
List<ProcessInstance> instances = runtimeService .createConditionEvaluation() .setVariable("temperature", 24) .evaluateStartConditions();// orList<ProcessInstance> instances = runtimeService .createConditionEvaluation() .setVariables(variableMap).evaluateStartConditions();
所提供的變量用于計(jì)算條件。它們還將作為變量傳遞給新創(chuàng)建的流程實(shí)例。條件啟動(dòng)事件的XML表示是帶有conditionalEventDefinition子元素的普通啟動(dòng)事件聲明。
可選:將variableName屬性添加到conditionalEventDefinition允許指定一個(gè)變量名,在該變量名上,條件事件的條件應(yīng)專(zhuān)門(mén)計(jì)算。
<startEvent id="conditionalStartEvent"> <conditionalEventDefinition camunda:variableName="temperature"> <condition type="tFormalExpression">${temperature > 20}</condition> </conditionalEventDefinition></startEvent>
2、Conditional Boundary Event(邊界條件事件)
條件邊界事件(Conditional Boundary Event)就像一個(gè)觀察者,如果滿(mǎn)足一個(gè)特定的條件,它就會(huì)被觸發(fā)。中斷條件事件和非中斷條件事件是有區(qū)別的。缺省情況下為中斷事件。非中斷事件導(dǎo)致原始活動(dòng)未被中斷,實(shí)例仍處于活動(dòng)狀態(tài)。相反,創(chuàng)建了一個(gè)額外的執(zhí)行路徑,采用事件的傳出轉(zhuǎn)換。一個(gè)不中斷的條件事件可以被觸發(fā)多次,只要它所附加的活動(dòng)是活動(dòng)的。
在非中斷條件事件的XML表示中,cancelActivity屬性被設(shè)置為false:
<boundaryEvent id="conditionalEvent" attachedToRef="taskWithCondition" cancelActivity="false"> <conditionalEventDefinition> <condition type="tFormalExpression">${var1 == 1}</condition> </conditionalEventDefinition></boundaryEvent>
參考:
https://docs.camunda.org/manual/7.15/reference/bpmn20/events/conditional-events/
?