假设Spring Boot应用程序连接到一个数据库,该数据库创建了所有与Camunda相关的表,如dbo。ACT_HI_PROCINST dbo。ACT_HI_TASKINST dbo。ACT_RU_TASK dbo。ACT_RU_EXECUTION等等。有一个UI屏幕(Angular/React前端)接受BPMN &DMN文件将部署在Camunda数据库(可以是任何关系数据库)。这个(.bpmn/.dmn)应该作为其文件名的最新版本部署。
Camunda版本:7.13.0
用户可以通过从UI屏幕浏览文件系统来选择文件(假设UI文件浏览并选择了有效的.bpmn或.dmn)。用户必须将此选定文件作为REST调用中请求的一部分发送到Spring Boot应用程序,并部署.bpmn/。数据库中的DMN文件。
.bpmn或.dmn可以通过多种方式部署:
- via Camunda Modeler 通过使用@EnableProcessApplication注释和@SpringBootApplication,从/src/main/resources/bpmn/*自动部署应用程序
- 通过发送.bpmn/手动部署。通过REST调用到Spring Boot控制器,并使用Camunda的RepositoryService.createDeployment()
application.yaml:提供Camunda DB数据源配置,如url,用户名和密码以及Camunda管理员用户凭证,如-
camunda.bpm.admin-user:
id: admin
password: admin
camunda:
bpm:
history-level: audit
job-execution:
core-pool-size: 3
max-pool-size: 10
jpa:
enabled: true
handle-transaction: true
server:
port: 8091
spring:
application:
name: camunda-bpm-workflow-app
datasource:
url: jdbc:sqlserver://ABC250.abc.xyz:10010;databaseName=DevCamunda
username: DevUser
password: DevPass
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
hikari:
maximum-pool-size: 200
jpa:
hibernate:
ddl-auto: create
show-sql: false
properties:
hibernate:
format_sql: true
dialect: org.hibernate.dialect.SQLServerDialect
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
pom.xml:camunda-bpm-spring-boot-startercamunda-bpm-spring-boot-starter-webappcamunda-bpm-spring-boot-starter-rest
Auto-deployment: @EnableProcessApplication: Spring启动应用启动自动部署/src/main/resources/bpmn/*
- 使用@EnableProcessApplication注释将Spring Boot应用程序转换为Camunda进程应用程序,而不扩展任何超类。
- 在Spring Boot应用程序中,这个注释有助于将资源链接到流程引擎。
- 禁用springprocessengineeconfiguration自动部署功能
- 启用从/src/main/resources/META-INF/processes.xml自动部署
- processes.xml—是资源扫描的指示器。 我们可以在bmpn文件夹中有。bpmn和。dmn文件,例如-/src/main/resources/bpmn/xyz。bpmn或/src/main/resources/bpmn/abc.dmn
- 在启动Spring Boot应用程序时,如果在位置/src/main/resources/bpmn/*中做了任何更改,所有的。bpmn和。dmn文件将被自动部署。
手动部署:通过发送。bpmn/。通过REST调用Spring Boot控制器并使用Camunda的RepositoryService.createDeployment(),从前端UI获取dmn文件。部署成功后,可以使用SQL:
在数据库中找到新的部署ID。SELECT
ID_,
NAME_,
DEPLOY_TIME_,
SOURCE_,
TENANT_ID_
FROM
dbo.ACT_RE_DEPLOYMENT
ORDER BY
DEPLOY_TIME_ DESC
主类:
import org.camunda.bpm.spring.boot.starter.annotation.EnableProcessApplication;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableProcessApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
REST控制器端点:要部署在数据库中的Camunda BPMN或DMN文件将被其他端点作为meditype . multipart_form_data_value使用。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.abc.workflow.dto.CamundaDeployResponse;
import com.abc.workflow.service.CamundaDeployService;
import lombok.extern.slf4j.Slf4j;
@RestController("/camunda")
public class CamundaDeployController {
@Autowired
private CamundaDeployService camundaDeployService;
@PostMapping(value = "/deploy", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<CamundaDeployResponse> deploy(@RequestParam("file") MultipartFile file) {
return ResponseEntity.ok(camundaDeployService.deploy(file));
}
}
服务接口:
import org.springframework.web.multipart.MultipartFile;
import com.abc.workflow.dto.CamundaDeployResponse;
public interface CamundaDeployService {
CamundaDeployResponse deploy(MultipartFile file);
}
服务实现类:RepositoryService——提供对流程定义和部署的存储库的访问的服务。
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.camunda.bpm.engine.RepositoryService;
import org.camunda.bpm.engine.repository.DeploymentWithDefinitions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.abc.workflow.dto.CamundaDeployRequestDto;
import com.abc.workflow.dto.CamundaDeployResponse;
import com.abc.workflow.service.CamundaDeployService;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class CamundaDeployServiceImpl implements CamundaDeployService {
@Autowired
private RepositoryService repositoryService;
@Override
public CamundaDeployResponse deploy(MultipartFile file) {
CamundaDeployResponse camundaDeployResponse = new CamundaDeployResponse();
String orgFileName = file.getOriginalFilename();
log.info("Camunda file to be deployed [{}]", orgFileName);
if(orgFileName.endsWith(".bpmn") || orgFileName.endsWith(".dmn")) {
try {
log.info("Camunda Deployment START : [{}]", orgFileName);
DeploymentWithDefinitions d = null;
d = repositoryService.createDeployment().addInputStream(orgFileName, file.getInputStream()).name(orgFileName).deployWithResult();
camundaDeployResponse.setSuccessMessage("Camunda Deployment SUCCESS ["+orgFileName+"] : Deployment ID ["+d.getId()+"]");
log.info("Camunda Deployment SUCCESS [{}] : Deployment ID [{}]", orgFileName, d.getId());
}
catch (IOException e) {
camundaDeployResponse.setErrorMessage("Camunda Deployment FAILED : "+e.getMessage());
log.error("Camunda Deployment FAILED [{}]: {}", orgFileName, e.getMessage());
e.printStackTrace();
}
}
else {
camundaDeployResponse.setErrorMessage("Not a valid Camunda file (BPMN/DMN)");
log.error("Not a valid Camunda file (BPMN/DMN)");
}
return camundaDeployResponse;
}
}