camunda_17_external_task
external task 是 Camunda 中Service task设计非常好的一种实现, 最大程度地做到了和流程引擎的解耦. 如果我们的流程是全自动的, 甚至可以完全使用 external task实现整个流程业务处理.
本文目的
- 学习 SpringBoot 版external-task-client 的使用
- 学习普通版 external-task-client 的使用
bpmn 流程
非常简单的流程图, 仅仅包含一个Service task, 实现类型选 External.
流程bpmn 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_0j7gdmg" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.3.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.17.0">
<bpmn:process id="loan_process" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_011etxb</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_011etxb" sourceRef="StartEvent_1" targetRef="Activity_1dbhjra" />
<bpmn:endEvent id="Event_1weohz6">
<bpmn:incoming>Flow_0qtyon7</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_0qtyon7" sourceRef="Activity_1dbhjra" targetRef="Event_1weohz6" />
<bpmn:serviceTask id="Activity_1dbhjra" name="creditScoreChecker" camunda:type="external" camunda:topic="creditScoreChecker">
<bpmn:incoming>Flow_011etxb</bpmn:incoming>
<bpmn:outgoing>Flow_0qtyon7</bpmn:outgoing>
</bpmn:serviceTask>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="loan_process">
<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_1weohz6_di" bpmnElement="Event_1weohz6">
<dc:Bounds x="432" y="99" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_103uall_di" bpmnElement="Activity_1dbhjra">
<dc:Bounds x="270" y="77" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_011etxb_di" bpmnElement="Flow_011etxb">
<di:waypoint x="215" y="117" />
<di:waypoint x="270" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0qtyon7_di" bpmnElement="Flow_0qtyon7">
<di:waypoint x="370" y="117" />
<di:waypoint x="432" y="117" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>
Post 请求测试脚本:
POST http://localhost:8080/engine-rest/process-definition/key/loan_process/start HTTP/1.1
Content-Type: application/json
{
"variables": {
"amount": {
"value":555,
"type":"long"
},
"item": {
"value": "item-xyz"
}
}
}
SpringBoot 版 client 测试程序
pom.xml
项目只要是标准的SpringBoot Web 项目即可, 增加下面依赖:
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter-external-task-client</artifactId>
<version>7.17.0</version>
</dependency>
application.yaml
在application.yaml 文件中声明要监听的camunda Rest API 服务器, 并设定订阅的topic, 一个项目可以订阅多个topic.
camunda.bpm.client:
base-url: http://localhost:8080/engine-rest
async-response-timeout: 1000 # Defines the maximum duration of the long-polling request
worker-id: spring-boot-client # Identifies the worker towards the Engine
#basic-auth: # Configure if REST API is secured with basic authentication
# username: demo
# password: demo
subscriptions:
creditScoreChecker: # This topic name must match the respective `@ExternalTaskSubscription`
process-definition-key: loan_process # Filters for External Tasks of this key
include-extension-properties: true
variable-names: defaultScore
lock-duration: 10000 # Defines for how long the External Tasks are locked until they can be fetched again
External task 监听类
@Configuration
@ExternalTaskSubscription("creditScoreChecker")
public class CreditScoreCheckerHandler implements ExternalTaskHandler {
@Override
public void execute(ExternalTask externalTask, ExternalTaskService externalTaskService) {
// add your business logic here
System.out.println("CreditScoreCheckerHandler done");
Map<String, Object> variables = new HashMap<>();
variables.put("approved", true);
externalTaskService.complete(externalTask,variables);
}
}
普通 Java jar 版client 测试程序
官方项目主页
我们的项目只要是标准的 Maven 项目即可, 简单使用 camunda-external-task-client 即可改造为 Listerner 后台程序.
pom.xml
增加下面依赖:
<dependency>
<groupId>org.camunda.bpm</groupId>
<artifactId>camunda-external-task-client</artifactId>
<version>7.17.0</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
External task 监听类
public class ExternalTaskTest {
private final static Logger logger = Logger.getLogger(ExternalTaskTest.class.getName());
public static void main(String[] args) {
logger.info("ExternalTaskClient setup");
// bootstrap the client
ExternalTaskClient client = ExternalTaskClient.create()
.baseUrl("http://localhost:8080/engine-rest")
.workerId("java-client")
.asyncResponseTimeout(1000).build();
// subscribe to the topic
client.subscribe("creditScoreChecker").lockDuration(10000).handler((externalTask, externalTaskService) -> {
Map<String, Object> variables = new HashMap<>();
variables.put("approved", true);
// complete the external task
externalTaskService.complete(externalTask, variables);
System.out.println("The External Task " + externalTask.getId() + " has been completed!");
}).open();
logger.info("Listening topics...");
}
}