A .bpmn or .dmn could be deployed in many ways:
- via Camunda Modeler
- via Spring Boot App startup auto-deploy from /src/main/resources/bpmn/* by using @EnableProcessApplication annotation along with @SpringBootApplication
- via Manual deployment by sending .bpmn/.dmn file from frontend UI via REST call to Spring Boot controller and using Camunda's RepositoryService.createDeployment()
application.yaml:
Provide Camunda DB datasource configurations like url, username and password along with Camunda admin user credential like -
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-starter
camunda-bpm-spring-boot-starter-webapp
camunda-bpm-spring-boot-starter-rest
Auto-deployment: @EnableProcessApplication: Spring Boot App startup auto-deploy from /src/main/resources/bpmn/*
- Turn your Spring Boot app into a Camunda process application using @EnableProcessApplication annotation without extending any super-classes.
- In the Spring Boot app, this annotation helps to link a resource to the process engine.
- Disables the SpringProcessEngineConfiguration auto-deploy feature
- Enables auto-deployment from /src/main/resources/META-INF/processes.xml
- processes.xml - is an indicator for resource scanning. This could be left empty.
- We can have .bpmn and .dmn files inside bmpn folder, example - /src/main/resources/bpmn/xyz.bmpn or /src/main/resources/bpmn/abc.dmn
- On startup of Spring Boot app, all .bpmn and .dmn files from location /src/main/resources/bpmn/* will be auto-deployed if any changes were done in them
Manual deployment: By sending .bpmn/.dmn file from fronend UI via REST call to Spring Boot controller and using Camunda's RepositoryService.createDeployment(). After deployment is successful, new deployment ID can be found in database using SQL:
SELECT
ID_,
NAME_,
DEPLOY_TIME_,
SOURCE_,
TENANT_ID_
FROM
dbo.ACT_RE_DEPLOYMENT
ORDER BY
DEPLOY_TIME_ DESC
Main Class:
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 Controller endpoint:
A Camunda BPMN or DMN file to be deployed in database will be consumed by the rest endpoint as MediaType.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));
}
}
Service Interface:
import org.springframework.web.multipart.MultipartFile;
import com.abc.workflow.dto.CamundaDeployResponse;
public interface CamundaDeployService {
CamundaDeployResponse deploy(MultipartFile file);
}
Service Implementation Class:
RepositoryService - Service providing access to the repository of process definitions and deployments.
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;
}
}