Skip to content

Commit

Permalink
Fix issue with incorrect stage getting activated on case instance mig…
Browse files Browse the repository at this point in the history
…ration
  • Loading branch information
tijsrademakers committed Nov 27, 2023
1 parent 55cdec3 commit 4b2999a
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -884,14 +884,16 @@ protected PlanItemInstanceEntity createStagesAndPlanItemInstances(PlanItem planI
cmmnHistoryManager.recordPlanItemInstanceCreated(newPlanItemInstance);

createChildPlanItemInstancesForStage(Collections.singletonList(newPlanItemInstance), runtimePlanItemInstanceMap,
caseInstanceChangeState.getTerminatedPlanItemInstances(), Collections.singleton(planItem.getId()), commandContext);
caseInstanceChangeState.getTerminatedPlanItemInstances(), Collections.singleton(planItem.getId()),
caseInstanceChangeState, commandContext);
}

return newPlanItemInstance;
}

protected void createChildPlanItemInstancesForStage(List<PlanItemInstanceEntity> newPlanItemInstances, Map<String, List<PlanItemInstanceEntity>> runtimePlanItemInstanceMap,
Map<String, PlanItemInstanceEntity> terminatedPlanItemInstances, Set<String> newPlanItemInstanceIds, CommandContext commandContext) {
Map<String, PlanItemInstanceEntity> terminatedPlanItemInstances, Set<String> newPlanItemInstanceIds,
CaseInstanceChangeState caseInstanceChangeState, CommandContext commandContext) {

if (newPlanItemInstances.size() == 0) {
return;
Expand All @@ -902,15 +904,15 @@ protected void createChildPlanItemInstancesForStage(List<PlanItemInstanceEntity>
if (planItem != null && planItem.getParentStage() != null) {
for (PlanItem stagePlanItem : planItem.getParentStage().getPlanItems()) {
if (!newPlanItemInstanceIds.contains(stagePlanItem.getId()) && !runtimePlanItemInstanceMap.containsKey(stagePlanItem.getPlanItemDefinition().getId())
&& !terminatedPlanItemInstances.containsKey(stagePlanItem.getPlanItemDefinition().getId())) {
&& !terminatedPlanItemInstances.containsKey(stagePlanItem.getPlanItemDefinition().getId())
&& !caseInstanceChangeState.getCurrentPlanItemInstances().containsKey(stagePlanItem.getPlanItemDefinition().getId())) {

PlanItemInstance parentStagePlanItem = newPlanItemInstance.getStagePlanItemInstanceEntity();
if (parentStagePlanItem == null && newPlanItemInstance.getStageInstanceId() != null) {
parentStagePlanItem = CommandContextUtil.getPlanItemInstanceEntityManager(commandContext).findById(newPlanItemInstance.getStageInstanceId());
}

if (stagePlanItem.getPlanItemDefinition() instanceof Stage) {

PlanItemInstanceEntity childStagePlanItemInstance = cmmnEngineConfiguration.getPlanItemInstanceEntityManager()
.createPlanItemInstanceEntityBuilder()
.planItem(stagePlanItem)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4291,6 +4291,86 @@ void withPostUpgradeExpression() {

assertThat((Boolean) caseInstanceAfterMigration.getCaseVariables().getOrDefault("postUpgradeExpressionExecuted", false)).isTrue();
}

@Test
void activatePlanItemWithCompletedStage() {
// Arrange
CaseDefinition sourceDefinition = deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/activate-planitem-ended-stages.cmmn.xml");
CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("caseWithEndedStage").start();
CaseDefinition destinationDefinition = deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/activate-planitem-ended-stages.cmmn.xml");

Task task = cmmnTaskService.createTaskQuery().scopeId(caseInstance.getId()).taskDefinitionKey("humanTask1").singleResult();
cmmnTaskService.complete(task.getId());

List<PlanItemInstance> planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery()
.caseInstanceId(caseInstance.getId())
.list();
assertThat(planItemInstances).hasSize(1);
assertThat(planItemInstances)
.extracting(PlanItemInstance::getCaseDefinitionId)
.containsOnly(sourceDefinition.getId());
assertThat(planItemInstances)
.extracting(PlanItemInstance::getName)
.containsExactlyInAnyOrder("Human task 2");

planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery()
.caseInstanceId(caseInstance.getId())
.includeEnded()
.list();
assertThat(planItemInstances).hasSize(4);
assertThat(planItemInstances)
.extracting(PlanItemInstance::getCaseDefinitionId)
.containsOnly(sourceDefinition.getId());
assertThat(planItemInstances)
.extracting(PlanItemInstance::getName)
.containsExactlyInAnyOrder("Human task", "Human task 2", "Service task", "Expanded stage");

// Act
cmmnMigrationService.createCaseInstanceMigrationBuilder()
.migrateToCaseDefinition(destinationDefinition.getId())
.addActivatePlanItemDefinitionMapping(PlanItemDefinitionMappingBuilder.createActivatePlanItemDefinitionMappingFor("serviceTask1"))
.migrate(caseInstance.getId());

CaseInstance caseInstanceAfterMigration = cmmnRuntimeService.createCaseInstanceQuery()
.caseInstanceId(caseInstance.getId())
.singleResult();
assertThat(caseInstanceAfterMigration.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId());
planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery()
.caseInstanceId(caseInstance.getId())
.list();
assertThat(planItemInstances).hasSize(1);
assertThat(planItemInstances)
.extracting(PlanItemInstance::getCaseDefinitionId)
.containsOnly(destinationDefinition.getId());
assertThat(planItemInstances)
.extracting(PlanItemInstance::getName)
.containsExactlyInAnyOrder("Human task 2");
assertThat(planItemInstances)
.filteredOn("name", "Human task 2")
.extracting(PlanItemInstance::getState)
.containsOnly(PlanItemInstanceState.ACTIVE);

planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery()
.caseInstanceId(caseInstance.getId())
.includeEnded()
.list();
assertThat(planItemInstances).hasSize(5);
assertThat(planItemInstances)
.extracting(PlanItemInstance::getCaseDefinitionId)
.containsOnly(destinationDefinition.getId());
assertThat(planItemInstances)
.extracting(PlanItemInstance::getName)
.containsExactlyInAnyOrder("Human task", "Human task 2", "Service task", "Service task", "Expanded stage");

// Assert
List<HistoricPlanItemInstance> historicPlanItemInstances = cmmnHistoryService.createHistoricPlanItemInstanceQuery()
.planItemInstanceCaseInstanceId(caseInstance.getId())
.planItemInstanceDefinitionId("expandedStage1")
.list();

assertThat(historicPlanItemInstances.size()).isEqualTo(1);
assertThat(historicPlanItemInstances.get(0).getState()).isEqualTo("completed");
}

// with sentries
// with stages
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/CMMN/20151109/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:flowable="http://flowable.org/cmmn" xmlns:cmmndi="http://www.omg.org/spec/CMMN/20151109/CMMNDI" xmlns:dc="http://www.omg.org/spec/CMMN/20151109/DC" xmlns:di="http://www.omg.org/spec/CMMN/20151109/DI" xmlns:design="http://flowable.org/design" targetNamespace="http://flowable.org/cmmn">
<case id="caseWithEndedStage" name="caseWithEndedStage">
<casePlanModel id="onecaseplanmodel1" name="Case plan model" flowable:formFieldValidation="false">
<planItem id="planItemexpandedStage1" definitionRef="expandedStage1" name="Expanded stage"></planItem>
<planItem id="planItemhumanTask2" name="Human task 2" definitionRef="humanTask2"></planItem>
<planItem id="planItemserviceTask1" name="Service task" definitionRef="serviceTask1"></planItem>
<stage id="expandedStage1" name="Expanded stage">
<planItem id="planItemhumanTask1" name="Human task" definitionRef="humanTask1"></planItem>
<humanTask id="humanTask1" name="Human task" />
</stage>
<humanTask id="humanTask2" name="Human task 2" />
<task id="serviceTask1" name="Service task" flowable:type="java" flowable:expression="${true}" />
</casePlanModel>
</case>
</definitions>

0 comments on commit 4b2999a

Please sign in to comment.