34. Integrated Workflow Activity for Spring Cloud 2.x

Workflow is very common in projects, so here are two diagrams:

First:

Second:

Explain the above two pictures:

Assume these two diagrams are flowcharts of Chinese brothers'vacations

Components of the graph:

Characters: Fan Bingbing, Feng Xiaogang, Wang Zhongjun

Events (Actions): Leave, Approve, Disapprove

Workflow: is the "automation of part or whole of a business process in a computer application environment". It mainly resolves the problem of "automating the process of transferring documents, information or tasks among multiple participants according to a predefined rule to achieve an expected business goal, or to promote the realization of this goal."Common workflow engines on the market today include jbpm, activiti, and OSWorkflow OSWorkflow.

1. New project sc-activiti, corresponding pom.xml file is as follows

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>

        <groupId>com.sc</groupId>
        <artifactId>sc-activiti</artifactId>
        <version>0.0.1-SNAPSHOT</version>

        <name>sc-activiti-drools</name>
        <!-- FIXME change it to the project's website -->
        <url>http://www.example.com</url>

        <properties>
                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                <maven.compiler.source>1.8</maven.compiler.source>
                <maven.compiler.target>1.8</maven.compiler.target>
        </properties>

        <parent>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>2.0.4.RELEASE</version>
        </parent>

        <dependencyManagement>
                <dependencies>
                        <dependency>
                                <groupId>org.springframework.cloud</groupId>
                                <artifactId>spring-cloud-dependencies</artifactId>
                                <version>Finchley.RELEASE</version>
                                <type>pom</type>
                                <scope>import</scope>
                        </dependency>

                </dependencies>
        </dependencyManagement>

        <dependencies>
                <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-web</artifactId>
                </dependency>

                <dependency>
                        <groupId>org.activiti</groupId>
                        <artifactId>activiti-spring-boot-starter-basic</artifactId>
                        <version>5.22.0</version>
                </dependency>

                <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-data-jpa</artifactId>
                </dependency>

                <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-thymeleaf</artifactId>
                </dependency>

                <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <scope>runtime</scope>
                </dependency>

                <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-jdbc</artifactId>
                </dependency>

                <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-test</artifactId>
                        <scope>test</scope>
                </dependency>

        </dependencies>

        <build>
                <pluginManagement><!-- lock down plugins versions to avoid using Maven 
                                defaults (may be moved to parent pom) -->
                        <plugins>
                                <plugin>
                                        <artifactId>maven-clean-plugin</artifactId>
                                        <version>3.0.0</version>
                                </plugin>
                                <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
                                <plugin>
                                        <artifactId>maven-resources-plugin</artifactId>
                                        <version>3.0.2</version>
                                </plugin>
                                <plugin>
                                        <artifactId>maven-compiler-plugin</artifactId>
                                        <version>3.7.0</version>
                                </plugin>
                                <plugin>
                                        <artifactId>maven-surefire-plugin</artifactId>
                                        <version>2.20.1</version>
                                </plugin>
                                <plugin>
                                        <artifactId>maven-jar-plugin</artifactId>
                                        <version>3.0.2</version>
                                </plugin>
                                <plugin>
                                        <artifactId>maven-install-plugin</artifactId>
                                        <version>2.5.2</version>
                                </plugin>
                                <plugin>
                                        <artifactId>maven-deploy-plugin</artifactId>
                                        <version>2.8.2</version>
                                </plugin>
                        </plugins>
                </pluginManagement>
        </build>
</project>

2. New profile application.yml

spring:
    datasource:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/sc?characterEncoding=utf8&useSSL=true
        username: root
        password: root
    activiti:
        check-process-definitions: false
    jpa:
        properties:
            hibernate:
                hbm2ddl:
                    auto: update
    show-sql: true

server:
    port: 8081
    context-path: /
    session:
        timeout: 10
    tomcat:
        uri-encoding: UTF-8

