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() {
55 List<ProcessDefinition> processDefinitions = new ArrayList<ProcessDefinition>();
56 processDefinitionKeys = env.getProperty("migration.processDefinitionKeys", List.class, new ArrayList<String>());
57 for (String key : processDefinitionKeys) {
58 processDefinitions.add(repositoryService.createProcessDefinitionQuery().processDefinitionKey(key)
59 .latestVersion().singleResult());
61 return processDefinitions;
64 private void migrate(String sourceProcessDefinitionId, String targetProcessDefinitionId) {
65 MigrationPlan migrationPlan =
66 runtimeService.createMigrationPlan(sourceProcessDefinitionId, targetProcessDefinitionId)
67 .mapEqualActivities().updateEventTriggers().build();
68 List<String> activityIds = new ArrayList<>();
70 for (MigrationInstruction instruction : migrationPlan.getInstructions()) {
71 activityIds.add(instruction.getSourceActivityId());
73 for (String activityId : activityIds) {
74 ProcessInstanceQuery activeProcessInstancesQuery = runtimeService.createProcessInstanceQuery()
75 .processDefinitionId(sourceProcessDefinitionId).activityIdIn(activityId).active();
76 if (!activeProcessInstancesQuery.list().isEmpty()) {
77 logger.info("Migrating {} process instance(s) from {} to {}",
78 Long.valueOf(activeProcessInstancesQuery.count()), sourceProcessDefinitionId,
79 targetProcessDefinitionId);
80 MigrationPlanExecutionBuilder migration =
81 runtimeService.newMigration(migrationPlan).processInstanceQuery(activeProcessInstancesQuery);
82 migration.executeAsync();
85 suspendEmptyProcessDefinition(sourceProcessDefinitionId);
88 private void suspendEmptyProcessDefinition(String sourceProcessDefinitionId) {
89 List<ProcessInstance> activeProcessInstances = runtimeService.createProcessInstanceQuery()
90 .processDefinitionId(sourceProcessDefinitionId).active().list();
91 if (activeProcessInstances.isEmpty()) {
92 repositoryService.suspendProcessDefinitionById(sourceProcessDefinitionId);
94 logger.info("Unable to migrate {} process instance(s) from {}",
95 Integer.valueOf(activeProcessInstances.size()), sourceProcessDefinitionId);
99 protected List<ProcessDefinition> getOldProcessDefinitions(String key, int version) {
100 List<ProcessDefinition> processDefinitions =
101 repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).list();
102 List<ProcessDefinition> oldProcessDefinitions = new ArrayList<>();
103 for (ProcessDefinition processDef : processDefinitions) {
104 if (!processDef.isSuspended() && (processDef.getVersion() != version)) {
105 oldProcessDefinitions.add(processDef);
108 return oldProcessDefinitions;