Skip to content

Commit

Permalink
Added testcases and fix when migrating an event sub process with two …
Browse files Browse the repository at this point in the history
…started sub processes
  • Loading branch information
basclaessen committed Aug 31, 2024
1 parent b94a0a5 commit 3a21d21
Show file tree
Hide file tree
Showing 4 changed files with 358 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -822,7 +822,10 @@ protected List<ExecutionEntity> createEmbeddedSubProcessAndExecutions(Collection

// Build the subProcess hierarchy
for (SubProcess subProcess : subProcessesToCreate.values()) {
if (!processInstanceChangeState.getCreatedEmbeddedSubProcesses().containsKey(subProcess.getId())) {
if (subProcess instanceof EventSubProcess) {
ExecutionEntity embeddedSubProcess = createEmbeddedSubProcessHierarchy(subProcess, defaultContinueParentExecution, subProcessesToCreate, movingExecutionIds, processInstanceChangeState, commandContext);
moveExecutionEntityContainer.addCreatedEventSubProcess(subProcess.getId(), embeddedSubProcess);
} else if (!processInstanceChangeState.getCreatedEmbeddedSubProcesses().containsKey(subProcess.getId())) {
ExecutionEntity embeddedSubProcess = createEmbeddedSubProcessHierarchy(subProcess, defaultContinueParentExecution, subProcessesToCreate, movingExecutionIds, processInstanceChangeState, commandContext);
processInstanceChangeState.addCreatedEmbeddedSubProcess(subProcess.getId(), embeddedSubProcess);
}
Expand All @@ -833,7 +836,9 @@ protected List<ExecutionEntity> createEmbeddedSubProcessAndExecutions(Collection
for (FlowElementMoveEntry flowElementMoveEntry : moveToFlowElements) {
FlowElement newFlowElement = flowElementMoveEntry.getNewFlowElement();
ExecutionEntity parentExecution;
if (newFlowElement.getSubProcess() != null && processInstanceChangeState.getCreatedEmbeddedSubProcesses().containsKey(newFlowElement.getSubProcess().getId())) {
if (newFlowElement.getSubProcess() != null && moveExecutionEntityContainer.getCreatedEventSubProcess(newFlowElement.getSubProcess().getId()) != null) {
parentExecution = moveExecutionEntityContainer.getCreatedEventSubProcess(newFlowElement.getSubProcess().getId());
} else if (newFlowElement.getSubProcess() != null && processInstanceChangeState.getCreatedEmbeddedSubProcesses().containsKey(newFlowElement.getSubProcess().getId())) {
parentExecution = processInstanceChangeState.getCreatedEmbeddedSubProcesses().get(newFlowElement.getSubProcess().getId());

} else if ((newFlowElement instanceof Task || newFlowElement instanceof CallActivity) && isFlowElementMultiInstance(newFlowElement) && !movingExecutions.get(0).isMultiInstanceRoot() &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public class MoveExecutionEntityContainer {
protected Map<String, FlowElementMoveEntry> currentActivityToNewElementMap = new LinkedHashMap<>();
protected Map<String, Map<String, Object>> flowElementLocalVariableMap = new HashMap<>();
protected List<String> newExecutionIds = new ArrayList<>();
protected Map<String, ExecutionEntity> createdEventSubProcesses = new HashMap<>();

public MoveExecutionEntityContainer(List<ExecutionEntity> executions, List<String> moveToActivityIds) {
this.executions = executions;
Expand Down Expand Up @@ -216,6 +217,14 @@ public void addNewExecutionId(String executionId) {
this.newExecutionIds.add(executionId);
}

public ExecutionEntity getCreatedEventSubProcess(String processDefinitionId) {
return createdEventSubProcesses.get(processDefinitionId);
}

public void addCreatedEventSubProcess(String processDefinitionId, ExecutionEntity executionEntity) {
createdEventSubProcesses.put(processDefinitionId, executionEntity);
}

public Map<String, Map<String, Object>> getFlowElementLocalVariableMap() {
return flowElementLocalVariableMap;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
*/
package org.flowable.engine.test.api.runtime.migration;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.List;

import org.assertj.core.groups.Tuple;
import org.flowable.engine.migration.ProcessInstanceMigrationBuilder;
import org.flowable.engine.migration.ProcessInstanceMigrationValidationResult;
Expand All @@ -23,10 +27,6 @@
import org.flowable.task.api.Task;
import org.junit.jupiter.api.Test;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

/**
* @author Bas Claessen
*/
Expand Down Expand Up @@ -167,6 +167,86 @@ public void testMigrateNonInterruptingEventRegistryEventSubProcessWithStartedSub
assertProcessEnded(processInstance.getId());
}

@Test
public void testMigrateNonInterruptingEventRegistryEventSubProcessWithTwoStartedSubProcess() {
//Deploy first version of the process
ProcessDefinition version1ProcessDef = deployProcessDefinition("my deploy",
"org/flowable/engine/test/api/runtime/migration/non-interrupting-eventregistry-event-subprocess.bpmn20.xml");

//Start an instance of the first version of the process for migration
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(version1ProcessDef.getKey());

//Deploy second version of the same process
ProcessDefinition version2ProcessDef = deployProcessDefinition("my deploy",
"org/flowable/engine/test/api/runtime/migration/non-interrupting-eventregistry-event-subprocess.bpmn20.xml");
assertThat(version1ProcessDef.getId()).isNotEqualTo(version2ProcessDef.getId());

//Trigger event to create first sub process
inboundEventChannelAdapter.triggerTestEvent();
//Trigger event to create second sub process
inboundEventChannelAdapter.triggerTestEvent();

//Confirm the state to migrate
List<Execution> executions = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId()).onlyChildExecutions().list();
assertThat(executions)
.extracting(Execution::getActivityId)
.containsExactlyInAnyOrder(
"processTask", "eventSubProcessStart", "eventSubProcess", "eventSubProcessTask", "eventSubProcess", "eventSubProcessTask"
);
assertThat(executions)
.extracting("processDefinitionId")
.containsOnly(version1ProcessDef.getId());
List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list();
assertThat(tasks)
.extracting(Task::getTaskDefinitionKey, Task::getProcessDefinitionId)
.containsExactlyInAnyOrder(
Tuple.tuple("processTask", version1ProcessDef.getId()),
Tuple.tuple("eventSubProcessTask", version1ProcessDef.getId()),
Tuple.tuple("eventSubProcessTask", version1ProcessDef.getId())
);
List<EventSubscription> eventSubscriptions = runtimeService.createEventSubscriptionQuery().processInstanceId(processInstance.getId()).list();
assertThat(eventSubscriptions)
.extracting(EventSubscription::getEventType, EventSubscription::getActivityId, EventSubscription::getProcessDefinitionId)
.containsExactlyInAnyOrder(Tuple.tuple("myEvent", "eventSubProcessStart", version1ProcessDef.getId()));

//Migrate to the other processDefinition
ProcessInstanceMigrationBuilder processInstanceMigrationBuilder = processMigrationService.createProcessInstanceMigrationBuilder()
.migrateToProcessDefinition(version2ProcessDef.getId());

ProcessInstanceMigrationValidationResult processInstanceMigrationValidationResult = processInstanceMigrationBuilder
.validateMigration(processInstance.getId());
assertThat(processInstanceMigrationValidationResult.isMigrationValid()).isTrue();

processInstanceMigrationBuilder.migrate(processInstance.getId());

//Confirm
executions = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId()).onlyChildExecutions().list();
assertThat(executions)
.extracting(Execution::getActivityId)
.containsExactlyInAnyOrder(
"processTask", "eventSubProcessStart", "eventSubProcess", "eventSubProcessTask", "eventSubProcess", "eventSubProcessTask"
);
assertThat(executions)
.extracting("processDefinitionId")
.containsOnly(version2ProcessDef.getId());
tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list();
assertThat(tasks)
.extracting(Task::getTaskDefinitionKey, Task::getProcessDefinitionId)
.containsExactlyInAnyOrder(
Tuple.tuple("processTask", version2ProcessDef.getId()),
Tuple.tuple("eventSubProcessTask", version2ProcessDef.getId()),
Tuple.tuple("eventSubProcessTask", version2ProcessDef.getId())
);

eventSubscriptions = runtimeService.createEventSubscriptionQuery().processInstanceId(processInstance.getId()).list();
assertThat(eventSubscriptions)
.extracting(EventSubscription::getEventType, EventSubscription::getActivityId, EventSubscription::getProcessDefinitionId)
.containsExactlyInAnyOrder(Tuple.tuple("myEvent", "eventSubProcessStart", version2ProcessDef.getId()));

completeProcessInstanceTasks(processInstance.getId());
assertProcessEnded(processInstance.getId());
}

private EventSubscriptionQueryImpl createEventSubscriptionQuery() {
return new EventSubscriptionQueryImpl(processEngineConfiguration.getCommandExecutor(), processEngineConfiguration.getEventSubscriptionServiceConfiguration());
}
Expand Down
Loading

0 comments on commit 3a21d21

Please sign in to comment.