外部任务:即任务可以在外部系统进行审批。

一:pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>springboot-camunda-client</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-camunda</name>
    <description>springboot-camunda</description>

    <properties>
        <camunda.spring-boot.version>7.17.0</camunda.spring-boot.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </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.spring-boot.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.32</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

二:application.yml

server:
  port: 8081

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/camunda?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&&nullCatalogMeansCurrent=true
    username: root
    password: root123
    driver-class-name: com.mysql.cj.jdbc.Driver

camunda:
  bpm:
    client:
      base-url: http://localhost:8080/engine-rest
      #一次最多拉取的任务数量
      max-tasks: 1
      #工作节点id
      worker-id: springboot-camunda-client
      # 长轮询挂起时间间隔,默认20s
      async-response-timeout: 20000
      #全局订阅topic的上锁时间,单位毫秒,锁住期间其它订阅者获取不到
      #这个配置时间要大于业务处理时间
      lock-duration: 60000
      basic-auth:
        username: admin
        password: 123456

三:bpmn

Camunda外部任务_maven

四:config

@Configuration
public class CamundaHandlerConfig {

    @Bean
    @ExternalTaskSubscription(topicName = "demo_external_task_topic",
            processDefinitionKeyIn = {"ExternalTaskProcess"},
            lockDuration = 5000)
    public ExternalTaskHandler externalTaskHandler() {
        return (ExternalTask externalTask, ExternalTaskService externalTaskService) -> {
            boolean flag = (boolean)externalTask.getVariable("flag");
            // 处理业务逻辑...
            if (!flag) {
                externalTaskService.handleFailure(externalTask, "error msg...", "error detail 异常堆栈信息等...", 0, 5000);
            }
            VariableMap variables = Variables.createVariables();
            variables.put("code", "ok");
            externalTaskService.complete(externalTask, variables);
        };
    }
}

客户端代码通过rest api通过长轮询Long Polling的方式去拉取任务,发送一次请求,如果没有任务返回会将请求挂起,进行等待(等待时间可以配置),超过等待时间再进行相应。这样就缓解了不停的循环去拉取。

Camunda外部任务_xml_02

五:启动流程

repositoryService.createDeployment()
       .name("外部任务流程")
       .addClasspathResource("bpmn/diagram_2.bpmn")
       .deploy();

identityService.setAuthenticatedUserId("huihui");
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("ExternalTaskProcess");

Task task = taskService.createTaskQuery()
       .processInstanceId(processInstance.getId())
       .singleResult();
Map<String,Object> variables = new HashMap<>();
variables.put("flag", true);
taskService.complete(task.getId(), variables);

Camunda外部任务_spring_03

六:获取外部任务设置的变量

下一个节点:经理审批 获取上一个外部任务设置的流程变量。

Task task = taskService.createTaskQuery()
      .processInstanceId("4f8c5081-aec5-11ee-b9f6-92e97825df95")
       .singleResult();
Map<String, Object> variables = taskService.getVariables(task.getId());
System.out.println(variables);

Camunda外部任务_spring_04