Skip to content

Commit 1c4be12

Browse files
Merge branch 'main' of github.com:flowable/flowable-engine into flowable-release-8.1.0
2 parents d2d7f87 + d3f485c commit 1c4be12

21 files changed

Lines changed: 291 additions & 10 deletions

modules/flowable-cmmn-api/src/main/java/org/flowable/cmmn/api/migration/CaseInstanceMigrationBuilder.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package org.flowable.cmmn.api.migration;
1515

1616
import java.util.Map;
17+
import java.util.Set;
1718

1819
import org.flowable.batch.api.Batch;
1920

@@ -31,6 +32,15 @@ public interface CaseInstanceMigrationBuilder {
3132
*/
3233
CaseInstanceMigrationBuilder fromCaseInstanceMigrationDocument(CaseInstanceMigrationDocument caseInstanceMigrationDocument);
3334

35+
/**
36+
* Specifies specific case instance ids to migrate. When set, only these case instances will be migrated
37+
* instead of all case instances of the source case definition.
38+
*
39+
* @param caseInstanceIds Set of case instance ids to migrate
40+
* @return Returns the builder
41+
*/
42+
CaseInstanceMigrationBuilder withCaseInstanceIdsToMigrate(Set<String> caseInstanceIds);
43+
3444
/**
3545
* Specifies the case definition to migrate to, using the case definition id
3646
*

modules/flowable-cmmn-api/src/main/java/org/flowable/cmmn/api/migration/CaseInstanceMigrationDocument.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import java.util.List;
1717
import java.util.Map;
18+
import java.util.Set;
1819

1920
/**
2021
* @author Valentin Zickner
@@ -29,6 +30,8 @@ public interface CaseInstanceMigrationDocument {
2930

3031
String getMigrateToCaseDefinitionTenantId();
3132

33+
Set<String> getCaseInstanceIdsToMigrate();
34+
3235
Boolean getEnableAutomaticPlanItemInstanceCreation();
3336

3437
List<ActivatePlanItemDefinitionMapping> getActivatePlanItemDefinitionMappings();

modules/flowable-cmmn-api/src/main/java/org/flowable/cmmn/api/migration/CaseInstanceMigrationDocumentBuilder.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,15 @@
1515

1616
import java.util.List;
1717
import java.util.Map;
18+
import java.util.Set;
1819

1920
/**
2021
* @author Valentin Zickner
2122
*/
2223
public interface CaseInstanceMigrationDocumentBuilder {
2324

25+
CaseInstanceMigrationDocumentBuilder setCaseInstanceIdsToMigrate(Set<String> caseInstanceIds);
26+
2427
CaseInstanceMigrationDocumentBuilder setCaseDefinitionToMigrateTo(String caseDefinitionId);
2528

2629
CaseInstanceMigrationDocumentBuilder setCaseDefinitionToMigrateTo(String caseDefinitionKey, Integer caseDefinitionVersion);

modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/migration/CaseInstanceMigrationBuilderImpl.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package org.flowable.cmmn.engine.impl.migration;
1515

1616
import java.util.Map;
17+
import java.util.Set;
1718

1819
import org.flowable.batch.api.Batch;
1920
import org.flowable.cmmn.api.CmmnMigrationService;
@@ -42,8 +43,15 @@ public CaseInstanceMigrationBuilderImpl(CmmnMigrationService cmmnMigrationServic
4243
this.cmmnMigrationService = cmmnMigrationService;
4344
}
4445

46+
@Override
47+
public CaseInstanceMigrationBuilder withCaseInstanceIdsToMigrate(Set<String> caseInstanceIds) {
48+
this.caseInstanceMigrationDocumentDocumentBuilder.setCaseInstanceIdsToMigrate(caseInstanceIds);
49+
return this;
50+
}
51+
4552
@Override
4653
public CaseInstanceMigrationBuilder fromCaseInstanceMigrationDocument(CaseInstanceMigrationDocument caseInstanceMigrationDocument) {
54+
this.caseInstanceMigrationDocumentDocumentBuilder.setCaseInstanceIdsToMigrate(caseInstanceMigrationDocument.getCaseInstanceIdsToMigrate());
4755
this.caseInstanceMigrationDocumentDocumentBuilder.setCaseDefinitionToMigrateTo(caseInstanceMigrationDocument.getMigrateToCaseDefinitionId());
4856
this.caseInstanceMigrationDocumentDocumentBuilder.setCaseDefinitionToMigrateTo(caseInstanceMigrationDocument.getMigrateToCaseDefinitionKey(), caseInstanceMigrationDocument.getMigrateToCaseDefinitionVersion());
4957
this.caseInstanceMigrationDocumentDocumentBuilder.setTenantId(caseInstanceMigrationDocument.getMigrateToCaseDefinitionTenantId());

modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/migration/CaseInstanceMigrationDocumentBuilderImpl.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515

1616
import java.util.ArrayList;
1717
import java.util.HashMap;
18+
import java.util.LinkedHashSet;
1819
import java.util.List;
1920
import java.util.Map;
21+
import java.util.Set;
2022

2123
import org.flowable.cmmn.api.migration.ActivatePlanItemDefinitionMapping;
2224
import org.flowable.cmmn.api.migration.CaseInstanceMigrationDocument;
@@ -34,6 +36,7 @@
3436
*/
3537
public class CaseInstanceMigrationDocumentBuilderImpl implements CaseInstanceMigrationDocumentBuilder {
3638

39+
protected Set<String> caseInstanceIdsToMigrate = new LinkedHashSet<>();
3740
protected String migrateToCaseDefinitionId;
3841
protected String migrateToCaseDefinitionKey;
3942
protected Integer migrateToCaseDefinitionVersion;
@@ -51,6 +54,12 @@ public class CaseInstanceMigrationDocumentBuilderImpl implements CaseInstanceMig
5154
protected String postUpgradeExpression;
5255
protected Map<String, Object> caseInstanceVariables = new HashMap<>();
5356

57+
@Override
58+
public CaseInstanceMigrationDocumentBuilder setCaseInstanceIdsToMigrate(Set<String> caseInstanceIds) {
59+
this.caseInstanceIdsToMigrate = caseInstanceIds;
60+
return this;
61+
}
62+
5463
@Override
5564
public CaseInstanceMigrationDocumentBuilder setCaseDefinitionToMigrateTo(String caseDefinitionId) {
5665
this.migrateToCaseDefinitionId = caseDefinitionId;
@@ -200,6 +209,7 @@ public CaseInstanceMigrationDocumentBuilder postUpgradeExpression(String postUpg
200209
@Override
201210
public CaseInstanceMigrationDocument build() {
202211
CaseInstanceMigrationDocumentImpl caseInstanceMigrationDocument = new CaseInstanceMigrationDocumentImpl();
212+
caseInstanceMigrationDocument.setCaseInstanceIdsToMigrate(this.caseInstanceIdsToMigrate);
203213
caseInstanceMigrationDocument.setMigrateToCaseDefinitionId(this.migrateToCaseDefinitionId);
204214
caseInstanceMigrationDocument.setMigrateToCaseDefinition(this.migrateToCaseDefinitionKey, this.migrateToCaseDefinitionVersion, this.migrateToCaseDefinitionTenantId);
205215
caseInstanceMigrationDocument.setEnableAutomaticPlanItemInstanceCreation(this.enableAutomaticPlanItemInstanceCreation);

modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/migration/CaseInstanceMigrationDocumentConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818
public interface CaseInstanceMigrationDocumentConstants {
1919

20+
String CASE_INSTANCE_IDS_TO_MIGRATE_JSON_PROPERTY = "caseInstanceIdsToMigrate";
2021
String TO_CASE_DEFINITION_ID_JSON_PROPERTY = "toCaseDefinitionId";
2122
String TO_CASE_DEFINITION_KEY_JSON_PROPERTY = "toCaseDefinitionKey";
2223
String TO_CASE_DEFINITION_VERSION_JSON_PROPERTY = "toCaseDefinitionVersion";

modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/migration/CaseInstanceMigrationDocumentConverter.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
package org.flowable.cmmn.engine.impl.migration;
1414

1515
import java.util.ArrayList;
16+
import java.util.LinkedHashSet;
1617
import java.util.List;
1718
import java.util.Map;
19+
import java.util.Set;
1820
import java.util.function.Predicate;
1921

2022
import org.apache.commons.lang3.StringUtils;
@@ -52,6 +54,15 @@ public class CaseInstanceMigrationDocumentConverter implements CaseInstanceMigra
5254
public static JsonNode convertToJson(CaseInstanceMigrationDocument caseInstanceMigrationDocument) {
5355
ObjectNode documentNode = objectMapper.createObjectNode();
5456

57+
Set<String> caseInstanceIdsToMigrate = caseInstanceMigrationDocument.getCaseInstanceIdsToMigrate();
58+
if (caseInstanceIdsToMigrate != null && !caseInstanceIdsToMigrate.isEmpty()) {
59+
ArrayNode idsArray = objectMapper.createArrayNode();
60+
for (String id : caseInstanceIdsToMigrate) {
61+
idsArray.add(id);
62+
}
63+
documentNode.set(CASE_INSTANCE_IDS_TO_MIGRATE_JSON_PROPERTY, idsArray);
64+
}
65+
5566
if (caseInstanceMigrationDocument.getMigrateToCaseDefinitionId() != null) {
5667
documentNode.put(TO_CASE_DEFINITION_ID_JSON_PROPERTY, caseInstanceMigrationDocument.getMigrateToCaseDefinitionId());
5768
}
@@ -299,6 +310,15 @@ public static CaseInstanceMigrationDocument convertFromJson(String jsonCaseInsta
299310
JsonNode rootNode = objectMapper.readTree(jsonCaseInstanceMigrationDocument);
300311
CaseInstanceMigrationDocumentBuilderImpl documentBuilder = new CaseInstanceMigrationDocumentBuilderImpl();
301312

313+
JsonNode caseInstanceIdsNode = rootNode.get(CASE_INSTANCE_IDS_TO_MIGRATE_JSON_PROPERTY);
314+
if (caseInstanceIdsNode != null && caseInstanceIdsNode.isArray()) {
315+
Set<String> caseInstanceIds = new LinkedHashSet<>();
316+
for (JsonNode idNode : caseInstanceIdsNode) {
317+
caseInstanceIds.add(idNode.asString());
318+
}
319+
documentBuilder.setCaseInstanceIdsToMigrate(caseInstanceIds);
320+
}
321+
302322
documentBuilder.setCaseDefinitionToMigrateTo(getJsonProperty(TO_CASE_DEFINITION_ID_JSON_PROPERTY, rootNode));
303323

304324
String caseDefinitionKey = getJsonProperty(TO_CASE_DEFINITION_KEY_JSON_PROPERTY, rootNode);

modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/migration/CaseInstanceMigrationDocumentImpl.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515

1616
import java.util.ArrayList;
1717
import java.util.HashMap;
18+
import java.util.LinkedHashSet;
1819
import java.util.List;
1920
import java.util.Map;
21+
import java.util.Set;
2022

2123
import org.flowable.cmmn.api.migration.ActivatePlanItemDefinitionMapping;
2224
import org.flowable.cmmn.api.migration.CaseInstanceMigrationDocument;
@@ -38,6 +40,7 @@ public class CaseInstanceMigrationDocumentImpl implements CaseInstanceMigrationD
3840
protected Integer migrateToCaseDefinitionVersion;
3941
protected String migrateToCaseDefinitionTenantId;
4042
protected Boolean enableAutomaticPlanItemInstanceCreation;
43+
protected Set<String> caseInstanceIdsToMigrate = new LinkedHashSet<>();
4144
protected List<ActivatePlanItemDefinitionMapping> activatePlanItemDefinitionMappings = new ArrayList<>();
4245
protected List<TerminatePlanItemDefinitionMapping> terminatePlanItemDefinitionMappings = new ArrayList<>();
4346
protected List<MoveToAvailablePlanItemDefinitionMapping> moveToAvailablePlanItemDefinitionMappings = new ArrayList<>();
@@ -47,7 +50,7 @@ public class CaseInstanceMigrationDocumentImpl implements CaseInstanceMigrationD
4750
protected List<ChangePlanItemIdWithDefinitionIdMapping> changePlanItemIdWithDefinitionIdMappings = new ArrayList<>();
4851
protected List<ChangePlanItemDefinitionWithNewTargetIdsMapping> changePlanItemDefinitionWithNewTargetIdsMappings = new ArrayList<>();
4952
protected String preUpgradeExpression;
50-
protected String postUpgradeExpression;
53+
protected String postUpgradeExpression;
5154
protected Map<String, Object> caseInstanceVariables = new HashMap<>();
5255
protected Map<String, Map<String, Object>> planItemLocalVariables = new HashMap<>();
5356

@@ -69,6 +72,15 @@ public void setMigrateToCaseDefinition(String caseDefinitionKey, Integer caseDef
6972
this.migrateToCaseDefinitionVersion = caseDefinitionVersion;
7073
this.migrateToCaseDefinitionTenantId = caseDefinitionTenantId;
7174
}
75+
76+
@Override
77+
public Set<String> getCaseInstanceIdsToMigrate() {
78+
return caseInstanceIdsToMigrate;
79+
}
80+
81+
public void setCaseInstanceIdsToMigrate(Set<String> caseInstanceIdsToMigrate) {
82+
this.caseInstanceIdsToMigrate = caseInstanceIdsToMigrate;
83+
}
7284

7385
public void setActivatePlanItemDefinitionMappings(List<ActivatePlanItemDefinitionMapping> planItemDefinitionMappings) {
7486
this.activatePlanItemDefinitionMappings = planItemDefinitionMappings;

modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/migration/CaseInstanceMigrationManagerImpl.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.util.List;
1919
import java.util.Map;
2020
import java.util.Objects;
21+
import java.util.Set;
2122

2223
import org.flowable.batch.api.Batch;
2324
import org.flowable.batch.api.BatchPart;
@@ -112,8 +113,12 @@ public CaseInstanceMigrationValidationResult validateMigrateCaseInstancesOfCaseD
112113
CmmnModel newModel = CaseDefinitionUtil.getCmmnModel(caseDefinition.getId());
113114

114115
CaseInstanceEntityManager caseInstanceEntityManager = cmmnEngineConfiguration.getCaseInstanceEntityManager();
115-
List<CaseInstance> caseInstances = caseInstanceEntityManager.findByCriteria(
116-
new CaseInstanceQueryImpl(commandContext, cmmnEngineConfiguration).caseDefinitionId(caseDefinitionId));
116+
CaseInstanceQueryImpl caseInstanceQuery = new CaseInstanceQueryImpl(commandContext, cmmnEngineConfiguration).caseDefinitionId(caseDefinitionId);
117+
Set<String> caseInstanceIdsToMigrate = document.getCaseInstanceIdsToMigrate();
118+
if (caseInstanceIdsToMigrate != null && !caseInstanceIdsToMigrate.isEmpty()) {
119+
caseInstanceQuery.caseInstanceIds(caseInstanceIdsToMigrate);
120+
}
121+
List<CaseInstance> caseInstances = caseInstanceEntityManager.findByCriteria(caseInstanceQuery);
117122

118123
for (CaseInstance caseInstance : caseInstances) {
119124
doValidateCaseInstanceMigration(caseInstance.getId(), newModel, document, validationResult, commandContext);
@@ -251,6 +256,10 @@ public void migrateCaseInstancesOfCaseDefinition(String caseDefinitionId, CaseIn
251256
}
252257

253258
CaseInstanceQueryImpl caseInstanceQueryByCaseDefinitionId = new CaseInstanceQueryImpl(commandContext, cmmnEngineConfiguration).caseDefinitionId(caseDefinitionId);
259+
Set<String> caseInstanceIdsToMigrate = document.getCaseInstanceIdsToMigrate();
260+
if (caseInstanceIdsToMigrate != null && !caseInstanceIdsToMigrate.isEmpty()) {
261+
caseInstanceQueryByCaseDefinitionId.caseInstanceIds(caseInstanceIdsToMigrate);
262+
}
254263
CaseInstanceEntityManager caseInstanceEntityManager = cmmnEngineConfiguration.getCaseInstanceEntityManager();
255264
List<CaseInstance> caseInstances = caseInstanceEntityManager.findByCriteria(caseInstanceQueryByCaseDefinitionId);
256265

@@ -534,8 +543,12 @@ public Batch batchMigrateCaseInstancesOfCaseDefinition(String caseDefinitionId,
534543
CaseDefinition caseDefinition = resolveCaseDefinition(document, commandContext);
535544

536545
CmmnEngineConfiguration engineConfiguration = CommandContextUtil.getCmmnEngineConfiguration();
537-
List<CaseInstanceEntity> caseInstances = engineConfiguration.getCaseInstanceEntityManager()
538-
.findCaseInstancesByCaseDefinitionId(caseDefinitionId);
546+
CaseInstanceQueryImpl caseInstanceQuery = new CaseInstanceQueryImpl(commandContext, engineConfiguration).caseDefinitionId(caseDefinitionId);
547+
Set<String> caseInstanceIdsToMigrate = document.getCaseInstanceIdsToMigrate();
548+
if (caseInstanceIdsToMigrate != null && !caseInstanceIdsToMigrate.isEmpty()) {
549+
caseInstanceQuery.caseInstanceIds(caseInstanceIdsToMigrate);
550+
}
551+
List<CaseInstance> caseInstances = engineConfiguration.getCaseInstanceEntityManager().findByCriteria(caseInstanceQuery);
539552

540553
BatchService batchService = engineConfiguration.getBatchServiceConfiguration().getBatchService();
541554
Batch batch = batchService.createBatchBuilder().batchType(Batch.CASE_MIGRATION_TYPE)

modules/flowable-cmmn-engine/src/test/java/org/flowable/cmmn/test/migration/CaseInstanceMigrationTest.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@
2222
import java.util.Calendar;
2323
import java.util.GregorianCalendar;
2424
import java.util.HashMap;
25+
import java.util.LinkedHashSet;
2526
import java.util.List;
2627
import java.util.Map;
2728
import java.util.Objects;
29+
import java.util.Set;
2830
import java.util.stream.Collectors;
2931

3032
import org.assertj.core.groups.Tuple;
@@ -6481,7 +6483,12 @@ void testCaseInstanceMigrationDocument() {
64816483
MoveToAvailablePlanItemDefinitionMapping moveToAvailablePlanItemDefinitionMapping = PlanItemDefinitionMappingBuilder.createMoveToAvailablePlanItemDefinitionMappingFor("availableId", "${availableCondition}");
64826484
moveToAvailablePlanItemDefinitionMapping.setWithLocalVariables(localVariables);
64836485

6486+
Set<String> caseInstanceIds = new LinkedHashSet<>();
6487+
caseInstanceIds.add("caseId1");
6488+
caseInstanceIds.add("caseId2");
6489+
64846490
String documentAsJson = this.cmmnMigrationService.createCaseInstanceMigrationBuilder()
6491+
.withCaseInstanceIdsToMigrate(caseInstanceIds)
64856492
.addTerminatePlanItemDefinitionMapping(
64866493
PlanItemDefinitionMappingBuilder.createTerminatePlanItemDefinitionMappingFor("terminateId", "${terminateCondition}"))
64876494
.addMoveToAvailablePlanItemDefinitionMapping(moveToAvailablePlanItemDefinitionMapping)
@@ -6582,6 +6589,49 @@ void testMigrationWithMappingsWithLocalVariables() {
65826589
assertThat(cmmnRuntimeService.createCaseInstanceQuery().caseInstanceId(caseInstance.getId()).count()).isZero();
65836590
}
65846591

6592+
@Test
6593+
void migrateCaseInstancesWithSpecificCaseInstanceIds() {
6594+
// Arrange
6595+
deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/one-task.cmmn.xml");
6596+
CaseInstance caseInstance1 = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("testCase").start();
6597+
CaseInstance caseInstance2 = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("testCase").start();
6598+
CaseInstance caseInstance3 = cmmnRuntimeService.createCaseInstanceBuilder().caseDefinitionKey("testCase").start();
6599+
CaseDefinition destinationDefinition = deployCaseDefinition("test1", "org/flowable/cmmn/test/migration/two-task.cmmn.xml");
6600+
6601+
Set<String> caseInstanceIds = new LinkedHashSet<>();
6602+
caseInstanceIds.add(caseInstance1.getId());
6603+
caseInstanceIds.add(caseInstance3.getId());
6604+
6605+
// Act - only migrate caseInstance1 and caseInstance3
6606+
cmmnMigrationService.createCaseInstanceMigrationBuilder()
6607+
.migrateToCaseDefinition(destinationDefinition.getId())
6608+
.withCaseInstanceIdsToMigrate(caseInstanceIds)
6609+
.addActivatePlanItemDefinitionMapping(PlanItemDefinitionMappingBuilder.createActivatePlanItemDefinitionMappingFor("humanTask2"))
6610+
.migrateCaseInstances(caseInstance1.getCaseDefinitionId());
6611+
6612+
// Assert - caseInstance1 and caseInstance3 should be migrated
6613+
CaseInstance caseInstance1AfterMigration = cmmnRuntimeService.createCaseInstanceQuery()
6614+
.caseInstanceId(caseInstance1.getId())
6615+
.singleResult();
6616+
assertThat(caseInstance1AfterMigration.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId());
6617+
6618+
CaseInstance caseInstance3AfterMigration = cmmnRuntimeService.createCaseInstanceQuery()
6619+
.caseInstanceId(caseInstance3.getId())
6620+
.singleResult();
6621+
assertThat(caseInstance3AfterMigration.getCaseDefinitionId()).isEqualTo(destinationDefinition.getId());
6622+
6623+
// Assert - caseInstance2 should NOT be migrated
6624+
CaseInstance caseInstance2AfterMigration = cmmnRuntimeService.createCaseInstanceQuery()
6625+
.caseInstanceId(caseInstance2.getId())
6626+
.singleResult();
6627+
assertThat(caseInstance2AfterMigration.getCaseDefinitionId()).isNotEqualTo(destinationDefinition.getId());
6628+
6629+
// Cleanup
6630+
cmmnRuntimeService.terminateCaseInstance(caseInstance1.getId());
6631+
cmmnRuntimeService.terminateCaseInstance(caseInstance2.getId());
6632+
cmmnRuntimeService.terminateCaseInstance(caseInstance3.getId());
6633+
}
6634+
65856635
protected class CustomTenantProvider implements DefaultTenantProvider {
65866636

65876637
@Override

0 commit comments

Comments
 (0)