camunda 动态生成流程(代码生成xml)
camunda 动态创建流程XML
根据caunda-model的能力,将xml代码化,将用户数据的结构转换成xml,进而发布到camuda里。
代码是提供参考,已经验证完成,并在生产环境使用。
<dependency>
<groupId>org.camunda.bpm.model</groupId>
<artifactId>camunda-bpmn-model</artifactId>
<version>7.20.0-alpha3</version>
</dependency>
public class TestCamunda {
public static String url = "http://localhost:8080/engine-rest/deployment/create";
public static void main(String[] args) {
autoGenerateBPMN();
}
// 子流程
CamundaFlowCreateParam param = new CamundaFlowCreateParam("t1", "开始", "head");
CamundaFlowCreateParam param2 = new CamundaFlowCreateParam("t3", "调用", "user-service");
CamundaFlowCreateParam param5 = new CamundaFlowCreateParam("t6", "结束", "end");
param.setNextList(Lists.newArrayList(param2));
param2.setNextList(Lists.newArrayList(param5));
// 父流程
CamundaFlowCreateParam parent_param = new CamundaFlowCreateParam("t1", "开始", "head");
CamundaFlowCreateParam parent_param2 = new CamundaFlowCreateParam("t3", "调用-父", "call");
parent_param2.setSubProcessId("t-5");
CamundaFlowCreateParam parent_param5 = new CamundaFlowCreateParam("t6", "结束", "end");
parent_param.setNextList(Lists.newArrayList(parent_param2));
parent_param2.setNextList(Lists.newArrayList(parent_param5));
create(param,"测试",null,"测试");
// create(param,"t-9","工作台");
// create(parent_param,"t-6");
}
private static void create(CamundaFlowCreateParam param,String tenantId,String id,String name) {
ProcessBuilder processBuilder= null;
if(id == null){
processBuilder = Bpmn.createExecutableProcess();
}else {
processBuilder = Bpmn.createExecutableProcess(id);
}
processBuilder.name(name);
BpmnModelInstance instance = iterate(processBuilder, param,null).done();
Bpmn.validateModel(instance);
File file = null;
try {
file = File.createTempFile("bpmn-model-api-",".bpmn");
} catch (IOException e) {
e.printStackTrace();
}
Bpmn.writeModelToFile(file,instance);
MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<>();
multiValueMap.add("*", new FileSystemResource(file));
multiValueMap.add("tenant-id", tenantId);//租户ID
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, Object>> files = new HttpEntity<>(multiValueMap, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, files, String.class);
String responseStr= responseEntity.getBody();
JSONObject jsonObject = JSON.parseObject(responseStr);
System.out.println("成功" );
System.out.println(responseEntity.getBody() );
JSONObject jsonObject1= jsonObject.getJSONObject("deployedProcessDefinitions");
JSONObject d = (JSONObject) jsonObject1.values().stream().findFirst().get();
System.out.println(d.getString("key"));
}
// 重点方法,
private static AbstractFlowNodeBuilder iterate(ProcessBuilder processBuilder, CamundaFlowCreateParam p, AbstractFlowNodeBuilder point) {
if (p == null) {
return point;
}
switch (p.getType()) {
case "head":
point = processBuilder.startEvent(p.getId()).name(p.getName());
forcachListNest(processBuilder, p, point);
break;
case "end":
point = point.endEvent(p.getId()).name(p.getName());
break;
case "service":
ServiceTask serviceTask = point.serviceTask(p.getId()).name(p.getName()).getElement();
if(StringUtils.isNotBlank(p.getCamundaExpression()) ){
serviceTask.setCamundaExpression(p.getCamundaExpression());
}
point= serviceTask.builder();
forcachListNest(processBuilder, p, point);
break;
case "user-service":
point=point.userTask(p.getId()).name(p.getName());
forcachListNest(processBuilder, p, point);
break;
case "call":
CallActivity callActivity = point.callActivity(p.getId()).name(p.getName()).calledElement(p.getSubProcessId()).getElement();
CamundaIn param = callActivity.getModelInstance().newInstance(CamundaIn.class);
param.setCamundaVariables("all");
callActivity.builder().addExtensionElement(param);
point = callActivity.builder();
forcachListNest(processBuilder, p, point);
break;
case "gateway":
point = point.exclusiveGateway().id(p.getId()).name(p.getName());
point = point.condition("yes","#{fine}");
point = iterate(null,p.getNextList().get(0), point);
point = point.moveToLastGateway().condition("no","#{!fine}");
iterate(null,p.getNextList().get(1),point );
break;
default:
break;
}
System.out.println("p="+p);
return point;
}
private static void forcachListNest(ProcessBuilder processBuilder, CamundaFlowCreateParam p, AbstractFlowNodeBuilder point) {
List<CamundaFlowCreateParam> nextList= p.getNextList();
if(nextList != null){
for(CamundaFlowCreateParam param:nextList){
iterate(processBuilder, param, point);
}
}
}
}
@Data
public class CamundaFlowCreateParam {
// 流程id
private String id;
private String name;
// head end user_task service
private String type;
//子流程id
private String subProcessId;
private String camundaExpression;
private List<CamundaFlowCreateParam> nextList;
public CamundaFlowCreateParam(String id, String name, String type) {
this.id = id;
this.name = name;
this.type = type;
}
}