3. Create a new vacation process file holiday.bpmn

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
    <process id="demo2" name="My process" isExecutable="true">
        <startEvent id="startevent1" name="Start"></startEvent>
        <userTask id="usertask1" name="leave"></userTask>
        <userTask id="usertask2" name="Approval"></userTask>
        <endEvent id="endevent1" name="End"></endEvent>
        <sequenceFlow id="flow1" sourceRef="usertask2" targetRef="endevent1"></sequenceFlow>
        <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>
        <sequenceFlow id="flow3" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
    </process>
    <bpmndi:BPMNDiagram id="BPMNDiagram_myProcess">
        <bpmndi:BPMNPlane bpmnElement="myProcess" id="BPMNPlane_myProcess">
            <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
                <omgdc:Bounds height="35.0" width="35.0" x="130.0" y="180.0"></omgdc:Bounds>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
                <omgdc:Bounds height="55.0" width="105.0" x="271.0" y="170.0"></omgdc:Bounds>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
                <omgdc:Bounds height="55.0" width="105.0" x="471.0" y="170.0"></omgdc:Bounds>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
                <omgdc:Bounds height="35.0" width="35.0" x="690.0" y="180.0"></omgdc:Bounds>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
                <omgdi:waypoint x="576.0" y="197.0"></omgdi:waypoint>
                <omgdi:waypoint x="690.0" y="197.0"></omgdi:waypoint>
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
                <omgdi:waypoint x="376.0" y="197.0"></omgdi:waypoint>
                <omgdi:waypoint x="471.0" y="197.0"></omgdi:waypoint>
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
                <omgdi:waypoint x="165.0" y="197.0"></omgdi:waypoint>
                <omgdi:waypoint x="271.0" y="197.0"></omgdi:waypoint>
            </bpmndi:BPMNEdge>
        </bpmndi:BPMNPlane>
    </bpmndi:BPMNDiagram>
</definitions>

The diagram for the corresponding bpmn file is as follows

4. New springboot startup class

package sc.ad;

import org.activiti.spring.boot.SecurityAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
public class ActivitiApp {
        public static void main(String[] args)
        {
                SpringApplication.run(ActivitiApp.class, args);
        }

}

Note: Be sure to ignore SecurityAutoConfiguration.class, otherwise the following exceptions will occur.

5. Create a new controller to start the vacation process

package sc.ad.controller;

import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ADController {

        @Autowired
        private RepositoryService repositoryService;

        @Autowired
        private RuntimeService runtimeService;

        @Autowired
        private TaskService taskService;

        @RequestMapping("/ad")
        public void firstDemo() {

                // Deploy process based on bpmn file
                Deployment deployment = repositoryService.createDeployment()
                                .addClasspathResource("holiday.bpmn").deploy();
                // Get process definition
                ProcessDefinition processDefinition = repositoryService
                                .createProcessDefinitionQuery()
                                .deploymentId(deployment.getId()).singleResult();
                // Start process definition and return process instance
                ProcessInstance pi = runtimeService
                                .startProcessInstanceById(processDefinition.getId());
                String processId = pi.getId();
                System.out.println("Process created successfully, current process instance ID: " + processId);

                Task task = taskService.createTaskQuery().processInstanceId(processId)
                                .singleResult();
                System.out.println("Before the first execution, the task name:" + task.getName());
                taskService.complete(task.getId());

                task = taskService.createTaskQuery().processInstanceId(processId)
                                .singleResult();
                System.out.println("Before the second execution, the task name:" + task.getName());
                taskService.complete(task.getId());

                task = taskService.createTaskQuery().processInstanceId(processId)
                                .singleResult();
                System.out.println("task by null´╝îTask completed:" + task);
        }
}

6. Start the project and verify it

View log, project started successfully

Visit: http://127.0.0.1:8081/ad

From the console, you can see a log of the approval of the leave process printed out.
From the data changes in the database, the following table structure is created

If you look at the corresponding tables using sql statements, you can see that the corresponding library tables leave the appropriate leave and approval record information.

Tags: Java Maven Spring Apache MySQL

Posted on Tue, 05 May 2020 01:39:58 -0700 by CiPH