文章目录
- 开始
- 脚本任务(ScriptTask)
- 发送任务(SendTask)
- 接收任务(ReceiveTask)
- 流程图xml
开始
前面我们已经介绍了Camunda最基本的操作和常见的监听器,如果不熟悉Camunda,可以先看一下,方便搭建环境,亲手测试。
Camunda组件与服务与基本操作
Camunda中强大的监听服务
本篇将简单介绍Camunda的Script Task、Send Task、Receive Task。
熟悉这些Task,可以帮我们更好理解Camunda流程。
脚本任务(ScriptTask)
Format:JavaScript
Type:Inline script
execution.setVariable("pa", "javascript");
如果启动流程发现:Can’t find scripting engine for ‘javascript’: scriptEngine is null
可以加入下面的依赖:
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js</artifactId>
<version>23.0.3</version>
</dependency>
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js-scriptengine</artifactId>
<version>23.0.3</version>
</dependency>
除了JavaScript,还可以使用Python、Groovy、Ruby等,得添加相关的依赖。
尽量不要在脚本中实现复杂的逻辑,调试起来比较麻烦,排查问题也痛苦。
发送任务(SendTask)
发送任务Send Task和我们之前介绍的Service Task差不多。
可以配置为Java Class然后实现JavaDelegate类。
在实现类中可以获取相关信息,例如:上一个脚本节点设置的参数。
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
public class SendTaskJavaDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution delegateExecution) {
System.out.println(SendTaskJavaDelegate.class.getName() + "--start");
System.out.println("获取参数:" + delegateExecution.getVariable("pa"));
System.out.println("getId:" + delegateExecution.getId());
System.out.println("getProcessInstanceId:" + delegateExecution.getProcessInstanceId());
System.out.println("getActivityInstanceId:" + delegateExecution.getActivityInstanceId());
System.out.println("getCurrentActivityId:" + delegateExecution.getCurrentActivityId());
System.out.println("getCurrentActivityName:" + delegateExecution.getCurrentActivityName());
System.out.println("getProcessBusinessKey:" + delegateExecution.getProcessBusinessKey());
System.out.println("getProcessDefinitionId:" + delegateExecution.getProcessDefinitionId());
System.out.println("getBusinessKey:" + delegateExecution.getBusinessKey());
System.out.println("getEventName:" + delegateExecution.getEventName());
System.out.println(SendTaskJavaDelegate.class.getName() + "--end");
}
}
com.example.workflow.delegate.SendTaskJavaDelegate--start
获取参数:javascript
getId:1fbafcb1-c0ac-11ee-b7bf-00ffe7687986
getProcessInstanceId:1fbafcb1-c0ac-11ee-b7bf-00ffe7687986
getActivityInstanceId:Activity_0xcgnyl:2053ba46-c0ac-11ee-b7bf-00ffe7687986
getCurrentActivityId:Activity_0xcgnyl
getCurrentActivityName:发送任务
getProcessBusinessKey:task0002
getProcessDefinitionId:Process_0btcu4b:2:ca1b15a6-c0aa-11ee-8ced-00ffe7687986
getBusinessKey:task0002
getEventName:null
com.example.workflow.delegate.SendTaskJavaDelegate--end
接收任务(ReceiveTask)
接收任务节点可以用来阻塞节点往下执行,比如等一个外部任务完成。
有例如,一个节点必须依赖另一个节点完成,就可以在节点前添加一个接收任务节点,等其他节点完成之后,通过接收任务节点继续往下走。
可以根据activityId来查询任务executionId
@Test
public void queryExecutionId() {
String activityId = "Activity_1nu3d7a";
Execution execution = runtimeService.createExecutionQuery()
.activityId(activityId).singleResult();
System.out.println(execution);
}
select * from act_hi_actinst where ACT_ID_ ='Activity_1nu3d7a';
然后通过executionId来通知接收消息的节点,不用等了,可以到下一个节点了。
@Test
public void signal() {
String executionId = "2054cbb7-c0ac-11ee-b7bf-00ffe7687986";
runtimeService.signal(executionId);
}
除了signal,还可以correlateMessage来通知Receive Task完成:
@Test
public void correlateMessage() {
String messageName = "Message_0ud6hg1";
runtimeService.correlateMessage(messageName);
}
消息也可以是中文:
@Test
public void correlate() {
String messageName = "消息2";
MessageCorrelationBuilder messageCorrelation =
runtimeService.createMessageCorrelation(messageName);
messageCorrelation.correlate();
}
完整的测试用例:
import jakarta.annotation.Resource;
import org.camunda.bpm.engine.RuntimeService;
import org.camunda.bpm.engine.runtime.Execution;
import org.camunda.bpm.engine.runtime.MessageCorrelationBuilder;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class ApplicationTest {
@Resource
private RuntimeService runtimeService;
@Test
public void queryExecutionId() {
String activityId = "Activity_1nu3d7a";
Execution execution = runtimeService.createExecutionQuery()
.activityId(activityId).singleResult();
System.out.println(execution);
}
@Test
public void signal() {
String executionId = "2054cbb7-c0ac-11ee-b7bf-00ffe7687986";
runtimeService.signal(executionId);
}
@Test
public void correlateMessage() {
String messageName = "Message_0ud6hg1";
runtimeService.correlateMessage(messageName);
}
@Test
public void correlate() {
String messageName = "消息2";
MessageCorrelationBuilder messageCorrelation =
runtimeService.createMessageCorrelation(messageName);
messageCorrelation.correlate();
}
}
记得添加依赖,不要加错了,不然执行不了。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
流程图xml
<?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_18zyppt" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.19.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.20.0">
<bpmn:process id="Process_0btcu4b" name="任务测试" isExecutable="true" camunda:historyTimeToLive="180">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_0x6f2m3</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_0x6f2m3" sourceRef="StartEvent_1" targetRef="Activity_08nl9jt" />
<bpmn:scriptTask id="Activity_08nl9jt" name="脚本任务" scriptFormat="JavaScript">
<bpmn:incoming>Flow_0x6f2m3</bpmn:incoming>
<bpmn:outgoing>Flow_1kkp455</bpmn:outgoing>
<bpmn:script>execution.setVariable("pa", "javascript");</bpmn:script>
</bpmn:scriptTask>
<bpmn:sequenceFlow id="Flow_1kkp455" sourceRef="Activity_08nl9jt" targetRef="Activity_0xcgnyl" />
<bpmn:sendTask id="Activity_0xcgnyl" name="发送任务" camunda:class="com.example.workflow.delegate.SendTaskJavaDelegate">
<bpmn:incoming>Flow_1kkp455</bpmn:incoming>
<bpmn:outgoing>Flow_0gw8gq5</bpmn:outgoing>
</bpmn:sendTask>
<bpmn:sequenceFlow id="Flow_0gw8gq5" sourceRef="Activity_0xcgnyl" targetRef="Activity_1nu3d7a" />
<bpmn:receiveTask id="Activity_1nu3d7a" name="接收任务" messageRef="Message_13j3si4">
<bpmn:incoming>Flow_0gw8gq5</bpmn:incoming>
<bpmn:outgoing>Flow_09l62nk</bpmn:outgoing>
</bpmn:receiveTask>
<bpmn:sequenceFlow id="Flow_09l62nk" sourceRef="Activity_1nu3d7a" targetRef="Activity_1oedt3n" />
<bpmn:userTask id="Activity_1oedt3n" name="用户任务">
<bpmn:incoming>Flow_09l62nk</bpmn:incoming>
<bpmn:outgoing>Flow_1yorrvs</bpmn:outgoing>
</bpmn:userTask>
<bpmn:endEvent id="Event_1o1zu4l">
<bpmn:incoming>Flow_1yorrvs</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_1yorrvs" sourceRef="Activity_1oedt3n" targetRef="Event_1o1zu4l" />
</bpmn:process>
<bpmn:message id="Message_3n3k1s8" name="消息1" />
<bpmn:message id="Message_13j3si4" name="消息2" />
<bpmn:message id="Message_0ud6hg1" name="Message_0ud6hg1" />
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_0btcu4b">
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="149" y="99" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0slvat5_di" bpmnElement="Activity_08nl9jt">
<dc:Bounds x="220" y="77" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1obj6uy_di" bpmnElement="Activity_0xcgnyl">
<dc:Bounds x="360" y="77" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1gz5v9p_di" bpmnElement="Activity_1nu3d7a">
<dc:Bounds x="250" y="210" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0k177dl_di" bpmnElement="Activity_1oedt3n">
<dc:Bounds x="410" y="210" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1o1zu4l_di" bpmnElement="Event_1o1zu4l">
<dc:Bounds x="572" y="232" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_0x6f2m3_di" bpmnElement="Flow_0x6f2m3">
<di:waypoint x="185" y="117" />
<di:waypoint x="220" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1kkp455_di" bpmnElement="Flow_1kkp455">
<di:waypoint x="320" y="117" />
<di:waypoint x="360" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0gw8gq5_di" bpmnElement="Flow_0gw8gq5">
<di:waypoint x="410" y="157" />
<di:waypoint x="410" y="184" />
<di:waypoint x="300" y="184" />
<di:waypoint x="300" y="210" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_09l62nk_di" bpmnElement="Flow_09l62nk">
<di:waypoint x="350" y="250" />
<di:waypoint x="410" y="250" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1yorrvs_di" bpmnElement="Flow_1yorrvs">
<di:waypoint x="510" y="250" />
<di:waypoint x="572" y="250" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>