From 198e5a7327cab1db322d04d0b4c87b691a62bfcf Mon Sep 17 00:00:00 2001 From: Tijs Rademakers Date: Mon, 19 Jun 2023 10:35:13 +0200 Subject: [PATCH] Make sure sentry part instances are in correct state after case instance migration --- .../CaseInstanceMigrationManagerImpl.java | 3 +- .../AbstractCmmnDynamicStateManager.java | 255 +++- .../DefaultCmmnDynamicStateManager.java | 10 +- .../migration/CaseInstanceMigrationTest.java | 1169 +++++++++++++++++ ...ry-onpart-eventdeferred-extratask.cmmn.xml | 25 + .../exitsentry-onpart-eventdeferred.cmmn.xml | 23 + ...xitsentry-onpart-id-eventdeferred.cmmn.xml | 23 + ...ge-onpart-eventdeferred-extratask.cmmn.xml | 30 + ...sentry-stage-onpart-eventdeferred.cmmn.xml | 28 + ...ry-ifpart-eventdeferred-extratask.cmmn.xml | 22 + .../sentry-ifpart-eventdeferred.cmmn.xml | 20 + ...ry-ifpart-condition-eventdeferred.cmmn.xml | 23 + ...ry-ifpart-eventdeferred-extratask.cmmn.xml | 25 + .../twosentry-ifpart-eventdeferred.cmmn.xml | 23 + .../twosentry-ifpart-onevent.cmmn.xml | 23 + ...ry-onpart-eventdeferred-extratask.cmmn.xml | 27 + .../twosentry-onpart-eventdeferred.cmmn.xml | 25 + ...twosentry-onpart-id-eventdeferred.cmmn.xml | 25 + ...try-onpart-planitem-eventdeferred.cmmn.xml | 25 + ....testExitPlanModelWithMultipleOnParts.cmmn | 19 + 20 files changed, 1820 insertions(+), 3 deletions(-) create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/exitsentry-onpart-eventdeferred-extratask.cmmn.xml create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/exitsentry-onpart-eventdeferred.cmmn.xml create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/exitsentry-onpart-id-eventdeferred.cmmn.xml create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/exitsentry-stage-onpart-eventdeferred-extratask.cmmn.xml create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/exitsentry-stage-onpart-eventdeferred.cmmn.xml create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/sentry-ifpart-eventdeferred-extratask.cmmn.xml create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/sentry-ifpart-eventdeferred.cmmn.xml create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-ifpart-condition-eventdeferred.cmmn.xml create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-ifpart-eventdeferred-extratask.cmmn.xml create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-ifpart-eventdeferred.cmmn.xml create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-ifpart-onevent.cmmn.xml create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-onpart-eventdeferred-extratask.cmmn.xml create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-onpart-eventdeferred.cmmn.xml create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-onpart-id-eventdeferred.cmmn.xml create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-onpart-planitem-eventdeferred.cmmn.xml create mode 100644 modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/ExitCriteriaTest.testExitPlanModelWithMultipleOnParts.cmmn diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/migration/CaseInstanceMigrationManagerImpl.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/migration/CaseInstanceMigrationManagerImpl.java index 001d8880907..f7efe19b22c 100644 --- a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/migration/CaseInstanceMigrationManagerImpl.java +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/migration/CaseInstanceMigrationManagerImpl.java @@ -200,6 +200,7 @@ protected void doMigrateCaseInstance(CaseInstanceEntity caseInstance, CaseDefini ChangePlanItemStateBuilderImpl changePlanItemStateBuilder = prepareChangeStateBuilder(caseInstance, caseDefinitionToMigrateTo, document, commandContext); LOGGER.debug("Updating case definition reference of case root execution with id:'{}' to '{}'", caseInstance.getId(), caseDefinitionToMigrateTo.getId()); + String originalCaseDefinitionId = caseInstance.getCaseDefinitionId(); caseInstance.setCaseDefinitionId(caseDefinitionToMigrateTo.getId()); caseInstance.setCaseDefinitionKey(caseDefinitionToMigrateTo.getKey()); caseInstance.setCaseDefinitionName(caseDefinitionToMigrateTo.getName()); @@ -217,7 +218,7 @@ protected void doMigrateCaseInstance(CaseInstanceEntity caseInstance, CaseDefini .setRemoveWaitingForRepetitionPlanItemDefinitions(changePlanItemStateBuilder.getRemoveWaitingForRepetitionPlanItemDefinitions()) .setCaseVariables(document.getCaseInstanceVariables()) .setChildInstanceTaskVariables(document.getPlanItemLocalVariables()); - doMovePlanItemState(caseInstanceChangeState, commandContext); + doMovePlanItemState(caseInstanceChangeState, originalCaseDefinitionId, commandContext); LOGGER.debug("Updating case definition reference in plan item instances"); CommandContextUtil.getPlanItemInstanceEntityManager(commandContext).updatePlanItemInstancesCaseDefinitionId(caseInstance.getId(), caseDefinitionToMigrateTo.getId()); diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/AbstractCmmnDynamicStateManager.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/AbstractCmmnDynamicStateManager.java index e913ae66bae..478af7bc288 100644 --- a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/AbstractCmmnDynamicStateManager.java +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/AbstractCmmnDynamicStateManager.java @@ -43,19 +43,26 @@ import org.flowable.cmmn.engine.impl.persistence.entity.CaseInstanceEntityManager; import org.flowable.cmmn.engine.impl.persistence.entity.PlanItemInstanceEntity; import org.flowable.cmmn.engine.impl.persistence.entity.PlanItemInstanceEntityManager; +import org.flowable.cmmn.engine.impl.persistence.entity.SentryPartInstanceEntity; +import org.flowable.cmmn.engine.impl.persistence.entity.SentryPartInstanceEntityManager; import org.flowable.cmmn.engine.impl.repository.CaseDefinitionUtil; import org.flowable.cmmn.engine.impl.runtime.MovePlanItemInstanceEntityContainer.PlanItemMoveEntry; import org.flowable.cmmn.engine.impl.task.TaskHelper; import org.flowable.cmmn.engine.impl.util.CommandContextUtil; import org.flowable.cmmn.engine.impl.util.ExpressionUtil; import org.flowable.cmmn.engine.interceptor.MigrationContext; +import org.flowable.cmmn.model.Case; import org.flowable.cmmn.model.CaseTask; import org.flowable.cmmn.model.CmmnModel; +import org.flowable.cmmn.model.Criterion; import org.flowable.cmmn.model.EventListener; import org.flowable.cmmn.model.HumanTask; import org.flowable.cmmn.model.PlanItem; import org.flowable.cmmn.model.PlanItemDefinition; import org.flowable.cmmn.model.ProcessTask; +import org.flowable.cmmn.model.Sentry; +import org.flowable.cmmn.model.SentryIfPart; +import org.flowable.cmmn.model.SentryOnPart; import org.flowable.cmmn.model.Stage; import org.flowable.cmmn.model.TimerEventListener; import org.flowable.cmmn.model.UserEventListener; @@ -104,13 +111,15 @@ protected PlanItem resolvePlanItemFromCmmnModel(CmmnModel cmmnModel, String plan return planItem; } - protected void doMovePlanItemState(CaseInstanceChangeState caseInstanceChangeState, CommandContext commandContext) { + protected void doMovePlanItemState(CaseInstanceChangeState caseInstanceChangeState, String originalCaseDefinitionId, CommandContext commandContext) { CaseInstanceEntityManager caseInstanceEntityManager = cmmnEngineConfiguration.getCaseInstanceEntityManager(); CaseInstanceEntity caseInstance = caseInstanceEntityManager.findById(caseInstanceChangeState.getCaseInstanceId()); Map> currentPlanItemInstances = retrievePlanItemInstances(caseInstanceChangeState.getCaseInstanceId()); caseInstanceChangeState.setCurrentPlanItemInstances(currentPlanItemInstances); + executeVerifySatisfiedSentryParts(caseInstanceChangeState, caseInstance, originalCaseDefinitionId, commandContext); + executeTerminatePlanItemInstances(caseInstanceChangeState, caseInstance, commandContext); navigatePlanItemInstances(currentPlanItemInstances, caseInstanceChangeState.getCaseDefinitionToMigrateTo()); @@ -381,6 +390,250 @@ protected void executeRemoveWaitingForRepetitionPlanItemInstances(CaseInstanceCh } } } + + protected void executeVerifySatisfiedSentryParts(CaseInstanceChangeState caseInstanceChangeState, + CaseInstanceEntity caseInstance, String originalCaseDefinitionId, CommandContext commandContext) { + + SentryPartInstanceEntityManager sentryPartInstanceEntityManager = cmmnEngineConfiguration.getSentryPartInstanceEntityManager(); + List sentryPartInstances = sentryPartInstanceEntityManager.findSentryPartInstancesByCaseInstanceId(caseInstance.getId()); + if (sentryPartInstances.isEmpty()) { + return; + } + + Map> sentryInstanceMap = new HashMap<>(); + for (SentryPartInstanceEntity sentryPartInstanceEntity : sentryPartInstances) { + if (!sentryInstanceMap.containsKey(sentryPartInstanceEntity.getPlanItemInstanceId())) { + sentryInstanceMap.put(sentryPartInstanceEntity.getPlanItemInstanceId(), new ArrayList<>()); + } + + sentryInstanceMap.get(sentryPartInstanceEntity.getPlanItemInstanceId()).add(sentryPartInstanceEntity); + } + + PlanItemInstanceEntityManager planItemInstanceEntityManager = cmmnEngineConfiguration.getPlanItemInstanceEntityManager(); + List planItemInstances = planItemInstanceEntityManager.findByCaseInstanceId(caseInstance.getId()); + + CmmnDeploymentManager deploymentManager = cmmnEngineConfiguration.getDeploymentManager(); + CmmnModel targetCmmnModel = deploymentManager.resolveCaseDefinition(caseInstanceChangeState.getCaseDefinitionToMigrateTo()).getCmmnModel(); + + for (PlanItemInstanceEntity planItemInstanceEntity : planItemInstances) { + List skipSentryPartInstanceForDeleteIds = new ArrayList<>(); + if (PlanItemInstanceState.AVAILABLE.equalsIgnoreCase(planItemInstanceEntity.getState()) && + sentryInstanceMap.containsKey(planItemInstanceEntity.getId())) { + + if (planItemInstanceEntity.getPlanItem().getEntryCriteria().isEmpty()) { + continue; + } + + for (Criterion criterion : planItemInstanceEntity.getPlanItem().getEntryCriteria()) { + verifySatisfiedSentryPartsForCriterion(criterion, planItemInstanceEntity, sentryInstanceMap, + skipSentryPartInstanceForDeleteIds, false, targetCmmnModel, sentryPartInstanceEntityManager); + } + + } else if (PlanItemInstanceState.ACTIVE.equalsIgnoreCase(planItemInstanceEntity.getState()) && + sentryInstanceMap.containsKey(planItemInstanceEntity.getId())) { + + if (planItemInstanceEntity.getPlanItem().getExitCriteria().isEmpty()) { + continue; + } + + for (Criterion criterion : planItemInstanceEntity.getPlanItem().getExitCriteria()) { + verifySatisfiedSentryPartsForCriterion(criterion, planItemInstanceEntity, sentryInstanceMap, + skipSentryPartInstanceForDeleteIds, true, targetCmmnModel, sentryPartInstanceEntityManager); + } + } + + List planItemSentryInstances = sentryInstanceMap.get(planItemInstanceEntity.getId()); + if (planItemSentryInstances != null) { + for (SentryPartInstanceEntity planItemSentryInstanceEntity : planItemSentryInstances) { + if (!skipSentryPartInstanceForDeleteIds.contains(planItemSentryInstanceEntity.getId())) { + sentryPartInstanceEntityManager.delete(planItemSentryInstanceEntity); + } + } + } + } + + if (sentryInstanceMap.containsKey(null)) { + List skipSentryPartInstanceForDeleteIds = new ArrayList<>(); + CaseDefinition sourceCaseDefinition = cmmnEngineConfiguration.getCaseDefinitionEntityManager().findById(originalCaseDefinitionId); + CmmnModel sourceCmmnModel = deploymentManager.resolveCaseDefinition(sourceCaseDefinition).getCmmnModel(); + Case sourceCase = sourceCmmnModel.getCaseById(sourceCaseDefinition.getKey()); + Case targetCase = targetCmmnModel.getCaseById(caseInstance.getCaseDefinitionKey()); + if (!sourceCase.getPlanModel().getExitCriteria().isEmpty()) { + for (Criterion criterion : sourceCase.getPlanModel().getExitCriteria()) { + Sentry sentry = criterion.getSentry(); + if (sentry.getOnParts().size() > 1 || + (!sentry.getOnParts().isEmpty() && sentry.getSentryIfPart() != null)) { + + List planItemSentryInstances = sentryInstanceMap.get(null); + if (sentry.getSentryIfPart() != null) { + for (SentryPartInstanceEntity planItemSentryInstanceEntity : planItemSentryInstances) { + if (sentry.getSentryIfPart().getId().equals(planItemSentryInstanceEntity.getIfPartId())) { + for (Criterion targetCriterion : targetCase.getPlanModel().getExitCriteria()) { + if (targetCriterion.getSentry().getSentryIfPart() == null) { + continue; + } + + SentryIfPart targetSentryIfPart = targetCriterion.getSentry().getSentryIfPart(); + + if (criterion.getAttachedToRefId().equals(targetCriterion.getAttachedToRefId()) && + sentry.getId().equals(targetCriterion.getSentryRef()) && + sentry.getSentryIfPart().getCondition().equals(targetSentryIfPart.getCondition())) { + + if (!sentry.isOnEventTriggerMode() && targetCriterion.getSentry().isOnEventTriggerMode()) { + continue; + } + + skipSentryPartInstanceForDeleteIds.add(planItemSentryInstanceEntity.getId()); + + if (!planItemSentryInstanceEntity.getIfPartId().equals(targetSentryIfPart.getId())) { + planItemSentryInstanceEntity.setIfPartId(targetSentryIfPart.getId()); + sentryPartInstanceEntityManager.update(planItemSentryInstanceEntity); + } + } + } + } + } + } + + for (SentryOnPart sentryOnPart : sentry.getOnParts()) { + for (SentryPartInstanceEntity planItemSentryInstanceEntity : planItemSentryInstances) { + if (sentryOnPart.getId().equals(planItemSentryInstanceEntity.getOnPartId())) { + for (Criterion targetCriterion : targetCase.getPlanModel().getExitCriteria()) { + if (targetCriterion.getSentry().getOnParts().isEmpty()) { + continue; + } + + for (SentryOnPart targetSentryOnPart : targetCriterion.getSentry().getOnParts()) { + if (criterion.getAttachedToRefId().equals(targetCriterion.getAttachedToRefId()) && + sentryOnPart.getSourceRef().equals(targetSentryOnPart.getSourceRef()) && + sentry.getId().equals(targetCriterion.getSentryRef()) && + sentryOnPart.getStandardEvent().equals(targetSentryOnPart.getStandardEvent())) { + + if (!sentry.isOnEventTriggerMode() && targetCriterion.getSentry().isOnEventTriggerMode()) { + continue; + } + + skipSentryPartInstanceForDeleteIds.add(planItemSentryInstanceEntity.getId()); + + if (!planItemSentryInstanceEntity.getOnPartId().equals(targetSentryOnPart.getId())) { + planItemSentryInstanceEntity.setOnPartId(targetSentryOnPart.getId()); + sentryPartInstanceEntityManager.update(planItemSentryInstanceEntity); + } + } + } + } + } + } + } + } + } + } + + List planItemSentryInstances = sentryInstanceMap.get(null); + for (SentryPartInstanceEntity planItemSentryInstanceEntity : planItemSentryInstances) { + if (!skipSentryPartInstanceForDeleteIds.contains(planItemSentryInstanceEntity.getId())) { + sentryPartInstanceEntityManager.delete(planItemSentryInstanceEntity); + } + } + } + + } + + protected void verifySatisfiedSentryPartsForCriterion(Criterion criterion, PlanItemInstanceEntity planItemInstanceEntity, + Map> sentryInstanceMap, List skipSentryPartInstanceForDeleteIds, + boolean isExitCriterion, CmmnModel cmmnModel, SentryPartInstanceEntityManager sentryPartInstanceEntityManager) { + + Sentry sentry = criterion.getSentry(); + if (sentry.getOnParts().size() > 1 || + (!sentry.getOnParts().isEmpty() && sentry.getSentryIfPart() != null)) { + + List planItemSentryInstances = sentryInstanceMap.get(planItemInstanceEntity.getId()); + if (sentry.getSentryIfPart() != null) { + for (SentryPartInstanceEntity planItemSentryInstanceEntity : planItemSentryInstances) { + if (sentry.getSentryIfPart().getId().equals(planItemSentryInstanceEntity.getIfPartId())) { + PlanItem targetPlanItem = cmmnModel.findPlanItemByPlanItemDefinitionId(planItemInstanceEntity.getPlanItemDefinitionId()); + if (targetPlanItem == null) { + continue; + } + + List targetCriteria = null; + if (isExitCriterion) { + targetCriteria = targetPlanItem.getExitCriteria(); + } else { + targetCriteria = targetPlanItem.getEntryCriteria(); + } + + for (Criterion targetCriterion : targetCriteria) { + if (targetCriterion.getSentry().getSentryIfPart() == null) { + continue; + } + + SentryIfPart targetSentryIfPart = targetCriterion.getSentry().getSentryIfPart(); + + if (criterion.getAttachedToRefId().equals(targetCriterion.getAttachedToRefId()) && + sentry.getId().equals(targetCriterion.getSentryRef()) && + sentry.getSentryIfPart().getCondition().equals(targetSentryIfPart.getCondition())) { + + if (!sentry.isOnEventTriggerMode() && targetCriterion.getSentry().isOnEventTriggerMode()) { + continue; + } + + skipSentryPartInstanceForDeleteIds.add(planItemSentryInstanceEntity.getId()); + + if (!planItemSentryInstanceEntity.getIfPartId().equals(targetSentryIfPart.getId())) { + planItemSentryInstanceEntity.setIfPartId(targetSentryIfPart.getId()); + sentryPartInstanceEntityManager.update(planItemSentryInstanceEntity); + } + } + } + } + } + } + + for (SentryOnPart sentryOnPart : sentry.getOnParts()) { + for (SentryPartInstanceEntity planItemSentryInstanceEntity : planItemSentryInstances) { + if (sentryOnPart.getId().equals(planItemSentryInstanceEntity.getOnPartId())) { + PlanItem targetPlanItem = cmmnModel.findPlanItemByPlanItemDefinitionId(planItemInstanceEntity.getPlanItemDefinitionId()); + if (targetPlanItem == null) { + continue; + } + + List targetCriteria = null; + if (isExitCriterion) { + targetCriteria = targetPlanItem.getExitCriteria(); + } else { + targetCriteria = targetPlanItem.getEntryCriteria(); + } + + for (Criterion targetCriterion : targetCriteria) { + if (targetCriterion.getSentry().getOnParts().isEmpty()) { + continue; + } + + for (SentryOnPart targetSentryOnPart : targetCriterion.getSentry().getOnParts()) { + if (criterion.getAttachedToRefId().equals(targetCriterion.getAttachedToRefId()) && + sentryOnPart.getSourceRef().equals(targetSentryOnPart.getSourceRef()) && + sentry.getId().equals(targetCriterion.getSentryRef()) && + sentryOnPart.getStandardEvent().equals(targetSentryOnPart.getStandardEvent())) { + + if (!sentry.isOnEventTriggerMode() && targetCriterion.getSentry().isOnEventTriggerMode()) { + continue; + } + + skipSentryPartInstanceForDeleteIds.add(planItemSentryInstanceEntity.getId()); + + if (!planItemSentryInstanceEntity.getOnPartId().equals(targetSentryOnPart.getId())) { + planItemSentryInstanceEntity.setOnPartId(targetSentryOnPart.getId()); + sentryPartInstanceEntityManager.update(planItemSentryInstanceEntity); + } + } + } + } + } + } + } + } + } protected void executeTerminatePlanItemInstances(CaseInstanceChangeState caseInstanceChangeState, CaseInstanceEntity caseInstance, CommandContext commandContext) { if (caseInstanceChangeState.getTerminatePlanItemDefinitions() == null || caseInstanceChangeState.getTerminatePlanItemDefinitions().isEmpty()) { diff --git a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/DefaultCmmnDynamicStateManager.java b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/DefaultCmmnDynamicStateManager.java index 07e20172645..c3e51e327d0 100644 --- a/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/DefaultCmmnDynamicStateManager.java +++ b/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/DefaultCmmnDynamicStateManager.java @@ -14,6 +14,9 @@ package org.flowable.cmmn.engine.impl.runtime; import org.flowable.cmmn.engine.CmmnEngineConfiguration; +import org.flowable.cmmn.engine.impl.persistence.entity.CaseInstanceEntity; +import org.flowable.cmmn.engine.impl.persistence.entity.CaseInstanceEntityManager; +import org.flowable.cmmn.engine.impl.util.CommandContextUtil; import org.flowable.cmmn.model.PlanItemDefinition; import org.flowable.common.engine.api.FlowableException; import org.flowable.common.engine.impl.interceptor.CommandContext; @@ -35,6 +38,11 @@ public void movePlanItemInstanceState(ChangePlanItemStateBuilderImpl changePlanI throw new FlowableException("Could not resolve case instance id"); } + CaseInstanceEntityManager caseInstanceEntityManager = CommandContextUtil.getCaseInstanceEntityManager(commandContext); + CaseInstanceEntity caseInstance = caseInstanceEntityManager.findById(caseInstanceId); + + String originalCaseDefinitionId = caseInstance.getCaseDefinitionId(); + CaseInstanceChangeState caseInstanceChangeState = new CaseInstanceChangeState() .setCaseInstanceId(caseInstanceId) .setActivatePlanItemDefinitions(changePlanItemStateBuilder.getActivatePlanItemDefinitions()) @@ -45,7 +53,7 @@ public void movePlanItemInstanceState(ChangePlanItemStateBuilderImpl changePlanI .setCaseVariables(changePlanItemStateBuilder.getCaseVariables()) .setChildInstanceTaskVariables(changePlanItemStateBuilder.getChildInstanceTaskVariables()); - doMovePlanItemState(caseInstanceChangeState, commandContext); + doMovePlanItemState(caseInstanceChangeState, originalCaseDefinitionId, commandContext); } @Override diff --git a/modules/flowable-cmmn-engine/src/test/java/org/flowable/cmmn/test/migration/CaseInstanceMigrationTest.java b/modules/flowable-cmmn-engine/src/test/java/org/flowable/cmmn/test/migration/CaseInstanceMigrationTest.java index 6e6b43b74a9..54b1c2bc4a7 100644 --- a/modules/flowable-cmmn-engine/src/test/java/org/flowable/cmmn/test/migration/CaseInstanceMigrationTest.java +++ b/modules/flowable-cmmn-engine/src/test/java/org/flowable/cmmn/test/migration/CaseInstanceMigrationTest.java @@ -28,10 +28,13 @@ import org.flowable.cmmn.api.runtime.CaseInstance; import org.flowable.cmmn.api.runtime.PlanItemInstance; import org.flowable.cmmn.api.runtime.PlanItemInstanceState; +import org.flowable.cmmn.engine.impl.persistence.entity.SentryPartInstanceEntity; import org.flowable.cmmn.engine.test.impl.CmmnHistoryTestHelper; import org.flowable.common.engine.api.FlowableException; import org.flowable.common.engine.impl.DefaultTenantProvider; import org.flowable.common.engine.impl.history.HistoryLevel; +import org.flowable.common.engine.impl.interceptor.Command; +import org.flowable.common.engine.impl.interceptor.CommandContext; import org.flowable.eventsubscription.api.EventSubscription; import org.flowable.task.api.Task; import org.flowable.task.api.history.HistoricTaskInstance; @@ -2150,6 +2153,1172 @@ void migrateCaseInstancesWithSimpleOneTaskMultipleCaseWithMappingsToSecondNewTas } } } + + @Test + void withTwoSentriesOnPartEventDeferred() { + // Arrange + deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/twosentry-onpart-eventdeferred.cmmn.xml"); + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("testCase").start(); + CaseDefinition destinationDefinition = deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/twosentry-onpart-eventdeferred-extratask.cmmn.xml"); + + Task firstTask = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).taskDefinitionKey("humanTask1").singleResult(); + cmmnTaskService.complete(firstTask.getId()); + + List sentryPartInstances = cmmnEngineConfiguration.getCommandExecutor().execute(new Command>() { + + @Override + public List execute(CommandContext commandContext) { + return cmmnEngineConfiguration.getSentryPartInstanceEntityManager().findSentryPartInstancesByCaseInstanceId(caseInstance.getId()); + } + + }); + + assertThat(sentryPartInstances).hasSize(1); + assertThat(sentryPartInstances.get(0).getOnPartId()).isEqualTo("sentryOnPartcmmnEntrySentry_2"); + + // Act + cmmnMigrationService.createCaseInstanceMigrationBuilder() + .migrateToCaseDefinition(destinationDefinition.getId()) + .addActivatePlanItemDefinitionMapping(PlanItemDefinitionMappingBuilder.createActivatePlanItemDefinitionMappingFor("humanTask4")) + .migrate(caseInstance.getId()); + + // Assert + CaseInstance caseInstanceAfterMigration = cmmnRuntimeService.createCaseInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .singleResult(); + assertThat(caseInstanceAfterMigration.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId()); + assertThat(caseInstanceAfterMigration.getCaseDefinitionKey()).isEqualTo("testCase"); + assertThat(caseInstanceAfterMigration.getCaseDefinitionName()).isEqualTo("Sentry On Part Test Case"); + assertThat(caseInstanceAfterMigration.getCaseDefinitionVersion()).isEqualTo(2); + assertThat(caseInstanceAfterMigration.getCaseDefinitionDeploymentId()).isEqualTo(destinationDefinition.getDeploymentId()); + + sentryPartInstances = cmmnEngineConfiguration.getCommandExecutor().execute(new Command>() { + + @Override + public List execute(CommandContext commandContext) { + return cmmnEngineConfiguration.getSentryPartInstanceEntityManager().findSentryPartInstancesByCaseInstanceId(caseInstance.getId()); + } + + }); + + assertThat(sentryPartInstances).hasSize(1); + assertThat(sentryPartInstances.get(0).getOnPartId()).isEqualTo("sentryOnPartcmmnEntrySentry_2"); + + List planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + assertThat(planItemInstances).hasSize(3); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getCaseDefinitionId) + .containsOnly(destinationDefinition.getId()); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getName) + .containsExactlyInAnyOrder("Task 2", "Task 3", "Task 4"); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.AVAILABLE, PlanItemInstanceState.ACTIVE); + + List tasks = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).list(); + assertThat(tasks).hasSize(2); + for (Task task : tasks) { + assertThat(task.getScopeDefinitionId()).isEqualTo(destinationDefinition.getId()); + cmmnTaskService.complete(task.getId()); + } + + planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + + assertThat(planItemInstances).hasSize(1); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getName) + .containsExactlyInAnyOrder("Task 3"); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.ACTIVE); + + Task task = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).singleResult(); + cmmnTaskService.complete(task.getId()); + + assertThat(cmmnRuntimeService.createCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isZero(); + + if (CmmnHistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.ACTIVITY, cmmnEngineConfiguration)) { + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isEqualTo(1); + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstance.getId()).singleResult().getCaseDefinitionId()) + .isEqualTo(destinationDefinition.getId()); + + List historicPlanItemInstances = cmmnHistoryService.createHistoricPlanItemInstanceQuery() + .planItemInstanceCaseInstanceId(caseInstance.getId()).list(); + assertThat(historicPlanItemInstances).hasSize(4); + for (HistoricPlanItemInstance historicPlanItemInstance : historicPlanItemInstances) { + assertThat(historicPlanItemInstance.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId()); + } + + List historicTasks = cmmnHistoryService.createHistoricTaskInstanceQuery().caseInstanceId(caseInstance.getId()).list(); + assertThat(historicTasks).hasSize(4); + for (HistoricTaskInstance historicTask : historicTasks) { + assertThat(historicTask.getScopeDefinitionId()).isEqualTo(destinationDefinition.getId()); + } + } + } + + @Test + void withTwoSentriesOnPartChangeIdEventDeferred() { + // Arrange + deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/twosentry-onpart-id-eventdeferred.cmmn.xml"); + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("testCase").start(); + CaseDefinition destinationDefinition = deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/twosentry-onpart-eventdeferred-extratask.cmmn.xml"); + + Task firstTask = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).taskDefinitionKey("humanTask1").singleResult(); + cmmnTaskService.complete(firstTask.getId()); + + List sentryPartInstances = cmmnEngineConfiguration.getCommandExecutor().execute(new Command>() { + + @Override + public List execute(CommandContext commandContext) { + return cmmnEngineConfiguration.getSentryPartInstanceEntityManager().findSentryPartInstancesByCaseInstanceId(caseInstance.getId()); + } + + }); + + assertThat(sentryPartInstances).hasSize(1); + assertThat(sentryPartInstances.get(0).getOnPartId()).isEqualTo("sentryOnPart1cmmnEntrySentry_2"); + + // Act + cmmnMigrationService.createCaseInstanceMigrationBuilder() + .migrateToCaseDefinition(destinationDefinition.getId()) + .addActivatePlanItemDefinitionMapping(PlanItemDefinitionMappingBuilder.createActivatePlanItemDefinitionMappingFor("humanTask4")) + .migrate(caseInstance.getId()); + + // Assert + CaseInstance caseInstanceAfterMigration = cmmnRuntimeService.createCaseInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .singleResult(); + assertThat(caseInstanceAfterMigration.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId()); + assertThat(caseInstanceAfterMigration.getCaseDefinitionKey()).isEqualTo("testCase"); + assertThat(caseInstanceAfterMigration.getCaseDefinitionName()).isEqualTo("Sentry On Part Test Case"); + assertThat(caseInstanceAfterMigration.getCaseDefinitionVersion()).isEqualTo(2); + assertThat(caseInstanceAfterMigration.getCaseDefinitionDeploymentId()).isEqualTo(destinationDefinition.getDeploymentId()); + + sentryPartInstances = cmmnEngineConfiguration.getCommandExecutor().execute(new Command>() { + + @Override + public List execute(CommandContext commandContext) { + return cmmnEngineConfiguration.getSentryPartInstanceEntityManager().findSentryPartInstancesByCaseInstanceId(caseInstance.getId()); + } + + }); + + assertThat(sentryPartInstances).hasSize(1); + assertThat(sentryPartInstances.get(0).getOnPartId()).isEqualTo("sentryOnPartcmmnEntrySentry_2"); + + List planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + assertThat(planItemInstances).hasSize(3); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getCaseDefinitionId) + .containsOnly(destinationDefinition.getId()); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getName) + .containsExactlyInAnyOrder("Task 2", "Task 3", "Task 4"); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.AVAILABLE, PlanItemInstanceState.ACTIVE); + + List tasks = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).list(); + assertThat(tasks).hasSize(2); + for (Task task : tasks) { + assertThat(task.getScopeDefinitionId()).isEqualTo(destinationDefinition.getId()); + cmmnTaskService.complete(task.getId()); + } + + planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + + assertThat(planItemInstances).hasSize(1); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getName) + .containsExactlyInAnyOrder("Task 3"); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.ACTIVE); + + Task task = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).singleResult(); + cmmnTaskService.complete(task.getId()); + + assertThat(cmmnRuntimeService.createCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isZero(); + + if (CmmnHistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.ACTIVITY, cmmnEngineConfiguration)) { + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isEqualTo(1); + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstance.getId()).singleResult().getCaseDefinitionId()) + .isEqualTo(destinationDefinition.getId()); + + List historicPlanItemInstances = cmmnHistoryService.createHistoricPlanItemInstanceQuery() + .planItemInstanceCaseInstanceId(caseInstance.getId()).list(); + assertThat(historicPlanItemInstances).hasSize(4); + for (HistoricPlanItemInstance historicPlanItemInstance : historicPlanItemInstances) { + assertThat(historicPlanItemInstance.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId()); + } + + List historicTasks = cmmnHistoryService.createHistoricTaskInstanceQuery().caseInstanceId(caseInstance.getId()).list(); + assertThat(historicTasks).hasSize(4); + for (HistoricTaskInstance historicTask : historicTasks) { + assertThat(historicTask.getScopeDefinitionId()).isEqualTo(destinationDefinition.getId()); + } + } + } + + @Test + void withTwoSentriesOnPartChangePlanItemEventDeferred() { + // Arrange + deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/twosentry-onpart-planitem-eventdeferred.cmmn.xml"); + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("testCase").start(); + CaseDefinition destinationDefinition = deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/twosentry-onpart-eventdeferred-extratask.cmmn.xml"); + + Task zeroTask = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).taskDefinitionKey("humanTask0").singleResult(); + cmmnTaskService.complete(zeroTask.getId()); + + List sentryPartInstances = cmmnEngineConfiguration.getCommandExecutor().execute(new Command>() { + + @Override + public List execute(CommandContext commandContext) { + return cmmnEngineConfiguration.getSentryPartInstanceEntityManager().findSentryPartInstancesByCaseInstanceId(caseInstance.getId()); + } + + }); + + assertThat(sentryPartInstances).hasSize(1); + assertThat(sentryPartInstances.get(0).getOnPartId()).isEqualTo("sentryOnPart1cmmnEntrySentry_2"); + + // Act + cmmnMigrationService.createCaseInstanceMigrationBuilder() + .migrateToCaseDefinition(destinationDefinition.getId()) + .addActivatePlanItemDefinitionMapping(PlanItemDefinitionMappingBuilder.createActivatePlanItemDefinitionMappingFor("humanTask1")) + .addActivatePlanItemDefinitionMapping(PlanItemDefinitionMappingBuilder.createActivatePlanItemDefinitionMappingFor("humanTask4")) + .migrate(caseInstance.getId()); + + // Assert + CaseInstance caseInstanceAfterMigration = cmmnRuntimeService.createCaseInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .singleResult(); + assertThat(caseInstanceAfterMigration.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId()); + assertThat(caseInstanceAfterMigration.getCaseDefinitionKey()).isEqualTo("testCase"); + assertThat(caseInstanceAfterMigration.getCaseDefinitionName()).isEqualTo("Sentry On Part Test Case"); + assertThat(caseInstanceAfterMigration.getCaseDefinitionVersion()).isEqualTo(2); + assertThat(caseInstanceAfterMigration.getCaseDefinitionDeploymentId()).isEqualTo(destinationDefinition.getDeploymentId()); + + sentryPartInstances = cmmnEngineConfiguration.getCommandExecutor().execute(new Command>() { + + @Override + public List execute(CommandContext commandContext) { + return cmmnEngineConfiguration.getSentryPartInstanceEntityManager().findSentryPartInstancesByCaseInstanceId(caseInstance.getId()); + } + + }); + + assertThat(sentryPartInstances).hasSize(0); + + List planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + assertThat(planItemInstances).hasSize(4); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getCaseDefinitionId) + .containsOnly(destinationDefinition.getId()); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getName) + .containsExactlyInAnyOrder("Task 1", "Task 2", "Task 3", "Task 4"); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.AVAILABLE, PlanItemInstanceState.ACTIVE); + + List tasks = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).list(); + assertThat(tasks).hasSize(3); + + Task secondTask = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).taskDefinitionKey("humanTask2").singleResult(); + assertThat(secondTask.getScopeDefinitionId()).isEqualTo(destinationDefinition.getId()); + cmmnTaskService.complete(secondTask.getId()); + + tasks = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).list(); + assertThat(tasks).hasSize(2); + + Task firstTask = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).taskDefinitionKey("humanTask1").singleResult(); + assertThat(firstTask.getScopeDefinitionId()).isEqualTo(destinationDefinition.getId()); + cmmnTaskService.complete(firstTask.getId()); + + tasks = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).list(); + assertThat(tasks).hasSize(2); + + for (Task task : tasks) { + assertThat(task.getScopeDefinitionId()).isEqualTo(destinationDefinition.getId()); + cmmnTaskService.complete(task.getId()); + } + + planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + + assertThat(planItemInstances).hasSize(0); + + assertThat(cmmnRuntimeService.createCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isZero(); + + if (CmmnHistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.ACTIVITY, cmmnEngineConfiguration)) { + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isEqualTo(1); + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstance.getId()).singleResult().getCaseDefinitionId()) + .isEqualTo(destinationDefinition.getId()); + + List historicPlanItemInstances = cmmnHistoryService.createHistoricPlanItemInstanceQuery() + .planItemInstanceCaseInstanceId(caseInstance.getId()).list(); + assertThat(historicPlanItemInstances).hasSize(5); + for (HistoricPlanItemInstance historicPlanItemInstance : historicPlanItemInstances) { + assertThat(historicPlanItemInstance.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId()); + } + + List historicTasks = cmmnHistoryService.createHistoricTaskInstanceQuery().caseInstanceId(caseInstance.getId()).list(); + assertThat(historicTasks).hasSize(5); + for (HistoricTaskInstance historicTask : historicTasks) { + assertThat(historicTask.getScopeDefinitionId()).isEqualTo(destinationDefinition.getId()); + } + } + } + + @Test + void withTwoSentriesOnPartEventDeferredToOnEvent() { + // Arrange + deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/twosentry-ifpart-eventdeferred.cmmn.xml"); + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("testCase") + .variable("var1", "test2") + .start(); + + Task task = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).singleResult(); + assertThat(task.getName()).isEqualTo("Task 1"); + + cmmnTaskService.complete(task.getId()); + + List sentryPartInstances = cmmnEngineConfiguration.getCommandExecutor().execute(new Command>() { + + @Override + public List execute(CommandContext commandContext) { + return cmmnEngineConfiguration.getSentryPartInstanceEntityManager().findSentryPartInstancesByCaseInstanceId(caseInstance.getId()); + } + + }); + + assertThat(sentryPartInstances).hasSize(1); + assertThat(sentryPartInstances.get(0).getOnPartId()).isEqualTo("sentryOnPartcmmnEntrySentry_2"); + + CaseDefinition destinationDefinition = deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/twosentry-ifpart-onevent.cmmn.xml"); + + // Act + cmmnMigrationService.createCaseInstanceMigrationBuilder() + .migrateToCaseDefinition(destinationDefinition.getId()) + .migrate(caseInstance.getId()); + + // Assert + CaseInstance caseInstanceAfterMigration = cmmnRuntimeService.createCaseInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .singleResult(); + assertThat(caseInstanceAfterMigration.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId()); + assertThat(caseInstanceAfterMigration.getCaseDefinitionKey()).isEqualTo("testCase"); + assertThat(caseInstanceAfterMigration.getCaseDefinitionName()).isEqualTo("Sentry If Part Test Case"); + assertThat(caseInstanceAfterMigration.getCaseDefinitionVersion()).isEqualTo(2); + assertThat(caseInstanceAfterMigration.getCaseDefinitionDeploymentId()).isEqualTo(destinationDefinition.getDeploymentId()); + + sentryPartInstances = cmmnEngineConfiguration.getCommandExecutor().execute(new Command>() { + + @Override + public List execute(CommandContext commandContext) { + return cmmnEngineConfiguration.getSentryPartInstanceEntityManager().findSentryPartInstancesByCaseInstanceId(caseInstance.getId()); + } + + }); + + assertThat(sentryPartInstances).hasSize(0); + + List 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("Task 2"); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.AVAILABLE); + + cmmnRuntimeService.createChangePlanItemStateBuilder().caseInstanceId(caseInstance.getId()) + .activatePlanItemDefinitionId("humanTask1") + .changeState(); + + task = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).singleResult(); + assertThat(task.getName()).isEqualTo("Task 1"); + + cmmnTaskService.complete(task.getId()); + + planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + + assertThat(planItemInstances).hasSize(1); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getName) + .containsExactlyInAnyOrder("Task 2"); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.AVAILABLE); + + cmmnRuntimeService.createChangePlanItemStateBuilder().caseInstanceId(caseInstance.getId()) + .activatePlanItemDefinitionId("humanTask1") + .changeState(); + + cmmnRuntimeService.setVariable(caseInstance.getId(), "var1", "test"); + + task = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).singleResult(); + cmmnTaskService.complete(task.getId()); + + planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + + assertThat(planItemInstances).hasSize(1); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getName) + .containsExactlyInAnyOrder("Task 2"); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.ACTIVE); + + task = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).singleResult(); + cmmnTaskService.complete(task.getId()); + + assertThat(cmmnRuntimeService.createCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isZero(); + + if (CmmnHistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.ACTIVITY, cmmnEngineConfiguration)) { + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isEqualTo(1); + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstance.getId()).singleResult().getCaseDefinitionId()) + .isEqualTo(destinationDefinition.getId()); + + List historicPlanItemInstances = cmmnHistoryService.createHistoricPlanItemInstanceQuery() + .planItemInstanceCaseInstanceId(caseInstance.getId()).list(); + assertThat(historicPlanItemInstances).hasSize(4); + for (HistoricPlanItemInstance historicPlanItemInstance : historicPlanItemInstances) { + assertThat(historicPlanItemInstance.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId()); + } + + List historicTasks = cmmnHistoryService.createHistoricTaskInstanceQuery().caseInstanceId(caseInstance.getId()).list(); + assertThat(historicTasks).hasSize(4); + for (HistoricTaskInstance historicTask : historicTasks) { + assertThat(historicTask.getScopeDefinitionId()).isEqualTo(destinationDefinition.getId()); + } + } + } + + @Test + void withTwoSentriesIfPartEventDeferred() { + // Arrange + deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/twosentry-ifpart-eventdeferred.cmmn.xml"); + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("testCase") + .variable("var1", "test") + .start(); + + cmmnRuntimeService.setVariable(caseInstance.getId(), "var1", "test2"); + + List sentryPartInstances = cmmnEngineConfiguration.getCommandExecutor().execute(new Command>() { + + @Override + public List execute(CommandContext commandContext) { + return cmmnEngineConfiguration.getSentryPartInstanceEntityManager().findSentryPartInstancesByCaseInstanceId(caseInstance.getId()); + } + + }); + + assertThat(sentryPartInstances).hasSize(1); + assertThat(sentryPartInstances.get(0).getIfPartId()).isEqualTo("ifpart1"); + + CaseDefinition destinationDefinition = deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/twosentry-ifpart-eventdeferred-extratask.cmmn.xml"); + + // Act + cmmnMigrationService.createCaseInstanceMigrationBuilder() + .migrateToCaseDefinition(destinationDefinition.getId()) + .addActivatePlanItemDefinitionMapping(PlanItemDefinitionMappingBuilder.createActivatePlanItemDefinitionMappingFor("humanTask3")) + .migrate(caseInstance.getId()); + + // Assert + CaseInstance caseInstanceAfterMigration = cmmnRuntimeService.createCaseInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .singleResult(); + assertThat(caseInstanceAfterMigration.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId()); + assertThat(caseInstanceAfterMigration.getCaseDefinitionKey()).isEqualTo("testCase"); + assertThat(caseInstanceAfterMigration.getCaseDefinitionName()).isEqualTo("Sentry If Part Test Case"); + assertThat(caseInstanceAfterMigration.getCaseDefinitionVersion()).isEqualTo(2); + assertThat(caseInstanceAfterMigration.getCaseDefinitionDeploymentId()).isEqualTo(destinationDefinition.getDeploymentId()); + + sentryPartInstances = cmmnEngineConfiguration.getCommandExecutor().execute(new Command>() { + + @Override + public List execute(CommandContext commandContext) { + return cmmnEngineConfiguration.getSentryPartInstanceEntityManager().findSentryPartInstancesByCaseInstanceId(caseInstance.getId()); + } + + }); + + assertThat(sentryPartInstances).hasSize(1); + assertThat(sentryPartInstances.get(0).getIfPartId()).isEqualTo("ifpart2"); + + List planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + assertThat(planItemInstances).hasSize(3); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getCaseDefinitionId) + .containsOnly(destinationDefinition.getId()); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getName) + .containsExactlyInAnyOrder("Task 1", "Task 2", "Task 3"); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.AVAILABLE, PlanItemInstanceState.ACTIVE); + + List tasks = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).list(); + assertThat(tasks).hasSize(2); + for (Task task : tasks) { + assertThat(task.getScopeDefinitionId()).isEqualTo(destinationDefinition.getId()); + cmmnTaskService.complete(task.getId()); + } + + planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + + assertThat(planItemInstances).hasSize(1); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getName) + .containsExactlyInAnyOrder("Task 2"); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.ACTIVE); + + Task task = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).singleResult(); + cmmnTaskService.complete(task.getId()); + + assertThat(cmmnRuntimeService.createCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isZero(); + + if (CmmnHistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.ACTIVITY, cmmnEngineConfiguration)) { + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isEqualTo(1); + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstance.getId()).singleResult().getCaseDefinitionId()) + .isEqualTo(destinationDefinition.getId()); + + List historicPlanItemInstances = cmmnHistoryService.createHistoricPlanItemInstanceQuery() + .planItemInstanceCaseInstanceId(caseInstance.getId()).list(); + assertThat(historicPlanItemInstances).hasSize(3); + for (HistoricPlanItemInstance historicPlanItemInstance : historicPlanItemInstances) { + assertThat(historicPlanItemInstance.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId()); + } + + List historicTasks = cmmnHistoryService.createHistoricTaskInstanceQuery().caseInstanceId(caseInstance.getId()).list(); + assertThat(historicTasks).hasSize(3); + for (HistoricTaskInstance historicTask : historicTasks) { + assertThat(historicTask.getScopeDefinitionId()).isEqualTo(destinationDefinition.getId()); + } + } + } + + @Test + void withTwoSentriesIfPartChangedConditionEventDeferred() { + // Arrange + deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/twosentry-ifpart-condition-eventdeferred.cmmn.xml"); + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("testCase") + .variable("var1", "test2") + .start(); + + cmmnRuntimeService.setVariable(caseInstance.getId(), "var1", "test3"); + + CaseDefinition destinationDefinition = deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/twosentry-ifpart-eventdeferred-extratask.cmmn.xml"); + + // Act + cmmnMigrationService.createCaseInstanceMigrationBuilder() + .migrateToCaseDefinition(destinationDefinition.getId()) + .addActivatePlanItemDefinitionMapping(PlanItemDefinitionMappingBuilder.createActivatePlanItemDefinitionMappingFor("humanTask3")) + .migrate(caseInstance.getId()); + + // Assert + CaseInstance caseInstanceAfterMigration = cmmnRuntimeService.createCaseInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .singleResult(); + assertThat(caseInstanceAfterMigration.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId()); + assertThat(caseInstanceAfterMigration.getCaseDefinitionKey()).isEqualTo("testCase"); + assertThat(caseInstanceAfterMigration.getCaseDefinitionName()).isEqualTo("Sentry If Part Test Case"); + assertThat(caseInstanceAfterMigration.getCaseDefinitionVersion()).isEqualTo(2); + assertThat(caseInstanceAfterMigration.getCaseDefinitionDeploymentId()).isEqualTo(destinationDefinition.getDeploymentId()); + + List planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + assertThat(planItemInstances).hasSize(3); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getCaseDefinitionId) + .containsOnly(destinationDefinition.getId()); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getName) + .containsExactlyInAnyOrder("Task 1", "Task 2", "Task 3"); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.AVAILABLE, PlanItemInstanceState.ACTIVE); + + List tasks = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).list(); + assertThat(tasks).hasSize(2); + for (Task task : tasks) { + assertThat(task.getScopeDefinitionId()).isEqualTo(destinationDefinition.getId()); + cmmnTaskService.complete(task.getId()); + } + + planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + + assertThat(planItemInstances).hasSize(1); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getName) + .containsExactlyInAnyOrder("Task 2"); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.AVAILABLE); + + cmmnRuntimeService.setVariable(caseInstance.getId(), "var1", "test"); + + planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.ACTIVE); + + Task task = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).singleResult(); + cmmnTaskService.complete(task.getId()); + + assertThat(cmmnRuntimeService.createCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isZero(); + + if (CmmnHistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.ACTIVITY, cmmnEngineConfiguration)) { + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isEqualTo(1); + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstance.getId()).singleResult().getCaseDefinitionId()) + .isEqualTo(destinationDefinition.getId()); + + List historicPlanItemInstances = cmmnHistoryService.createHistoricPlanItemInstanceQuery() + .planItemInstanceCaseInstanceId(caseInstance.getId()).list(); + assertThat(historicPlanItemInstances).hasSize(3); + for (HistoricPlanItemInstance historicPlanItemInstance : historicPlanItemInstances) { + assertThat(historicPlanItemInstance.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId()); + } + + List historicTasks = cmmnHistoryService.createHistoricTaskInstanceQuery().caseInstanceId(caseInstance.getId()).list(); + assertThat(historicTasks).hasSize(3); + for (HistoricTaskInstance historicTask : historicTasks) { + assertThat(historicTask.getScopeDefinitionId()).isEqualTo(destinationDefinition.getId()); + } + } + } + + @Test + void withTwoSentriesIfPartEventDeferredToOnEvent() { + // Arrange + deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/twosentry-ifpart-eventdeferred.cmmn.xml"); + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("testCase") + .variable("var1", "test") + .start(); + + cmmnRuntimeService.setVariable(caseInstance.getId(), "var1", "test2"); + + CaseDefinition destinationDefinition = deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/twosentry-ifpart-onevent.cmmn.xml"); + + // Act + cmmnMigrationService.createCaseInstanceMigrationBuilder() + .migrateToCaseDefinition(destinationDefinition.getId()) + .migrate(caseInstance.getId()); + + // Assert + CaseInstance caseInstanceAfterMigration = cmmnRuntimeService.createCaseInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .singleResult(); + assertThat(caseInstanceAfterMigration.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId()); + assertThat(caseInstanceAfterMigration.getCaseDefinitionKey()).isEqualTo("testCase"); + assertThat(caseInstanceAfterMigration.getCaseDefinitionName()).isEqualTo("Sentry If Part Test Case"); + assertThat(caseInstanceAfterMigration.getCaseDefinitionVersion()).isEqualTo(2); + assertThat(caseInstanceAfterMigration.getCaseDefinitionDeploymentId()).isEqualTo(destinationDefinition.getDeploymentId()); + + List planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + assertThat(planItemInstances).hasSize(2); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getCaseDefinitionId) + .containsOnly(destinationDefinition.getId()); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getName) + .containsExactlyInAnyOrder("Task 1", "Task 2"); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.AVAILABLE, PlanItemInstanceState.ACTIVE); + + List tasks = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).list(); + assertThat(tasks).hasSize(1); + assertThat(tasks.get(0).getScopeDefinitionId()).isEqualTo(destinationDefinition.getId()); + cmmnTaskService.complete(tasks.get(0).getId()); + + planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + + assertThat(planItemInstances).hasSize(1); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getName) + .containsExactlyInAnyOrder("Task 2"); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.AVAILABLE); + + assertThat(cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).count()).isZero(); + + cmmnRuntimeService.setVariable(caseInstance.getId(), "var1", "test"); + + cmmnRuntimeService.createChangePlanItemStateBuilder().caseInstanceId(caseInstance.getId()) + .activatePlanItemDefinitionId("humanTask1") + .changeState(); + + Task task = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).singleResult(); + assertThat(task.getName()).isEqualTo("Task 1"); + + cmmnTaskService.complete(task.getId()); + + planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + + assertThat(planItemInstances).hasSize(1); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getName) + .containsExactlyInAnyOrder("Task 2"); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.ACTIVE); + + task = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).singleResult(); + cmmnTaskService.complete(task.getId()); + + assertThat(cmmnRuntimeService.createCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isZero(); + + if (CmmnHistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.ACTIVITY, cmmnEngineConfiguration)) { + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isEqualTo(1); + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstance.getId()).singleResult().getCaseDefinitionId()) + .isEqualTo(destinationDefinition.getId()); + + List historicPlanItemInstances = cmmnHistoryService.createHistoricPlanItemInstanceQuery() + .planItemInstanceCaseInstanceId(caseInstance.getId()).list(); + assertThat(historicPlanItemInstances).hasSize(3); + for (HistoricPlanItemInstance historicPlanItemInstance : historicPlanItemInstances) { + assertThat(historicPlanItemInstance.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId()); + } + + List historicTasks = cmmnHistoryService.createHistoricTaskInstanceQuery().caseInstanceId(caseInstance.getId()).list(); + assertThat(historicTasks).hasSize(3); + for (HistoricTaskInstance historicTask : historicTasks) { + assertThat(historicTask.getScopeDefinitionId()).isEqualTo(destinationDefinition.getId()); + } + } + } + + @Test + void withExitSentryOnPartEventDeferred() { + // Arrange + deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/exitsentry-onpart-eventdeferred.cmmn.xml"); + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("testCase").start(); + CaseDefinition destinationDefinition = deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/exitsentry-onpart-eventdeferred-extratask.cmmn.xml"); + + Task firstTask = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).taskDefinitionKey("humanTask1").singleResult(); + cmmnTaskService.complete(firstTask.getId()); + + List sentryPartInstances = cmmnEngineConfiguration.getCommandExecutor().execute(new Command>() { + + @Override + public List execute(CommandContext commandContext) { + return cmmnEngineConfiguration.getSentryPartInstanceEntityManager().findSentryPartInstancesByCaseInstanceId(caseInstance.getId()); + } + + }); + + assertThat(sentryPartInstances).hasSize(1); + assertThat(sentryPartInstances.get(0).getOnPartId()).isEqualTo("sentryOnPartcmmnExitSentry_1"); + + // Act + cmmnMigrationService.createCaseInstanceMigrationBuilder() + .migrateToCaseDefinition(destinationDefinition.getId()) + .addActivatePlanItemDefinitionMapping(PlanItemDefinitionMappingBuilder.createActivatePlanItemDefinitionMappingFor("humanTask3")) + .migrate(caseInstance.getId()); + + // Assert + CaseInstance caseInstanceAfterMigration = cmmnRuntimeService.createCaseInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .singleResult(); + assertThat(caseInstanceAfterMigration.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId()); + assertThat(caseInstanceAfterMigration.getCaseDefinitionKey()).isEqualTo("testCase"); + assertThat(caseInstanceAfterMigration.getCaseDefinitionName()).isEqualTo("Sentry On Part Test Case"); + assertThat(caseInstanceAfterMigration.getCaseDefinitionVersion()).isEqualTo(2); + assertThat(caseInstanceAfterMigration.getCaseDefinitionDeploymentId()).isEqualTo(destinationDefinition.getDeploymentId()); + + sentryPartInstances = cmmnEngineConfiguration.getCommandExecutor().execute(new Command>() { + + @Override + public List execute(CommandContext commandContext) { + return cmmnEngineConfiguration.getSentryPartInstanceEntityManager().findSentryPartInstancesByCaseInstanceId(caseInstance.getId()); + } + + }); + + assertThat(sentryPartInstances).hasSize(1); + assertThat(sentryPartInstances.get(0).getOnPartId()).isEqualTo("sentryOnPartcmmnExitSentry_1"); + + List planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + assertThat(planItemInstances).hasSize(2); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getCaseDefinitionId) + .containsOnly(destinationDefinition.getId()); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getName) + .containsExactlyInAnyOrder("Task 2", "Task 3"); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.ACTIVE); + + Task task = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).taskDefinitionKey("humanTask2").singleResult(); + cmmnTaskService.complete(task.getId()); + + assertThat(cmmnRuntimeService.createCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isZero(); + + if (CmmnHistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.ACTIVITY, cmmnEngineConfiguration)) { + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isEqualTo(1); + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstance.getId()).singleResult().getCaseDefinitionId()) + .isEqualTo(destinationDefinition.getId()); + + List historicPlanItemInstances = cmmnHistoryService.createHistoricPlanItemInstanceQuery() + .planItemInstanceCaseInstanceId(caseInstance.getId()).list(); + assertThat(historicPlanItemInstances).hasSize(3); + for (HistoricPlanItemInstance historicPlanItemInstance : historicPlanItemInstances) { + assertThat(historicPlanItemInstance.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId()); + } + + List historicTasks = cmmnHistoryService.createHistoricTaskInstanceQuery().caseInstanceId(caseInstance.getId()).list(); + assertThat(historicTasks).hasSize(3); + for (HistoricTaskInstance historicTask : historicTasks) { + assertThat(historicTask.getScopeDefinitionId()).isEqualTo(destinationDefinition.getId()); + } + } + } + + @Test + void withExitSentryOnPartChangedIdEventDeferred() { + // Arrange + deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/exitsentry-onpart-id-eventdeferred.cmmn.xml"); + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("testCase").start(); + CaseDefinition destinationDefinition = deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/exitsentry-onpart-eventdeferred-extratask.cmmn.xml"); + + Task firstTask = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).taskDefinitionKey("humanTask1").singleResult(); + cmmnTaskService.complete(firstTask.getId()); + + List sentryPartInstances = cmmnEngineConfiguration.getCommandExecutor().execute(new Command>() { + + @Override + public List execute(CommandContext commandContext) { + return cmmnEngineConfiguration.getSentryPartInstanceEntityManager().findSentryPartInstancesByCaseInstanceId(caseInstance.getId()); + } + + }); + + assertThat(sentryPartInstances).hasSize(1); + assertThat(sentryPartInstances.get(0).getOnPartId()).isEqualTo("sentryOnPart1cmmnExitSentry_1"); + + // Act + cmmnMigrationService.createCaseInstanceMigrationBuilder() + .migrateToCaseDefinition(destinationDefinition.getId()) + .addActivatePlanItemDefinitionMapping(PlanItemDefinitionMappingBuilder.createActivatePlanItemDefinitionMappingFor("humanTask3")) + .migrate(caseInstance.getId()); + + // Assert + CaseInstance caseInstanceAfterMigration = cmmnRuntimeService.createCaseInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .singleResult(); + assertThat(caseInstanceAfterMigration.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId()); + assertThat(caseInstanceAfterMigration.getCaseDefinitionKey()).isEqualTo("testCase"); + assertThat(caseInstanceAfterMigration.getCaseDefinitionName()).isEqualTo("Sentry On Part Test Case"); + assertThat(caseInstanceAfterMigration.getCaseDefinitionVersion()).isEqualTo(2); + assertThat(caseInstanceAfterMigration.getCaseDefinitionDeploymentId()).isEqualTo(destinationDefinition.getDeploymentId()); + + sentryPartInstances = cmmnEngineConfiguration.getCommandExecutor().execute(new Command>() { + + @Override + public List execute(CommandContext commandContext) { + return cmmnEngineConfiguration.getSentryPartInstanceEntityManager().findSentryPartInstancesByCaseInstanceId(caseInstance.getId()); + } + + }); + + assertThat(sentryPartInstances).hasSize(1); + assertThat(sentryPartInstances.get(0).getOnPartId()).isEqualTo("sentryOnPartcmmnExitSentry_1"); + + List planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + assertThat(planItemInstances).hasSize(2); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getCaseDefinitionId) + .containsOnly(destinationDefinition.getId()); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getName) + .containsExactlyInAnyOrder("Task 2", "Task 3"); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.ACTIVE); + + Task task = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).taskDefinitionKey("humanTask2").singleResult(); + cmmnTaskService.complete(task.getId()); + + assertThat(cmmnRuntimeService.createCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isZero(); + + if (CmmnHistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.ACTIVITY, cmmnEngineConfiguration)) { + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isEqualTo(1); + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstance.getId()).singleResult().getCaseDefinitionId()) + .isEqualTo(destinationDefinition.getId()); + + List historicPlanItemInstances = cmmnHistoryService.createHistoricPlanItemInstanceQuery() + .planItemInstanceCaseInstanceId(caseInstance.getId()).list(); + assertThat(historicPlanItemInstances).hasSize(3); + for (HistoricPlanItemInstance historicPlanItemInstance : historicPlanItemInstances) { + assertThat(historicPlanItemInstance.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId()); + } + + List historicTasks = cmmnHistoryService.createHistoricTaskInstanceQuery().caseInstanceId(caseInstance.getId()).list(); + assertThat(historicTasks).hasSize(3); + for (HistoricTaskInstance historicTask : historicTasks) { + assertThat(historicTask.getScopeDefinitionId()).isEqualTo(destinationDefinition.getId()); + } + } + } + + @Test + void withExitSentryOnPartEventDeferredOnStage() { + // Arrange + deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/exitsentry-stage-onpart-eventdeferred.cmmn.xml"); + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("testCase").start(); + CaseDefinition destinationDefinition = deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/exitsentry-stage-onpart-eventdeferred-extratask.cmmn.xml"); + + Task firstTask = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).taskDefinitionKey("stageHumanTask1").singleResult(); + cmmnTaskService.complete(firstTask.getId()); + + List sentryPartInstances = cmmnEngineConfiguration.getCommandExecutor().execute(new Command>() { + + @Override + public List execute(CommandContext commandContext) { + return cmmnEngineConfiguration.getSentryPartInstanceEntityManager().findSentryPartInstancesByCaseInstanceId(caseInstance.getId()); + } + + }); + + assertThat(sentryPartInstances).hasSize(1); + assertThat(sentryPartInstances.get(0).getOnPartId()).isEqualTo("sentryOnPartcmmnExitSentry_1"); + + // Act + cmmnMigrationService.createCaseInstanceMigrationBuilder() + .migrateToCaseDefinition(destinationDefinition.getId()) + .addActivatePlanItemDefinitionMapping(PlanItemDefinitionMappingBuilder.createActivatePlanItemDefinitionMappingFor("stageHumanTask3")) + .migrate(caseInstance.getId()); + + // Assert + CaseInstance caseInstanceAfterMigration = cmmnRuntimeService.createCaseInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .singleResult(); + assertThat(caseInstanceAfterMigration.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId()); + assertThat(caseInstanceAfterMigration.getCaseDefinitionKey()).isEqualTo("testCase"); + assertThat(caseInstanceAfterMigration.getCaseDefinitionName()).isEqualTo("Sentry On Part Test Case"); + assertThat(caseInstanceAfterMigration.getCaseDefinitionVersion()).isEqualTo(2); + assertThat(caseInstanceAfterMigration.getCaseDefinitionDeploymentId()).isEqualTo(destinationDefinition.getDeploymentId()); + + sentryPartInstances = cmmnEngineConfiguration.getCommandExecutor().execute(new Command>() { + + @Override + public List execute(CommandContext commandContext) { + return cmmnEngineConfiguration.getSentryPartInstanceEntityManager().findSentryPartInstancesByCaseInstanceId(caseInstance.getId()); + } + + }); + + assertThat(sentryPartInstances).hasSize(1); + assertThat(sentryPartInstances.get(0).getOnPartId()).isEqualTo("sentryOnPartcmmnExitSentry_1"); + + List planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + assertThat(planItemInstances).hasSize(4); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getCaseDefinitionId) + .containsOnly(destinationDefinition.getId()); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getName) + .containsExactlyInAnyOrder("Task 1", "Stage", "Stage task 2", "Stage task 3"); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.ACTIVE); + + List tasks = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).list(); + assertThat(tasks).hasSize(3); + + Task task = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).taskDefinitionKey("stageHumanTask2").singleResult(); + cmmnTaskService.complete(task.getId()); + + planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + + assertThat(planItemInstances).hasSize(1); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getName) + .containsExactlyInAnyOrder("Task 1"); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.ACTIVE); + + task = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).taskDefinitionKey("humanTask1").singleResult(); + cmmnTaskService.complete(task.getId()); + + assertThat(cmmnRuntimeService.createCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isZero(); + + if (CmmnHistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.ACTIVITY, cmmnEngineConfiguration)) { + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isEqualTo(1); + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstance.getId()).singleResult().getCaseDefinitionId()) + .isEqualTo(destinationDefinition.getId()); + + List historicPlanItemInstances = cmmnHistoryService.createHistoricPlanItemInstanceQuery() + .planItemInstanceCaseInstanceId(caseInstance.getId()).list(); + assertThat(historicPlanItemInstances).hasSize(5); + for (HistoricPlanItemInstance historicPlanItemInstance : historicPlanItemInstances) { + assertThat(historicPlanItemInstance.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId()); + } + + List historicTasks = cmmnHistoryService.createHistoricTaskInstanceQuery().caseInstanceId(caseInstance.getId()).list(); + assertThat(historicTasks).hasSize(4); + for (HistoricTaskInstance historicTask : historicTasks) { + assertThat(historicTask.getScopeDefinitionId()).isEqualTo(destinationDefinition.getId()); + } + } + } + + @Test + void withSentryIfPartEventDeferred() { + // Arrange + deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/sentry-ifpart-eventdeferred.cmmn.xml"); + CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder() + .caseDefinitionKey("testCase") + .variable("var1", "test2") + .start(); + + CaseDefinition destinationDefinition = deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/sentry-ifpart-eventdeferred-extratask.cmmn.xml"); + + // Act + cmmnMigrationService.createCaseInstanceMigrationBuilder() + .migrateToCaseDefinition(destinationDefinition.getId()) + .addActivatePlanItemDefinitionMapping(PlanItemDefinitionMappingBuilder.createActivatePlanItemDefinitionMappingFor("humanTask3")) + .migrate(caseInstance.getId()); + + // Assert + CaseInstance caseInstanceAfterMigration = cmmnRuntimeService.createCaseInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .singleResult(); + assertThat(caseInstanceAfterMigration.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId()); + assertThat(caseInstanceAfterMigration.getCaseDefinitionKey()).isEqualTo("testCase"); + assertThat(caseInstanceAfterMigration.getCaseDefinitionName()).isEqualTo("Sentry If Part Test Case"); + assertThat(caseInstanceAfterMigration.getCaseDefinitionVersion()).isEqualTo(2); + assertThat(caseInstanceAfterMigration.getCaseDefinitionDeploymentId()).isEqualTo(destinationDefinition.getDeploymentId()); + + List planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + assertThat(planItemInstances).hasSize(3); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getCaseDefinitionId) + .containsOnly(destinationDefinition.getId()); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getName) + .containsExactlyInAnyOrder("Task 1", "Task 2", "Task 3"); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.AVAILABLE, PlanItemInstanceState.ACTIVE); + + List tasks = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).list(); + assertThat(tasks).hasSize(2); + for (Task task : tasks) { + assertThat(task.getScopeDefinitionId()).isEqualTo(destinationDefinition.getId()); + cmmnTaskService.complete(task.getId()); + } + + planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + + assertThat(planItemInstances).hasSize(1); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getName) + .containsExactlyInAnyOrder("Task 2"); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.AVAILABLE); + + cmmnRuntimeService.setVariable(caseInstance.getId(), "var1", "test"); + + planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery() + .caseInstanceId(caseInstance.getId()) + .list(); + + assertThat(planItemInstances).hasSize(1); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getName) + .containsExactlyInAnyOrder("Task 2"); + assertThat(planItemInstances) + .extracting(PlanItemInstance::getState) + .containsOnly(PlanItemInstanceState.ACTIVE); + + Task task = cmmnTaskService.createTaskQuery().caseInstanceId(caseInstance.getId()).singleResult(); + cmmnTaskService.complete(task.getId()); + + assertThat(cmmnRuntimeService.createCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isZero(); + + if (CmmnHistoryTestHelper.isHistoryLevelAtLeast(HistoryLevel.ACTIVITY, cmmnEngineConfiguration)) { + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isEqualTo(1); + assertThat(cmmnHistoryService.createHistoricCaseInstanceQuery().caseInstanceId(caseInstance.getId()).singleResult().getCaseDefinitionId()) + .isEqualTo(destinationDefinition.getId()); + + List historicPlanItemInstances = cmmnHistoryService.createHistoricPlanItemInstanceQuery() + .planItemInstanceCaseInstanceId(caseInstance.getId()).list(); + assertThat(historicPlanItemInstances).hasSize(3); + for (HistoricPlanItemInstance historicPlanItemInstance : historicPlanItemInstances) { + assertThat(historicPlanItemInstance.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId()); + } + + List historicTasks = cmmnHistoryService.createHistoricTaskInstanceQuery().caseInstanceId(caseInstance.getId()).list(); + assertThat(historicTasks).hasSize(3); + for (HistoricTaskInstance historicTask : historicTasks) { + assertThat(historicTask.getScopeDefinitionId()).isEqualTo(destinationDefinition.getId()); + } + } + } // with sentries // with stages diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/exitsentry-onpart-eventdeferred-extratask.cmmn.xml b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/exitsentry-onpart-eventdeferred-extratask.cmmn.xml new file mode 100644 index 00000000000..8847a4cfdb3 --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/exitsentry-onpart-eventdeferred-extratask.cmmn.xml @@ -0,0 +1,25 @@ + + + + + + + + + + complete + + + complete + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/exitsentry-onpart-eventdeferred.cmmn.xml b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/exitsentry-onpart-eventdeferred.cmmn.xml new file mode 100644 index 00000000000..bf8dbc4368a --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/exitsentry-onpart-eventdeferred.cmmn.xml @@ -0,0 +1,23 @@ + + + + + + + + + complete + + + complete + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/exitsentry-onpart-id-eventdeferred.cmmn.xml b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/exitsentry-onpart-id-eventdeferred.cmmn.xml new file mode 100644 index 00000000000..c28cb474827 --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/exitsentry-onpart-id-eventdeferred.cmmn.xml @@ -0,0 +1,23 @@ + + + + + + + + + complete + + + complete + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/exitsentry-stage-onpart-eventdeferred-extratask.cmmn.xml b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/exitsentry-stage-onpart-eventdeferred-extratask.cmmn.xml new file mode 100644 index 00000000000..aebde7bd975 --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/exitsentry-stage-onpart-eventdeferred-extratask.cmmn.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + complete + + + complete + + + + + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/exitsentry-stage-onpart-eventdeferred.cmmn.xml b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/exitsentry-stage-onpart-eventdeferred.cmmn.xml new file mode 100644 index 00000000000..13baae1b2fd --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/exitsentry-stage-onpart-eventdeferred.cmmn.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + complete + + + complete + + + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/sentry-ifpart-eventdeferred-extratask.cmmn.xml b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/sentry-ifpart-eventdeferred-extratask.cmmn.xml new file mode 100644 index 00000000000..2788b7f60ea --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/sentry-ifpart-eventdeferred-extratask.cmmn.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/sentry-ifpart-eventdeferred.cmmn.xml b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/sentry-ifpart-eventdeferred.cmmn.xml new file mode 100644 index 00000000000..e1be1aa2ec2 --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/sentry-ifpart-eventdeferred.cmmn.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-ifpart-condition-eventdeferred.cmmn.xml b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-ifpart-condition-eventdeferred.cmmn.xml new file mode 100644 index 00000000000..5b9b58cf2bd --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-ifpart-condition-eventdeferred.cmmn.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + complete + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-ifpart-eventdeferred-extratask.cmmn.xml b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-ifpart-eventdeferred-extratask.cmmn.xml new file mode 100644 index 00000000000..2103f373109 --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-ifpart-eventdeferred-extratask.cmmn.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + complete + + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-ifpart-eventdeferred.cmmn.xml b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-ifpart-eventdeferred.cmmn.xml new file mode 100644 index 00000000000..16b83b1aa8a --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-ifpart-eventdeferred.cmmn.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + complete + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-ifpart-onevent.cmmn.xml b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-ifpart-onevent.cmmn.xml new file mode 100644 index 00000000000..a8c5f26e60a --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-ifpart-onevent.cmmn.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + complete + + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-onpart-eventdeferred-extratask.cmmn.xml b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-onpart-eventdeferred-extratask.cmmn.xml new file mode 100644 index 00000000000..661f1bb5638 --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-onpart-eventdeferred-extratask.cmmn.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + complete + + + complete + + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-onpart-eventdeferred.cmmn.xml b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-onpart-eventdeferred.cmmn.xml new file mode 100644 index 00000000000..8c05b5d73ca --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-onpart-eventdeferred.cmmn.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + complete + + + complete + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-onpart-id-eventdeferred.cmmn.xml b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-onpart-id-eventdeferred.cmmn.xml new file mode 100644 index 00000000000..504bcae6e3d --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-onpart-id-eventdeferred.cmmn.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + complete + + + complete + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-onpart-planitem-eventdeferred.cmmn.xml b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-onpart-planitem-eventdeferred.cmmn.xml new file mode 100644 index 00000000000..81abaec9553 --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/migration/twosentry-onpart-planitem-eventdeferred.cmmn.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + complete + + + complete + + + + + + + + diff --git a/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/ExitCriteriaTest.testExitPlanModelWithMultipleOnParts.cmmn b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/ExitCriteriaTest.testExitPlanModelWithMultipleOnParts.cmmn new file mode 100644 index 00000000000..395ab16bf0c --- /dev/null +++ b/modules/flowable-cmmn-engine/src/test/resources/org/flowable/cmmn/test/runtime/ExitCriteriaTest.testExitPlanModelWithMultipleOnParts.cmmn @@ -0,0 +1,19 @@ + + + + + + + + + + + complete + + + complete + + + + + \ No newline at end of file