项目构建
- 我使用的是7.20.0版本,初步构建的是一个简单购物流程,流程中的加入购物车、付款、物流发货流程使用了java和js两种外部任务
- 外部任务项目包括一个camunda-external-platform的java springboot外部项目和一个shopping-service-nodejs的node js项目
- Camunda提供了项目初始化构建的网址 构建网址
- 构建项目后,下载好相关依赖,配置好数据库,第一次启动,会自动初始化相关的数据库表
主项目介绍
- pom.xml 引入mysql依赖
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>3.1.1</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.camunda.bpm</groupId> <artifactId>camunda-bom</artifactId> <version>7.20.0</version> <scope>import</scope> <type>pom</type> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.camunda.bpm.springboot</groupId> <artifactId>camunda-bpm-spring-boot-starter-rest</artifactId> </dependency> <dependency> <groupId>org.camunda.bpm.springboot</groupId> <artifactId>camunda-bpm-spring-boot-starter-webapp</artifactId> </dependency> <dependency> <groupId>org.camunda.bpm</groupId> <artifactId>camunda-engine-plugin-spin</artifactId> </dependency> <dependency> <groupId>org.camunda.spin</groupId> <artifactId>camunda-spin-dataformat-all</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> <!-- GraalVM JavaScript Engine --> <dependency> <groupId>org.graalvm.js</groupId> <artifactId>js</artifactId> <version>21.3.3</version> </dependency> </dependencies>
- application.yml配置
server: port: 8080 servlet: context-path: /engine-rest spring: datasource: url: jdbc:mysql://127.0.0.1:3306/camunda?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&&serverTimezone=Asia/Shanghai driver-class-name: com.mysql.cj.jdbc.Driver username: camunda password: 123456a camunda.bpm.admin-user: id: admin password: 123456
-
项目目录截图
-
processes.xml配置后,如果bpmn文件有改动,项目重新启动后会进行部署或版本更新
<?xml version="1.0" encoding="UTF-8"?> <process-application xmlns="http://www.camunda.org/schema/1.0/ProcessApplication" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <process-archive> <process-engine>default</process-engine> <properties> <property name="isDeleteUponUndeploy">false</property> <property name="isScanForProcessDefinitions">true</property> </properties> </process-archive> </process-application>
流程设计图
- 流程整体配置的Name及Id配置截图
- 加入购物车外部任务配置截图
- 付款外部任务配置截图
- 物流发货外部任务截图
java外部任务介绍
- 使用的是springboot架构,pom.xml配置
<description>camunda-external-platform</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>17</java.version> <camunda-external.version>7.18.0</camunda-external.version> <jaxb-api.version>2.3.1</jaxb-api.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--<dependency>--> <!-- <groupId>org.camunda.bpm.springboot</groupId>--> <!-- <artifactId>camunda-bpm-spring-boot-starter-external-task-client</artifactId>--> <!-- <!–<version>${camunda-external.version}</version>–>--> <!--</dependency>--> <dependency> <groupId>org.camunda.bpm.springboot</groupId> <artifactId>camunda-bpm-spring-boot-starter-external-task-client</artifactId> <version>7.18.0</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.30</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
- 项目目录结构
- 加入购物车外部任务和物流发货外部认为监听代码
import jakarta.annotation.PostConstruct; import lombok.extern.slf4j.Slf4j; import org.camunda.bpm.client.ExternalTaskClient; import org.camunda.bpm.engine.variable.VariableMap; import org.camunda.bpm.engine.variable.Variables; import org.springframework.stereotype.Component; /** * @author : CZJ * @date : 2024-03-18 23:14 **/ @Slf4j @Component public class SubScribeTask { private final static String url = "http://localhost:8080/engine-rest/engine-rest"; private ExternalTaskClient client = null; private ExternalTaskClient getClient() { if (client == null) { client = ExternalTaskClient.create().baseUrl(url).build(); } return client; } @PostConstruct public void handleShoppingCart() { getClient().subscribe("shopping_cart").processDefinitionKey("camunda-shopping").lockDuration(2000).handler(((externalTask, externalTaskService) -> { log.info("订阅到加入购物车任务"); VariableMap goodVariables = Variables.createVariables(); goodVariables.putValue("size", 1); goodVariables.putValue("count", 3); externalTaskService.complete(externalTask, goodVariables); })).open(); } @PostConstruct public void handleLogisticsShipment() { getClient().subscribe("logistics_shipment").processDefinitionKey("camunda-shopping").lockDuration(2000).handler(((externalTask, externalTaskService) -> { Object toWhere = externalTask.getVariable("to_where"); log.info("收到发货任务: 发往目的地 {}", toWhere); externalTaskService.complete(externalTask); })).open(); } }
-
application.yml文件,仅仅定义了server.port 端口,其他没有配置
nodeJs外部任务介绍
- 目录结构
- 付款外部任务代码
import { Client, logger ,Variables} from 'camunda-external-task-client-js' import open from 'open' // configuration for the Client: // - 'baseUrl': url to the Process Engine // - 'logger': utility to automatically log important events // - 'asyncResponseTimeout': long polling timeout (then a new request will be issued) const config = { baseUrl: 'http://127.0.0.1:8080/engine-rest/engine-rest', use: logger, asyncResponseTimeout: 10000 }; const client = new Client(config); // 订阅BPMN中付款 topic: 'pay',processDefinitionKey可以指定是哪个流程,可能其他流程也是相同topic client.subscribe( 'pay', { processDefinitionKey: "camunda-shopping" }, async function ({ task, taskService }) { // Put your business logic here // Get a process variable const size = task.variables.get('size'); const count = task.variables.get('count'); console.log(`顾客下单尺寸: ${size} 数量:'${count}'...`); const processVariables = new Variables() .set("to_where", "shanghai China"); // Complete the task try { await taskService.complete(task,processVariables); console.log('I completed my task successfully!!'); } catch (e) { console.error(`Failed completing my task, ${e}`); } } );
- yarn install后,执行node shopping-cart.js路径 即可运行
遇到的问题
曾遇到的问题,直接上问题错误代码
2024-03-29T22:53:19.853+08:00 ERROR 29484 --- [criptionManager] org.camunda.bpm.client : TASK/CLIENT-03001 Exception while fetching and locking task.
org.camunda.bpm.client.impl.EngineClientException: TASK/CLIENT-02001 Request 'POST http://localhost:8080/engine-rest/external-task/fetchAndLock HTTP/1.1' returned error: status code '404' - message: null
at org.camunda.bpm.client.impl.EngineClientLogger.exceptionWhileReceivingResponse(EngineClientLogger.java:30) ~[camunda-external-task-client-7.18.0.jar:7.18.0]
at org.camunda.bpm.client.impl.RequestExecutor.executeRequest(RequestExecutor.java:91) ~[camunda-external-task-client-7.18.0.jar:7.18.0]
at org.camunda.bpm.client.impl.RequestExecutor.postRequest(RequestExecutor.java:74) ~[camunda-external-task-client-7.18.0.jar:7.18.0]
at org.camunda.bpm.client.impl.EngineClient.fetchAndLock(EngineClient.java:83) ~[camunda-external-task-client-7.18.0.jar:7.18.0]
at org.camunda.bpm.client.topic.impl.TopicSubscriptionManager.fetchAndLock(TopicSubscriptionManager.java:136) ~[camunda-external-task-client-7.18.0.jar:7.18.0]
at org.camunda.bpm.client.topic.impl.TopicSubscriptionManager.acquire(TopicSubscriptionManager.java:102) ~[camunda-external-task-client-7.18.0.jar:7.18.0]
at org.camunda.bpm.client.topic.impl.TopicSubscriptionManager.run(TopicSubscriptionManager.java:88) ~[camunda-external-task-client-7.18.0.jar:7.18.0]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: org.camunda.bpm.client.exception.RestException: null
at org.camunda.bpm.client.impl.EngineRestExceptionDto.toRestException(EngineRestExceptionDto.java:52) ~[camunda-external-task-client-7.18.0.jar:7.18.0]
at org.camunda.bpm.client.impl.RequestExecutor$1.handleResponse(RequestExecutor.java:133) ~[camunda-external-task-client-7.18.0.jar:7.18.0]
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:223) ~[httpclient-4.5.13.jar:4.5.13]
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:165) ~[httpclient-4.5.13.jar:4.5.13]
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:140) ~[httpclient-4.5.13.jar:4.5.13]
at org.camunda.bpm.client.impl.RequestExecutor.executeRequest(RequestExecutor.java:88) ~[camunda-external-task-client-7.18.0.jar:7.18.0]
... 6 common frames omitted
解决:
这个问题就是我主项目的application.yml配置如下
server: port: 8080 servlet: context-path: /engine-rest#项目的访问地址为http://127.0.0.1:8080/engine-rest
外部任务的连接url就是http://127.0.0.1:8080/engine-rest/engine-rest