Skip to content

Commit

Permalink
Merge branch 'main' of github.com:flowable/flowable-engine
Browse files Browse the repository at this point in the history
  • Loading branch information
tijsrademakers committed Apr 12, 2024
2 parents feb87b2 + f10aa6c commit b5d15f6
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public CaseInstanceMigrationBuilder fromCaseInstanceMigrationDocument(CaseInstan
this.caseInstanceMigrationDocumentDocumentBuilder.addWaitingForRepetitionPlanItemDefinitionMappings(caseInstanceMigrationDocument.getWaitingForRepetitionPlanItemDefinitionMappings());
this.caseInstanceMigrationDocumentDocumentBuilder.addRemoveWaitingForRepetitionPlanItemDefinitionMappings(caseInstanceMigrationDocument.getRemoveWaitingForRepetitionPlanItemDefinitionMappings());
this.caseInstanceMigrationDocumentDocumentBuilder.addCaseInstanceVariables(caseInstanceMigrationDocument.getCaseInstanceVariables());
this.caseInstanceMigrationDocumentDocumentBuilder.preUpgradeExpression(caseInstanceMigrationDocument.getPreUpgradeExpression());
this.caseInstanceMigrationDocumentDocumentBuilder.postUpgradeExpression(caseInstanceMigrationDocument.getPostUpgradeExpression());
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ protected void executeChangePlanItemInstancesToAvailableState(CaseInstanceChange
}

PlanItemInstance existingPlanItemInstance = null;
boolean allExistingPlanItemsAreAvailable = true;
for (PlanItemInstance planItemInstance : planItemInstances) {
if (PlanItemInstanceState.ACTIVE.equals(planItemInstance.getState()) || PlanItemInstanceState.ENABLED.equals(planItemInstance.getState())) {
if (existingPlanItemInstance != null) {
Expand All @@ -363,6 +364,14 @@ protected void executeChangePlanItemInstancesToAvailableState(CaseInstanceChange
existingPlanItemInstance = planItemInstance;
}
}
if (!PlanItemInstanceState.AVAILABLE.equals(planItemInstance.getState())) {
allExistingPlanItemsAreAvailable = false;
}
}

if (allExistingPlanItemsAreAvailable) {
// all existing plan items are available, we can continue without any changes
continue;
}

if (existingPlanItemInstance == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

package org.flowable.cmmn.test.migration;

import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.flowable.cmmn.converter.CmmnXmlConstants.ELEMENT_STAGE;
Expand All @@ -23,9 +24,11 @@
import java.util.Objects;
import java.util.stream.Collectors;

import org.assertj.core.groups.Tuple;
import org.flowable.cmmn.api.history.HistoricMilestoneInstance;
import org.flowable.cmmn.api.history.HistoricPlanItemInstance;
import org.flowable.cmmn.api.migration.ActivatePlanItemDefinitionMapping;
import org.flowable.cmmn.api.migration.CaseInstanceMigrationDocument;
import org.flowable.cmmn.api.migration.ChangePlanItemIdMapping;
import org.flowable.cmmn.api.migration.ChangePlanItemIdWithDefinitionIdMapping;
import org.flowable.cmmn.api.migration.PlanItemDefinitionMappingBuilder;
Expand All @@ -37,6 +40,7 @@
import org.flowable.cmmn.api.runtime.PlanItemInstance;
import org.flowable.cmmn.api.runtime.PlanItemInstanceState;
import org.flowable.cmmn.api.runtime.UserEventListenerInstance;
import org.flowable.cmmn.engine.impl.migration.CaseInstanceMigrationDocumentConverter;
import org.flowable.cmmn.engine.impl.persistence.entity.SentryPartInstanceEntity;
import org.flowable.cmmn.engine.test.impl.CmmnHistoryTestHelper;
import org.flowable.common.engine.api.FlowableException;
Expand Down Expand Up @@ -5252,6 +5256,34 @@ void migrateCaseInstancesWithStageAvailableBasedOnStageCondition() {
.containsOnly(PlanItemInstanceState.AVAILABLE);
}

@Test
void migrateCaseInstancesWithMoveStageToAvailableAndAlreadyAvailableStage() {
// Arrange
CaseDefinition definition1 = deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/task-followed-by-stage.cmmn.xml");
CaseInstance caseInstance = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("testCase").start();
CaseDefinition definition2 = deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/task-followed-by-stage.cmmn.xml");

assertThat(definition2.getId()).isNotEqualTo(definition1.getId());

// Act
cmmnMigrationService.createCaseInstanceMigrationBuilder()
.migrateToCaseDefinition(definition2.getId())
.addMoveToAvailablePlanItemDefinitionMapping(PlanItemDefinitionMappingBuilder.createMoveToAvailablePlanItemDefinitionMappingFor("cmmnStage_2"))
.migrate(caseInstance.getId());

// Assert
List<PlanItemInstance> planItemInstances = cmmnRuntimeService.createPlanItemInstanceQuery()
.caseInstanceId(caseInstance.getId())
.list();
assertThat(planItemInstances)
.hasSize(2)
.extracting(PlanItemInstance::getName, PlanItemInstance::getState)
.containsExactlyInAnyOrder(
Tuple.tuple("Task 1", PlanItemInstanceState.ACTIVE),
Tuple.tuple("Stage", PlanItemInstanceState.AVAILABLE)
);
}

@Test
void migrateCaseInstancesWithRepetitionAndStageVariable() {
// Arrange
Expand Down Expand Up @@ -5818,6 +5850,32 @@ void withCaseTaskWhichWillBeTerminated() {
assertThat(subcaseInstances).isEqualTo(0);
}

@Test
void testCaseInstanceMigrationDocument() {
String documentAsJson = this.cmmnMigrationService.createCaseInstanceMigrationBuilder()
.addTerminatePlanItemDefinitionMapping(
PlanItemDefinitionMappingBuilder.createTerminatePlanItemDefinitionMappingFor("terminateId", "${terminateCondition}"))
.addMoveToAvailablePlanItemDefinitionMapping(
PlanItemDefinitionMappingBuilder.createMoveToAvailablePlanItemDefinitionMappingFor("availableId", "${availableCondition}"))
.addWaitingForRepetitionPlanItemDefinitionMapping(
PlanItemDefinitionMappingBuilder.createWaitingForRepetitionPlanItemDefinitionMappingFor("repetitionId", "${repetitionCondition}"))
.removeWaitingForRepetitionPlanItemDefinitionMapping(
PlanItemDefinitionMappingBuilder.createRemoveWaitingForRepetitionPlanItemDefinitionMappingFor("removeRepetitionId",
"${removeRepetitionCondition}"))
.addActivatePlanItemDefinitionMapping(
PlanItemDefinitionMappingBuilder.createActivatePlanItemDefinitionMappingFor("activateId", "${activateCondition}"))
.withPreUpgradeExpression("${preExpression}")
.withPostUpgradeExpression("${postExpression}")
.getCaseInstanceMigrationDocument()
.asJsonString();
CaseInstanceMigrationDocument caseInstanceMigrationDocumentFromString = CaseInstanceMigrationDocumentConverter.convertFromJson(documentAsJson);
String documentAsJsonConverted = this.cmmnMigrationService.createCaseInstanceMigrationBuilderFromCaseInstanceMigrationDocument(
caseInstanceMigrationDocumentFromString)
.getCaseInstanceMigrationDocument()
.asJsonString();
assertThatJson(documentAsJsonConverted).isEqualTo(documentAsJson);
}

protected class CustomTenantProvider implements DefaultTenantProvider {

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/CMMN/20151109/MODEL" xmlns:flowable="http://flowable.org/cmmn"
targetNamespace="http://flowable.org/cmmn">
<case id="testCase" name="Test case" flowable:initiatorVariableName="initiator" flowable:candidateStarterGroups="flowableUser">
<casePlanModel id="onecaseplanmodel1" name="Case plan model" flowable:formFieldValidation="false">
<planItem id="planItemcmmnStage_2" name="Stage" definitionRef="cmmnStage_2">
<entryCriterion id="cmmnEntrySentry_3" sentryRef="sentrycmmnEntrySentry_3"/>
</planItem>
<planItem id="planItemcmmnTask_1" name="Task 1" definitionRef="cmmnTask_1"/>
<sentry id="sentrycmmnEntrySentry_3" name="Entry criterion">
<planItemOnPart id="sentryOnPartcmmnEntrySentry_3" sourceRef="planItemcmmnTask_1">
<standardEvent>complete</standardEvent>
</planItemOnPart>
</sentry>
<stage id="cmmnStage_2" name="Stage">
<planItem id="planItemcmmnTask_5" name="Task 2" definitionRef="cmmnTask_5"/>
<humanTask id="cmmnTask_5" name="Task 2" flowable:assignee="${initiator}" flowable:formFieldValidation="false">
</humanTask>
</stage>
<humanTask id="cmmnTask_1" name="Task 1" flowable:assignee="${initiator}" flowable:formFieldValidation="false">
</humanTask>
</casePlanModel>
</case>
</definitions>

0 comments on commit b5d15f6

Please sign in to comment.