1 package org.onap.so.bpmn.common.workflow.service;
3 import java.util.ArrayList;
5 import org.camunda.bpm.engine.ProcessEngine;
6 import org.camunda.bpm.engine.RepositoryService;
7 import org.camunda.bpm.engine.RuntimeService;
8 import org.camunda.bpm.engine.migration.MigrationInstruction;
9 import org.camunda.bpm.engine.migration.MigrationPlan;
10 import org.camunda.bpm.engine.migration.MigrationPlanExecutionBuilder;
11 import org.camunda.bpm.engine.repository.ProcessDefinition;
12 import org.camunda.bpm.engine.runtime.ProcessInstance;
13 import org.camunda.bpm.engine.runtime.ProcessInstanceQuery;
14 import org.slf4j.Logger;
15 import org.slf4j.LoggerFactory;
16 import org.springframework.beans.factory.annotation.Autowired;
17 import org.springframework.beans.factory.annotation.Value;
18 import org.springframework.boot.context.event.ApplicationReadyEvent;
19 import org.springframework.context.event.EventListener;
20 import org.springframework.core.env.Environment;
21 import org.springframework.stereotype.Service;
24 public class AutoProcessInstanceMigrationService {
26 private static Logger logger = LoggerFactory.getLogger(AutoProcessInstanceMigrationService.class);
29 private Environment env;
31 protected ProcessEngine processEngine;
33 @Value("${migration.autoMigrationEnabled:false}")
34 private boolean autoMigrationEnabled;
36 private RuntimeService runtimeService;
37 private RepositoryService repositoryService;
38 private List<String> processDefinitionKeys;
40 @EventListener(ApplicationReadyEvent.class)
41 protected void executeAutoProcessInstanceMigrations() {
42 if (autoMigrationEnabled) {
43 runtimeService = processEngine.getRuntimeService();
44 repositoryService = processEngine.getRepositoryService();
45 for (ProcessDefinition definition : getProcessDefinitions()) {
46 for (ProcessDefinition procDefOld : getOldProcessDefinitions(definition.getKey(),
47 definition.getVersion())) {
48 migrate(procDefOld.getId(), definition.getId());
54 protected List<ProcessDefinition> getProcessDefinitions() {
56 List<ProcessDefinition> processDefinitions = new ArrayList<ProcessDefinition>();
57 processDefinitionKeys = env.getProperty("migration.processDefinitionKeys", List.class, new ArrayList<String>());
58 for (String key : processDefinitionKeys) {
59 processDefinitions.add(repositoryService.createProcessDefinitionQuery().processDefinitionKey(key)
60 .latestVersion().singleResult());
62 return processDefinitions;
65 private void migrate(String sourceProcessDefinitionId, String targetProcessDefinitionId) {
66 MigrationPlan migrationPlan =
67 runtimeService.createMigrationPlan(sourceProcessDefinitionId, targetProcessDefinitionId)
68 .mapEqualActivities().updateEventTriggers().build();
69 List<String> activityIds = new ArrayList<>();
71 for (MigrationInstruction instruction : migrationPlan.getInstructions()) {
72 activityIds.add(instruction.getSourceActivityId());
74 for (String activityId : activityIds) {
75 ProcessInstanceQuery activeProcessInstancesQuery = runtimeService.createProcessInstanceQuery()
76 .processDefinitionId(sourceProcessDefinitionId).activityIdIn(activityId).active();
77 if (!activeProcessInstancesQuery.list().isEmpty()) {
78 logger.info("Migrating {} process instance(s) from {} to {}",
79 Long.valueOf(activeProcessInstancesQuery.count()), sourceProcessDefinitionId,
80 targetProcessDefinitionId);
81 MigrationPlanExecutionBuilder migration =
82 runtimeService.newMigration(migrationPlan).processInstanceQuery(activeProcessInstancesQuery);
83 migration.executeAsync();
86 suspendEmptyProcessDefinition(sourceProcessDefinitionId);
89 private void suspendEmptyProcessDefinition(String sourceProcessDefinitionId) {
90 List<ProcessInstance> activeProcessInstances = runtimeService.createProcessInstanceQuery()
91 .processDefinitionId(sourceProcessDefinitionId).active().list();
92 if (activeProcessInstances.isEmpty()) {
93 repositoryService.suspendProcessDefinitionById(sourceProcessDefinitionId);
95 logger.info("Unable to migrate {} process instance(s) from {}",
96 Integer.valueOf(activeProcessInstances.size()), sourceProcessDefinitionId);
100 protected List<ProcessDefinition> getOldProcessDefinitions(String key, int version) {
101 List<ProcessDefinition> processDefinitions =
102 repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).list();
103 List<ProcessDefinition> oldProcessDefinitions = new ArrayList<>();
104 for (ProcessDefinition processDef : processDefinitions) {
105 if (!processDef.isSuspended() && (processDef.getVersion() != version)) {
106 oldProcessDefinitions.add(processDef);
109 return oldProcessDefinitions;