From ee13126ad846607aec5433945f950e23278230d8 Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Fri, 10 Jul 2026 10:15:31 +0200 Subject: [PATCH 01/14] [NAE-2464] Post release fixes Update Jackson dependencies to version 3.1.5 in `pom.xml` --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index be06c1a59a..01fef9a9f0 100644 --- a/pom.xml +++ b/pom.xml @@ -74,8 +74,8 @@ 3.4.1 5.8.0 - 3.1.2 - 3.1.2 + 3.1.5 + 3.1.5 4.1.0 3.0.3 From 99f6b65a64dde1352a3893a9bd54f7edaa1d1ac2 Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Wed, 15 Jul 2026 14:08:41 +0200 Subject: [PATCH 02/14] Refactor `Task` and `ProcessResourceId` to use `processIdentifier` instead of `processId`. --- .../helpers/TaskMigrationHelper.groovy | 1 + .../engine/objects/workflow/domain/Case.java | 2 +- .../workflow/domain/ProcessResourceId.java | 20 ++++++++++--------- .../engine/objects/workflow/domain/Task.java | 17 ++++++++++------ 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/helpers/TaskMigrationHelper.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/helpers/TaskMigrationHelper.groovy index dbb369f424..8730ed1d25 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/helpers/TaskMigrationHelper.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/helpers/TaskMigrationHelper.groovy @@ -268,6 +268,7 @@ class TaskMigrationHelper extends AbstractMigrationHelper { Task oldTask = taskService.findOne(taskPair.task) log.trace("Updating task roles and permissions for task: ${oldTask.stringId}") oldTask.setProcessId(net.stringId) + oldTask.setProcessIdentifier(net.identifier) oldTask.setRoles(newTransition.roles) oldTask.setNegativeViewRoles(newTransition.negativeViewRoles) oldTask.resolveViewRoles() diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java index e8669c691c..cbbbfff692 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java @@ -147,7 +147,7 @@ protected Case() { public Case(PetriNet petriNet) { this(); - this._id = new ProcessResourceId(petriNet.getObjectId()); + this._id = new ProcessResourceId(petriNet.getIdentifier()); petriNetObjectId = petriNet.getObjectId(); processIdentifier = petriNet.getIdentifier(); this.petriNet = petriNet; diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java index abcbb4b859..402c20d320 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java @@ -6,6 +6,8 @@ import java.io.Serial; import java.io.Serializable; import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; import java.util.Date; import java.util.Objects; @@ -35,14 +37,14 @@ public ProcessResourceId(ObjectId processId) { this.shortProcessId = generateShortProcessId(processId.toString()); } - public ProcessResourceId(String processId, String objectId) { + public ProcessResourceId(String processIdentifier, String objectId) { this.objectId = new ObjectId(objectId); - this.shortProcessId = generateShortProcessId(processId); + this.shortProcessId = generateShortProcessId(processIdentifier); } - public ProcessResourceId(String processId, ObjectId objectId) { + public ProcessResourceId(String processIdentifier, ObjectId objectId) { this.objectId = objectId; - this.shortProcessId = generateShortProcessId(processId); + this.shortProcessId = generateShortProcessId(processIdentifier); } public ProcessResourceId(String compositeId) { @@ -75,12 +77,12 @@ public String toString() { return getFullId(); } - private static String generateShortProcessId(String processId) { - if (processId == null || processId.isEmpty()) { + private static String generateShortProcessId(String processIdentifier) { + if (processIdentifier == null || processIdentifier.isEmpty()) { return null; } try { - BigInteger number = new BigInteger(processId, 16); + BigInteger number = new BigInteger(1, processIdentifier.getBytes()); StringBuilder shortIdBuilder = new StringBuilder(); while (number.compareTo(BigInteger.ZERO) > 0) { @@ -91,7 +93,7 @@ private static String generateShortProcessId(String processId) { return shortIdBuilder.reverse().toString(); } catch (NumberFormatException e) { - throw new IllegalArgumentException("Invalid input string for encoding: " + processId, e); + throw new IllegalArgumentException("Invalid input string for encoding: " + processIdentifier, e); } } @@ -108,7 +110,7 @@ public static String decodeShortProcessId(String shortProcessId) { } number = number.add(BigInteger.valueOf(index)); } - return number.toString(16); + return new String(number.toByteArray()); } @Override diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Task.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Task.java index 87fd58c5a0..d9d10abca5 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Task.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Task.java @@ -36,10 +36,15 @@ public abstract class Task implements Serializable { private ProcessResourceId _id; + @Setter @Getter @Indexed private String processId; + @Getter + @Indexed + private String processIdentifier; + @Getter @Setter @Indexed @@ -169,8 +174,8 @@ public abstract class Task implements Serializable { private Map tags = new HashMap<>(); public Task() { - if (this.processId != null && !this.processId.isEmpty()) { - this._id = new ProcessResourceId(new ObjectId(this.processId)); + if (this.processIdentifier != null && !this.processIdentifier.isEmpty()) { + this._id = new ProcessResourceId(new ObjectId(this.processIdentifier)); } } @@ -179,10 +184,10 @@ public ProcessResourceId getObjectId() { return _id; } - public void setProcessId(String processId) { - this.processId = processId; - if (processId != null && !processId.isEmpty()) { - this._id = new ProcessResourceId(new ObjectId(processId)); + public void setProcessIdentifier(String processIdentifier) { + this.processIdentifier = processIdentifier; + if (processIdentifier != null && !processIdentifier.isEmpty()) { + this._id = new ProcessResourceId(new ObjectId(processIdentifier)); } } From bf6fb704b911347b6386c11ebb3967a1f89dcb0f Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Wed, 15 Jul 2026 16:15:23 +0200 Subject: [PATCH 03/14] Refactor `ProcessResourceId` constructors and usages to consistently handle `processIdentifier`. --- .../helpers/CaseMigrationHelper.groovy | 2 +- .../engine/importer/service/Importer.java | 2 +- .../engine/workflow/service/TaskService.java | 1 + .../petrinet/domain/roles/ProcessRole.java | 2 +- .../engine/objects/workflow/domain/Case.java | 2 +- .../workflow/domain/ProcessResourceId.java | 23 +++++++------------ .../engine/objects/workflow/domain/Task.java | 6 ++--- .../adapter/spring/workflow/domain/Task.java | 4 ++-- 8 files changed, 18 insertions(+), 24 deletions(-) diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/helpers/CaseMigrationHelper.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/helpers/CaseMigrationHelper.groovy index f64df517c1..74edc3612e 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/helpers/CaseMigrationHelper.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/helpers/CaseMigrationHelper.groovy @@ -461,7 +461,7 @@ class CaseMigrationHelper extends AbstractMigrationHelper { */ void migratePetriNet(Case useCase, PetriNet newNet, MigrationErrorPolicy errorPolicy = defaultErrorPolicy()) { log.debug("Starting migratePetriNet for case: ${useCase.stringId}, new net: ${newNet.stringId}") - ProcessResourceId newCaseId = new ProcessResourceId(newNet.getStringId(), useCase.get_id().getObjectId()) + ProcessResourceId newCaseId = new ProcessResourceId(newNet.getIdentifier(), useCase.get_id().getObjectId()) useCase.set_id(newCaseId) useCase.setPetriNetObjectId(newNet.objectId) log.trace("Updated petriNet reference for case: ${useCase.stringId} to net: ${newNet.stringId}") diff --git a/application-engine/src/main/java/com/netgrif/application/engine/importer/service/Importer.java b/application-engine/src/main/java/com/netgrif/application/engine/importer/service/Importer.java index 31396dec46..bce35352d9 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/importer/service/Importer.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/importer/service/Importer.java @@ -1057,7 +1057,7 @@ protected ProcessRole initRole(Role importRole) { if (importRole.isGlobal() != null && importRole.isGlobal()) { role.setGlobal(importRole.isGlobal()); } else { - role.set_id(new ProcessResourceId(new ObjectId(net.getStringId()))); + role.set_id(new ProcessResourceId(net.getIdentifier(), new ObjectId())); role.setProcessId(net.getStringId()); role.setProcessTitle(net.getTitle()); role.setProcessIdentifier(net.getIdentifier()); diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java index 17a1167600..60e327f519 100644 --- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java +++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/service/TaskService.java @@ -886,6 +886,7 @@ private Task createFromTransition(Transition transition, Case useCase) { final Task task = com.netgrif.application.engine.adapter.spring.workflow.domain.Task.with() .title(transition.getTitle()) .processId(useCase.getPetriNetId()) + .processIdentifier(useCase.getProcessIdentifier()) .caseId(useCase.get_id().toString()) .transitionId(transition.getImportId()) .layout(transition.getLayout()) diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/roles/ProcessRole.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/roles/ProcessRole.java index 851a4974b1..758346192b 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/roles/ProcessRole.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/roles/ProcessRole.java @@ -63,7 +63,7 @@ public ProcessRole() { if (this.getProcessId() == null) { _id = new ProcessResourceId(); } else { - _id = new ProcessResourceId(new ObjectId(this.getProcessId())); + _id = new ProcessResourceId(processIdentifier, new ObjectId()); } } diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java index cbbbfff692..18864d0ed6 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Case.java @@ -147,7 +147,7 @@ protected Case() { public Case(PetriNet petriNet) { this(); - this._id = new ProcessResourceId(petriNet.getIdentifier()); + this._id = new ProcessResourceId(petriNet.getIdentifier(), new ObjectId()); petriNetObjectId = petriNet.getObjectId(); processIdentifier = petriNet.getIdentifier(); this.petriNet = petriNet; diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java index 402c20d320..8fd787a283 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java @@ -6,8 +6,6 @@ import java.io.Serial; import java.io.Serializable; import java.math.BigInteger; -import java.nio.charset.StandardCharsets; -import java.security.MessageDigest; import java.util.Date; import java.util.Objects; @@ -25,26 +23,21 @@ public final class ProcessResourceId implements Comparable, S // todo add example values to javadoc private ObjectId objectId; - private String shortProcessId; + private String shortProcessIdentifier; public ProcessResourceId() { this.objectId = new ObjectId(); - this.shortProcessId = NONE_SHORT_ID_VALUE; - } - - public ProcessResourceId(ObjectId processId) { - this.objectId = new ObjectId(); - this.shortProcessId = generateShortProcessId(processId.toString()); + this.shortProcessIdentifier = NONE_SHORT_ID_VALUE; } public ProcessResourceId(String processIdentifier, String objectId) { this.objectId = new ObjectId(objectId); - this.shortProcessId = generateShortProcessId(processIdentifier); + this.shortProcessIdentifier = generateShortProcessId(processIdentifier); } public ProcessResourceId(String processIdentifier, ObjectId objectId) { this.objectId = objectId; - this.shortProcessId = generateShortProcessId(processIdentifier); + this.shortProcessIdentifier = generateShortProcessId(processIdentifier); } public ProcessResourceId(String compositeId) { @@ -52,12 +45,12 @@ public ProcessResourceId(String compositeId) { if (parts.length != 2) { throw new IllegalArgumentException("Invalid composite ID format: " + compositeId); } - this.shortProcessId = parts[0]; + this.shortProcessIdentifier = parts[0]; this.objectId = new ObjectId(parts[1]); } public String getFullId() { - return shortProcessId + ID_SEPARATOR + objectId.toHexString(); + return shortProcessIdentifier + ID_SEPARATOR + objectId.toHexString(); } public String getStringId() { @@ -123,12 +116,12 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ProcessResourceId that = (ProcessResourceId) o; - return Objects.equals(objectId, that.objectId) && Objects.equals(shortProcessId, that.shortProcessId); + return Objects.equals(objectId, that.objectId) && Objects.equals(shortProcessIdentifier, that.shortProcessIdentifier); } @Override public int hashCode() { - return Objects.hash(objectId, shortProcessId); + return Objects.hash(objectId, shortProcessIdentifier); } } diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Task.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Task.java index d9d10abca5..72563e8237 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Task.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Task.java @@ -175,7 +175,7 @@ public abstract class Task implements Serializable { public Task() { if (this.processIdentifier != null && !this.processIdentifier.isEmpty()) { - this._id = new ProcessResourceId(new ObjectId(this.processIdentifier)); + this._id = new ProcessResourceId(this.processIdentifier, new ObjectId()); } } @@ -187,14 +187,14 @@ public ProcessResourceId getObjectId() { public void setProcessIdentifier(String processIdentifier) { this.processIdentifier = processIdentifier; if (processIdentifier != null && !processIdentifier.isEmpty()) { - this._id = new ProcessResourceId(new ObjectId(processIdentifier)); + this._id = new ProcessResourceId(processIdentifier, new ObjectId()); } } public ProcessResourceId get_id() { if (this._id == null) { this._id = this.processId != null && !this.processId.isEmpty() - ? new ProcessResourceId(new ObjectId(this.processId)) + ? new ProcessResourceId(this.processIdentifier, new ObjectId()) : new ProcessResourceId(); } return this._id; diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/workflow/domain/Task.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/workflow/domain/Task.java index 6b9117b18e..fe13692850 100644 --- a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/workflow/domain/Task.java +++ b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/workflow/domain/Task.java @@ -30,7 +30,7 @@ public Task() { } @Builder(builderMethodName = "with") - public Task(ProcessResourceId _id, String processId, String caseId, String transitionId, TaskLayout layout, I18nString title, + public Task(ProcessResourceId _id, String processId, String processIdentifier, String caseId, String transitionId, TaskLayout layout, I18nString title, String caseColor, String caseTitle, Integer priority, ActorRef assignee, AbstractUser user, List triggers, Map> roles, Map> actorRefs, Map> actors, List viewRoles, List viewActorRefs, List viewActors, @@ -38,7 +38,7 @@ public Task(ProcessResourceId _id, String processId, String caseId, String trans String finishedBy, String transactionId, Boolean requiredFilled, LinkedHashSet immediateDataFields, List> immediateData, String icon, AssignPolicy assignPolicy, DataFocusPolicy dataFocusPolicy, FinishPolicy finishPolicy, Map eventTitles, Map assignedUserPolicy, Map consumedTokens, Map tags) { - super(_id, processId, caseId, transitionId, layout, title, caseColor, caseTitle, priority, assignee, user, + super(_id, processId, processIdentifier, caseId, transitionId, layout, title, caseColor, caseTitle, priority, assignee, user, triggers, roles, actorRefs, actors, viewRoles, viewActorRefs, viewActors, negativeViewRoles, negativeViewActors, startDate, finishDate, finishedBy, transactionId, requiredFilled, immediateDataFields, immediateData, icon, assignPolicy, dataFocusPolicy, finishPolicy, eventTitles, assignedUserPolicy, consumedTokens, tags); From a6d659fe0d3457e77cdd1c02dbbbff7e4cf67cf4 Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Thu, 16 Jul 2026 13:08:49 +0200 Subject: [PATCH 04/14] Introduce `ProcessResourceIdMigration` for consistent migration of `ProcessResourceId` and update related classes. --- .../ProcessResourceIdMigration.groovy | 137 ++++++++++++++++++ .../workflow/domain/ProcessResourceId.java | 27 +++- .../engine/objects/workflow/domain/Task.java | 1 + 3 files changed, 160 insertions(+), 5 deletions(-) create mode 100644 application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy new file mode 100644 index 0000000000..7b1cf30ee3 --- /dev/null +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy @@ -0,0 +1,137 @@ +package com.netgrif.application.engine.migration + +import com.netgrif.application.engine.elastic.service.ElasticCaseService +import com.netgrif.application.engine.elastic.service.ElasticIndexService +import com.netgrif.application.engine.elastic.service.ElasticTaskMappingService +import com.netgrif.application.engine.elastic.service.ElasticTaskService +import com.netgrif.application.engine.elastic.service.interfaces.IElasticCaseMappingService +import com.netgrif.application.engine.elastic.service.interfaces.IElasticTaskMappingService +import com.netgrif.application.engine.objects.elastic.domain.TaskField +import com.netgrif.application.engine.objects.petrinet.domain.PetriNet +import com.netgrif.application.engine.objects.petrinet.domain.dataset.CaseField +import com.netgrif.application.engine.objects.petrinet.domain.dataset.Field +import com.netgrif.application.engine.objects.petrinet.domain.dataset.FieldWithAllowedNets +import com.netgrif.application.engine.objects.workflow.domain.Case +import com.netgrif.application.engine.objects.workflow.domain.ProcessResourceId +import com.netgrif.application.engine.objects.workflow.domain.Task +import com.netgrif.application.engine.objects.workflow.domain.TaskPair +import groovy.util.logging.Slf4j +import org.bson.types.ObjectId +import org.springframework.beans.factory.annotation.Qualifier +import org.springframework.data.mongodb.core.MongoTemplate +import org.springframework.data.mongodb.core.query.Criteria +import org.springframework.data.mongodb.core.query.Query +import org.springframework.stereotype.Component + +import java.util.stream.Stream + +@Slf4j +@Component +class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { + + MigrationHelper migrationHelper + + MongoTemplate mongoTemplate + + Map processIdentifierIdMap = new HashMap<>() + + ElasticCaseService elasticCaseService + + ElasticTaskService elasticTaskService + + IElasticCaseMappingService elasticCaseMappingService + + IElasticTaskMappingService elasticTaskMappingService + + ProcessResourceIdMigration(MigrationHelper migrationHelper, + @Qualifier("mongoTemplate") MongoTemplate mongoTemplate, + ElasticCaseService elasticCaseService, + ElasticTaskService elasticTaskService, + IElasticCaseMappingService elasticCaseMappingService, + IElasticTaskMappingService elasticTaskMappingService) { + this.migrationHelper = migrationHelper + this.mongoTemplate = mongoTemplate + this.elasticCaseService = elasticCaseService + this.elasticTaskService = elasticTaskService + this.elasticCaseMappingService = elasticCaseMappingService + this.elasticTaskMappingService = elasticTaskMappingService + } + + @Override + void migrate() { + Query query = Query.query(Criteria.where("_id.shortProcessId").exists(true)) + query.cursorBatchSize(500) + + try (Stream cursorStream = mongoTemplate.stream(query, Case.class)) { + Iterator cursor = cursorStream.iterator() + + while (cursor.hasNext()) { + Case useCase = cursor.next() + + ProcessResourceId oldCaseId = useCase.get_id() + ProcessResourceId newCaseId = new ProcessResourceId(useCase.getProcessIdentifier(), oldCaseId.getObjectId()) + + if (newCaseId == oldCaseId) { + continue + } + + if (useCase.getTasks() != null && !useCase.getTasks().isEmpty()) { + Set newTaskPairs = new HashSet<>() + List oldTasks = mongoTemplate.find(Query.query(Criteria.where("caseId").is(oldCaseId.toString())), Task.class) + oldTasks.forEach { + ProcessResourceId oldTaskId = it.get_id() + ProcessResourceId newTaskId = new ProcessResourceId(useCase.getProcessIdentifier(), oldTaskId.getObjectId()) + if (newTaskId != oldTaskId) { + it.set_id(newTaskId) + it.setProcessIdentifier(useCase.getProcessIdentifier()) + it.setCaseId(newCaseId.toString()) + } + mongoTemplate.insert(it) + mongoTemplate.remove(Query.query(Criteria.where("_id").is(oldTaskId)), Task.class) + + elasticTaskService.index(elasticTaskMappingService.transform(it)) + elasticTaskService.remove(oldTaskId.getStringId()) + newTaskPairs.add(new TaskPair(newTaskId.toString(), it.transitionId)) + } + useCase.setTasks(newTaskPairs) + } + + useCase.dataSet.each { key, dataField -> + Field field = useCase.getField(key) + if (field instanceof FieldWithAllowedNets) { + List oldValues = (List) dataField.getValue() + List newValues = new ArrayList<>() + oldValues.forEach { oldStringId -> + String[] parts = oldStringId.split(ProcessResourceId.ID_SEPARATOR); + if (parts.length != 2) { + throw new IllegalArgumentException("Invalid composite ID format: " + oldStringId); + } + String processId = ProcessResourceId.decodeShortProcessId(parts[0]) + if (processIdentifierIdMap.containsKey(processId)) { + newValues.add(new ProcessResourceId(processIdentifierIdMap.get(processId), parts[1]).toString()) + } else { + try { + PetriNet petriNet = mongoTemplate.findById(new ObjectId(processId), PetriNet.class) + if (petriNet != null) { + processIdentifierIdMap.put(processId, petriNet.getIdentifier()) + newValues.add(new ProcessResourceId(petriNet.getIdentifier(), parts[1]).toString()) + } + } catch (IllegalArgumentException e) { + log.error("Error while update reference fields", e) + } + } + } + dataField.setValue(newValues) + } + } + + useCase.set_id(newCaseId) + + mongoTemplate.insert(useCase) + mongoTemplate.remove(Query.query(Criteria.where("_id").is(oldCaseId)), Case.class) + elasticCaseService.index(elasticCaseMappingService.transform(useCase)) + elasticCaseService.remove(oldCaseId.toString()) + } + } + } +} diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java index 8fd787a283..b60f7c07cc 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java @@ -23,6 +23,7 @@ public final class ProcessResourceId implements Comparable, S // todo add example values to javadoc private ObjectId objectId; + private String shortProcessIdentifier; public ProcessResourceId() { @@ -32,16 +33,16 @@ public ProcessResourceId() { public ProcessResourceId(String processIdentifier, String objectId) { this.objectId = new ObjectId(objectId); - this.shortProcessIdentifier = generateShortProcessId(processIdentifier); + this.shortProcessIdentifier = generateShortProcessIdentifier(processIdentifier); } public ProcessResourceId(String processIdentifier, ObjectId objectId) { this.objectId = objectId; - this.shortProcessIdentifier = generateShortProcessId(processIdentifier); + this.shortProcessIdentifier = generateShortProcessIdentifier(processIdentifier); } public ProcessResourceId(String compositeId) { - String[] parts = compositeId.split("-"); + String[] parts = compositeId.split(ID_SEPARATOR); if (parts.length != 2) { throw new IllegalArgumentException("Invalid composite ID format: " + compositeId); } @@ -70,7 +71,23 @@ public String toString() { return getFullId(); } - private static String generateShortProcessId(String processIdentifier) { + public static String decodeShortProcessId(String shortProcessId) { + if (shortProcessId == null || shortProcessId.isEmpty()) { + return null; + } + BigInteger number = BigInteger.ZERO; + for (char c : shortProcessId.toCharArray()) { + number = number.multiply(CHAR_ARRAY_LENGTH); + int index = CHAR_ARRAY.indexOf(c); + if (index == -1) { + throw new IllegalArgumentException("Invalid character in short process ID: " + c); + } + number = number.add(BigInteger.valueOf(index)); + } + return number.toString(16); + } + + private static String generateShortProcessIdentifier(String processIdentifier) { if (processIdentifier == null || processIdentifier.isEmpty()) { return null; } @@ -90,7 +107,7 @@ private static String generateShortProcessId(String processIdentifier) { } } - public static String decodeShortProcessId(String shortProcessId) { + public static String decodeShortProcessIdentifier(String shortProcessId) { if (shortProcessId == null || shortProcessId.isEmpty()) { return null; } diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Task.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Task.java index 72563e8237..dda6136263 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Task.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/Task.java @@ -34,6 +34,7 @@ public abstract class Task implements Serializable { @Serial private static final long serialVersionUID = -7112277728921547546L; + @Setter private ProcessResourceId _id; @Setter From e2b94757357327ba7395a310b30dd7cf7f8b619f Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Thu, 16 Jul 2026 13:44:51 +0200 Subject: [PATCH 05/14] Mark `shortProcessId` as deprecated in `ProcessResourceId`. --- .../engine/migration/ProcessResourceIdMigration.groovy | 3 ++- .../engine/objects/workflow/domain/ProcessResourceId.java | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy index 7b1cf30ee3..88be7668f1 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy @@ -127,8 +127,9 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { useCase.set_id(newCaseId) + mongoTemplate.insert(useCase) - mongoTemplate.remove(Query.query(Criteria.where("_id").is(oldCaseId)), Case.class) + mongoTemplate.remove(Query.query(Criteria.where("_id.objectId").is(oldCaseId.getObjectId()).and("_id.shortProcessId").is(oldCaseId.getShortProcessId())), Case.class) elasticCaseService.index(elasticCaseMappingService.transform(useCase)) elasticCaseService.remove(oldCaseId.toString()) } diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java index b60f7c07cc..1d15d1386b 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java @@ -26,6 +26,9 @@ public final class ProcessResourceId implements Comparable, S private String shortProcessIdentifier; + @Deprecated(since = "7.0.0", forRemoval = true) + private String shortProcessId; + public ProcessResourceId() { this.objectId = new ObjectId(); this.shortProcessIdentifier = NONE_SHORT_ID_VALUE; From a644313e5a54558762c6cc1165515023ed823a1b Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Thu, 16 Jul 2026 14:16:45 +0200 Subject: [PATCH 06/14] Simplify `ProcessResourceIdMigration` by removing `shortProcessId` from queries and setting it to null during migration. --- .../engine/migration/ProcessResourceIdMigration.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy index 88be7668f1..0bd712d887 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy @@ -69,6 +69,7 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { Case useCase = cursor.next() ProcessResourceId oldCaseId = useCase.get_id() + oldCaseId.shortProcessIdentifier = null ProcessResourceId newCaseId = new ProcessResourceId(useCase.getProcessIdentifier(), oldCaseId.getObjectId()) if (newCaseId == oldCaseId) { @@ -127,9 +128,8 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { useCase.set_id(newCaseId) - mongoTemplate.insert(useCase) - mongoTemplate.remove(Query.query(Criteria.where("_id.objectId").is(oldCaseId.getObjectId()).and("_id.shortProcessId").is(oldCaseId.getShortProcessId())), Case.class) + mongoTemplate.remove(Query.query(Criteria.where("_id").is(oldCaseId)), Case.class) elasticCaseService.index(elasticCaseMappingService.transform(useCase)) elasticCaseService.remove(oldCaseId.toString()) } From c0091b0118ea07015c5df9ee41e990ff64c6fae3 Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Thu, 16 Jul 2026 14:35:51 +0200 Subject: [PATCH 07/14] Add `@Setter` to `ProcessResourceId` and update migration logic to use setters consistently --- .../ProcessResourceIdMigration.groovy | 39 ++++++++++--------- .../workflow/domain/ProcessResourceId.java | 2 + 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy index 0bd712d887..d9786a4c0b 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy @@ -69,7 +69,7 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { Case useCase = cursor.next() ProcessResourceId oldCaseId = useCase.get_id() - oldCaseId.shortProcessIdentifier = null + oldCaseId.setShortProcessIdentifier(null) ProcessResourceId newCaseId = new ProcessResourceId(useCase.getProcessIdentifier(), oldCaseId.getObjectId()) if (newCaseId == oldCaseId) { @@ -78,9 +78,10 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { if (useCase.getTasks() != null && !useCase.getTasks().isEmpty()) { Set newTaskPairs = new HashSet<>() - List oldTasks = mongoTemplate.find(Query.query(Criteria.where("caseId").is(oldCaseId.toString())), Task.class) + List oldTasks = mongoTemplate.find(Query.query(Criteria.where("caseId").is(oldCaseId.shortProcessId + ProcessResourceId.ID_SEPARATOR + oldCaseId.getObjectId().toString())), Task.class) oldTasks.forEach { ProcessResourceId oldTaskId = it.get_id() + oldTaskId.setShortProcessIdentifier(null) ProcessResourceId newTaskId = new ProcessResourceId(useCase.getProcessIdentifier(), oldTaskId.getObjectId()) if (newTaskId != oldTaskId) { it.set_id(newTaskId) @@ -102,23 +103,25 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { if (field instanceof FieldWithAllowedNets) { List oldValues = (List) dataField.getValue() List newValues = new ArrayList<>() - oldValues.forEach { oldStringId -> - String[] parts = oldStringId.split(ProcessResourceId.ID_SEPARATOR); - if (parts.length != 2) { - throw new IllegalArgumentException("Invalid composite ID format: " + oldStringId); - } - String processId = ProcessResourceId.decodeShortProcessId(parts[0]) - if (processIdentifierIdMap.containsKey(processId)) { - newValues.add(new ProcessResourceId(processIdentifierIdMap.get(processId), parts[1]).toString()) - } else { - try { - PetriNet petriNet = mongoTemplate.findById(new ObjectId(processId), PetriNet.class) - if (petriNet != null) { - processIdentifierIdMap.put(processId, petriNet.getIdentifier()) - newValues.add(new ProcessResourceId(petriNet.getIdentifier(), parts[1]).toString()) + if (oldValues != null) { + oldValues.forEach { oldStringId -> + String[] parts = oldStringId.split(ProcessResourceId.ID_SEPARATOR); + if (parts.length != 2) { + throw new IllegalArgumentException("Invalid composite ID format: " + oldStringId); + } + String processId = ProcessResourceId.decodeShortProcessId(parts[0]) + if (processIdentifierIdMap.containsKey(processId)) { + newValues.add(new ProcessResourceId(processIdentifierIdMap.get(processId), parts[1]).toString()) + } else { + try { + PetriNet petriNet = mongoTemplate.findById(new ObjectId(processId), PetriNet.class) + if (petriNet != null) { + processIdentifierIdMap.put(processId, petriNet.getIdentifier()) + newValues.add(new ProcessResourceId(petriNet.getIdentifier(), parts[1]).toString()) + } + } catch (IllegalArgumentException e) { + log.error("Error while update reference fields", e) } - } catch (IllegalArgumentException e) { - log.error("Error while update reference fields", e) } } } diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java index 1d15d1386b..8b903315fd 100644 --- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java +++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/workflow/domain/ProcessResourceId.java @@ -1,6 +1,7 @@ package com.netgrif.application.engine.objects.workflow.domain; import lombok.Getter; +import lombok.Setter; import org.bson.types.ObjectId; import java.io.Serial; @@ -10,6 +11,7 @@ import java.util.Objects; @Getter +@Setter public final class ProcessResourceId implements Comparable, Serializable { @Serial From 1c96cb87abd77fbe2596ec5b787899adf740e44f Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Thu, 16 Jul 2026 15:20:12 +0200 Subject: [PATCH 08/14] Update `ProcessResourceIdMigration` to handle `ProcessRole` IDs and migrate role-related fields in `Case` documents --- .../ProcessResourceIdMigration.groovy | 126 +++++++++++++++++- 1 file changed, 123 insertions(+), 3 deletions(-) diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy index d9786a4c0b..a860bd41ba 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy @@ -11,6 +11,7 @@ import com.netgrif.application.engine.objects.petrinet.domain.PetriNet import com.netgrif.application.engine.objects.petrinet.domain.dataset.CaseField import com.netgrif.application.engine.objects.petrinet.domain.dataset.Field import com.netgrif.application.engine.objects.petrinet.domain.dataset.FieldWithAllowedNets +import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole import com.netgrif.application.engine.objects.workflow.domain.Case import com.netgrif.application.engine.objects.workflow.domain.ProcessResourceId import com.netgrif.application.engine.objects.workflow.domain.Task @@ -59,10 +60,30 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { @Override void migrate() { - Query query = Query.query(Criteria.where("_id.shortProcessId").exists(true)) - query.cursorBatchSize(500) + Query roleQuery = Query.query(Criteria.where("_id.shortProcessId").exists(true)) + roleQuery.cursorBatchSize(500) + try (Stream cursorStream = mongoTemplate.stream(roleQuery, ProcessRole.class)) { + Iterator cursor = cursorStream.iterator() + while (cursor.hasNext()) { + ProcessRole processRole = cursor.next() + + if (processRole.isGlobal()) { + continue + } + + ProcessResourceId oldRoleId = processRole.get_id(); + oldRoleId.setShortProcessIdentifier(null) + ProcessResourceId newRoleId = new ProcessResourceId(processRole.getProcessIdentifier(), oldRoleId.getObjectId()) + processRole.set_id(newRoleId) - try (Stream cursorStream = mongoTemplate.stream(query, Case.class)) { + mongoTemplate.insert(processRole) + mongoTemplate.remove(Query.query(Criteria.where("_id").is(oldRoleId)), ProcessRole.class) + } + } + + Query caseQuery = Query.query(Criteria.where("_id.shortProcessId").exists(true)) + caseQuery.cursorBatchSize(500) + try (Stream cursorStream = mongoTemplate.stream(caseQuery, Case.class)) { Iterator cursor = cursorStream.iterator() while (cursor.hasNext()) { @@ -98,6 +119,105 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { useCase.setTasks(newTaskPairs) } + if (useCase.getEnabledRoles() != null && !useCase.getEnabledRoles().isEmpty()) { + Set newValues = new HashSet<>() + useCase.getEnabledRoles().each { oldRoleId -> + String[] parts = oldRoleId.split(ProcessResourceId.ID_SEPARATOR); + if (parts.length != 2) { + throw new IllegalArgumentException("Invalid composite ID format: " + oldRoleId); + } + String processId = ProcessResourceId.decodeShortProcessId(parts[0]) + if (processIdentifierIdMap.containsKey(processId)) { + newValues.add(new ProcessResourceId(processIdentifierIdMap.get(processId), parts[1]).toString()) + } else { + try { + PetriNet petriNet = mongoTemplate.findById(new ObjectId(processId), PetriNet.class) + if (petriNet != null) { + processIdentifierIdMap.put(processId, petriNet.getIdentifier()) + newValues.add(new ProcessResourceId(petriNet.getIdentifier(), parts[1]).toString()) + } + } catch (IllegalArgumentException e) { + log.error("Error while update reference fields", e) + } + } + } + useCase.setEnabledRoles(newValues) + } + if (useCase.getViewRoles() != null && !useCase.getViewRoles().isEmpty()) { + List newValues = new ArrayList<>() + useCase.getViewRoles().each { oldRoleId -> + String[] parts = oldRoleId.split(ProcessResourceId.ID_SEPARATOR); + if (parts.length != 2) { + throw new IllegalArgumentException("Invalid composite ID format: " + oldRoleId); + } + String processId = ProcessResourceId.decodeShortProcessId(parts[0]) + if (processIdentifierIdMap.containsKey(processId)) { + newValues.add(new ProcessResourceId(processIdentifierIdMap.get(processId), parts[1]).toString()) + } else { + try { + PetriNet petriNet = mongoTemplate.findById(new ObjectId(processId), PetriNet.class) + if (petriNet != null) { + processIdentifierIdMap.put(processId, petriNet.getIdentifier()) + newValues.add(new ProcessResourceId(petriNet.getIdentifier(), parts[1]).toString()) + } + } catch (IllegalArgumentException e) { + log.error("Error while update reference fields", e) + } + } + } + useCase.setViewRoles(newValues) + } + + if (useCase.getNegativeViewRoles() != null && !useCase.getNegativeViewRoles().isEmpty()) { + List newValues = new ArrayList<>() + useCase.getNegativeViewRoles().each { oldRoleId -> + String[] parts = oldRoleId.split(ProcessResourceId.ID_SEPARATOR); + if (parts.length != 2) { + throw new IllegalArgumentException("Invalid composite ID format: " + oldRoleId); + } + String processId = ProcessResourceId.decodeShortProcessId(parts[0]) + if (processIdentifierIdMap.containsKey(processId)) { + newValues.add(new ProcessResourceId(processIdentifierIdMap.get(processId), parts[1]).toString()) + } else { + try { + PetriNet petriNet = mongoTemplate.findById(new ObjectId(processId), PetriNet.class) + if (petriNet != null) { + processIdentifierIdMap.put(processId, petriNet.getIdentifier()) + newValues.add(new ProcessResourceId(petriNet.getIdentifier(), parts[1]).toString()) + } + } catch (IllegalArgumentException e) { + log.error("Error while update reference fields", e) + } + } + } + useCase.setNegativeViewRoles(newValues) + } + + if (useCase.getPermissions() != null && !useCase.getPermissions().isEmpty()) { + Map> newValues = new HashMap<>() + useCase.getPermissions().each { oldRoleId, permissions -> + String[] parts = oldRoleId.split(ProcessResourceId.ID_SEPARATOR); + if (parts.length != 2) { + throw new IllegalArgumentException("Invalid composite ID format: " + oldRoleId); + } + String processId = ProcessResourceId.decodeShortProcessId(parts[0]) + if (processIdentifierIdMap.containsKey(processId)) { + newValues.put(new ProcessResourceId(processIdentifierIdMap.get(processId), parts[1]).toString(), permissions) + } else { + try { + PetriNet petriNet = mongoTemplate.findById(new ObjectId(processId), PetriNet.class) + if (petriNet != null) { + processIdentifierIdMap.put(processId, petriNet.getIdentifier()) + newValues.put(new ProcessResourceId(petriNet.getIdentifier(), parts[1]).toString(), permissions) + } + } catch (IllegalArgumentException e) { + log.error("Error while update reference fields", e) + } + } + } + useCase.setPermissions(newValues) + } + useCase.dataSet.each { key, dataField -> Field field = useCase.getField(key) if (field instanceof FieldWithAllowedNets) { From 8963d05674dcd20f33b4ad695b1e946de5adfdf6 Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Thu, 16 Jul 2026 15:53:16 +0200 Subject: [PATCH 09/14] Refactor `ProcessResourceIdMigration` to simplify role ID migrations and centralize ID translation logic with `getNewIdFromOldId`. --- .../ProcessResourceIdMigration.groovy | 179 +++++++++--------- 1 file changed, 89 insertions(+), 90 deletions(-) diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy index a860bd41ba..257d9e9a2d 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy @@ -22,6 +22,7 @@ import org.springframework.beans.factory.annotation.Qualifier import org.springframework.data.mongodb.core.MongoTemplate import org.springframework.data.mongodb.core.query.Criteria import org.springframework.data.mongodb.core.query.Query +import org.springframework.data.mongodb.core.query.Update import org.springframework.stereotype.Component import java.util.stream.Stream @@ -97,6 +98,43 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { continue } + + if (!processIdentifierIdMap.containsKey(useCase.getPetriNetId())) { + PetriNet petriNet = mongoTemplate.findById(useCase.getPetriNetObjectId(), PetriNet.class) + processIdentifierIdMap.put(petriNet.getStringId(), petriNet.getIdentifier()) + + if (petriNet.getRoles() != null && !petriNet.getRoles().isEmpty()) { + Map newValues = new LinkedHashMap<>() + petriNet.getRoles().each { oldRoleStringId, processRole -> + ProcessResourceId oldRoleId = processRole.get_id() + oldRoleId.setShortProcessIdentifier(null) + ProcessResourceId newRoleId = new ProcessResourceId(processRole.getProcessIdentifier(), oldRoleId.getObjectId()) + processRole.set_id(newRoleId) + + mongoTemplate.insert(processRole) + mongoTemplate.remove(Query.query(Criteria.where("_id").is(oldRoleId)), ProcessRole.class) + + newValues.put(newRoleId.toString(), processRole) + } + petriNet.setRoles(newValues) + } + if (petriNet.getPermissions() != null && !petriNet.getPermissions().isEmpty()) { + Map> newValues = new HashMap<>() + petriNet.getPermissions().each { oldRoleId, permissions -> + newValues.put(getNewIdFromOldId(oldRoleId), permissions) + } + petriNet.setPermissions(newValues) + } + if (petriNet.getNegativeViewRoles() != null && !petriNet.getNegativeViewRoles().isEmpty()) { + List newValues = new ArrayList<>() + petriNet.getNegativeViewRoles().each { oldRoleId -> + newValues.add(getNewIdFromOldId(oldRoleId)) + } + petriNet.setNegativeViewRoles(newValues) + } + mongoTemplate.save(petriNet) + } + if (useCase.getTasks() != null && !useCase.getTasks().isEmpty()) { Set newTaskPairs = new HashSet<>() List oldTasks = mongoTemplate.find(Query.query(Criteria.where("caseId").is(oldCaseId.shortProcessId + ProcessResourceId.ID_SEPARATOR + oldCaseId.getObjectId().toString())), Task.class) @@ -109,6 +147,31 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { it.setProcessIdentifier(useCase.getProcessIdentifier()) it.setCaseId(newCaseId.toString()) } + + if (it.getRoles() != null && !it.getRoles().isEmpty()) { + Map> newValues = new HashMap<>() + it.getRoles().each { oldRoleId, permissions -> + newValues.put(getNewIdFromOldId(oldRoleId), permissions) + } + it.setRoles(newValues) + } + + if (it.getViewRoles() != null && !it.getViewRoles().isEmpty()) { + List newValues = new ArrayList<>() + it.getViewRoles().each { oldRoleId -> + newValues.add(getNewIdFromOldId(oldRoleId)) + } + it.setViewRoles(newValues) + } + + if (it.getNegativeViewRoles() != null && !it.getNegativeViewRoles().isEmpty()) { + List newValues = new ArrayList<>() + it.getNegativeViewRoles().each { oldRoleId -> + newValues.add(getNewIdFromOldId(oldRoleId)) + } + it.setNegativeViewRoles(newValues) + } + mongoTemplate.insert(it) mongoTemplate.remove(Query.query(Criteria.where("_id").is(oldTaskId)), Task.class) @@ -122,48 +185,14 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { if (useCase.getEnabledRoles() != null && !useCase.getEnabledRoles().isEmpty()) { Set newValues = new HashSet<>() useCase.getEnabledRoles().each { oldRoleId -> - String[] parts = oldRoleId.split(ProcessResourceId.ID_SEPARATOR); - if (parts.length != 2) { - throw new IllegalArgumentException("Invalid composite ID format: " + oldRoleId); - } - String processId = ProcessResourceId.decodeShortProcessId(parts[0]) - if (processIdentifierIdMap.containsKey(processId)) { - newValues.add(new ProcessResourceId(processIdentifierIdMap.get(processId), parts[1]).toString()) - } else { - try { - PetriNet petriNet = mongoTemplate.findById(new ObjectId(processId), PetriNet.class) - if (petriNet != null) { - processIdentifierIdMap.put(processId, petriNet.getIdentifier()) - newValues.add(new ProcessResourceId(petriNet.getIdentifier(), parts[1]).toString()) - } - } catch (IllegalArgumentException e) { - log.error("Error while update reference fields", e) - } - } + newValues.add(getNewIdFromOldId(oldRoleId)) } useCase.setEnabledRoles(newValues) } if (useCase.getViewRoles() != null && !useCase.getViewRoles().isEmpty()) { List newValues = new ArrayList<>() useCase.getViewRoles().each { oldRoleId -> - String[] parts = oldRoleId.split(ProcessResourceId.ID_SEPARATOR); - if (parts.length != 2) { - throw new IllegalArgumentException("Invalid composite ID format: " + oldRoleId); - } - String processId = ProcessResourceId.decodeShortProcessId(parts[0]) - if (processIdentifierIdMap.containsKey(processId)) { - newValues.add(new ProcessResourceId(processIdentifierIdMap.get(processId), parts[1]).toString()) - } else { - try { - PetriNet petriNet = mongoTemplate.findById(new ObjectId(processId), PetriNet.class) - if (petriNet != null) { - processIdentifierIdMap.put(processId, petriNet.getIdentifier()) - newValues.add(new ProcessResourceId(petriNet.getIdentifier(), parts[1]).toString()) - } - } catch (IllegalArgumentException e) { - log.error("Error while update reference fields", e) - } - } + newValues.add(getNewIdFromOldId(oldRoleId)) } useCase.setViewRoles(newValues) } @@ -171,24 +200,7 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { if (useCase.getNegativeViewRoles() != null && !useCase.getNegativeViewRoles().isEmpty()) { List newValues = new ArrayList<>() useCase.getNegativeViewRoles().each { oldRoleId -> - String[] parts = oldRoleId.split(ProcessResourceId.ID_SEPARATOR); - if (parts.length != 2) { - throw new IllegalArgumentException("Invalid composite ID format: " + oldRoleId); - } - String processId = ProcessResourceId.decodeShortProcessId(parts[0]) - if (processIdentifierIdMap.containsKey(processId)) { - newValues.add(new ProcessResourceId(processIdentifierIdMap.get(processId), parts[1]).toString()) - } else { - try { - PetriNet petriNet = mongoTemplate.findById(new ObjectId(processId), PetriNet.class) - if (petriNet != null) { - processIdentifierIdMap.put(processId, petriNet.getIdentifier()) - newValues.add(new ProcessResourceId(petriNet.getIdentifier(), parts[1]).toString()) - } - } catch (IllegalArgumentException e) { - log.error("Error while update reference fields", e) - } - } + newValues.add(getNewIdFromOldId(oldRoleId)) } useCase.setNegativeViewRoles(newValues) } @@ -196,24 +208,7 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { if (useCase.getPermissions() != null && !useCase.getPermissions().isEmpty()) { Map> newValues = new HashMap<>() useCase.getPermissions().each { oldRoleId, permissions -> - String[] parts = oldRoleId.split(ProcessResourceId.ID_SEPARATOR); - if (parts.length != 2) { - throw new IllegalArgumentException("Invalid composite ID format: " + oldRoleId); - } - String processId = ProcessResourceId.decodeShortProcessId(parts[0]) - if (processIdentifierIdMap.containsKey(processId)) { - newValues.put(new ProcessResourceId(processIdentifierIdMap.get(processId), parts[1]).toString(), permissions) - } else { - try { - PetriNet petriNet = mongoTemplate.findById(new ObjectId(processId), PetriNet.class) - if (petriNet != null) { - processIdentifierIdMap.put(processId, petriNet.getIdentifier()) - newValues.put(new ProcessResourceId(petriNet.getIdentifier(), parts[1]).toString(), permissions) - } - } catch (IllegalArgumentException e) { - log.error("Error while update reference fields", e) - } - } + newValues.put(getNewIdFromOldId(oldRoleId), permissions) } useCase.setPermissions(newValues) } @@ -225,24 +220,7 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { List newValues = new ArrayList<>() if (oldValues != null) { oldValues.forEach { oldStringId -> - String[] parts = oldStringId.split(ProcessResourceId.ID_SEPARATOR); - if (parts.length != 2) { - throw new IllegalArgumentException("Invalid composite ID format: " + oldStringId); - } - String processId = ProcessResourceId.decodeShortProcessId(parts[0]) - if (processIdentifierIdMap.containsKey(processId)) { - newValues.add(new ProcessResourceId(processIdentifierIdMap.get(processId), parts[1]).toString()) - } else { - try { - PetriNet petriNet = mongoTemplate.findById(new ObjectId(processId), PetriNet.class) - if (petriNet != null) { - processIdentifierIdMap.put(processId, petriNet.getIdentifier()) - newValues.add(new ProcessResourceId(petriNet.getIdentifier(), parts[1]).toString()) - } - } catch (IllegalArgumentException e) { - log.error("Error while update reference fields", e) - } - } + newValues.add(getNewIdFromOldId(oldStringId)) } } dataField.setValue(newValues) @@ -258,4 +236,25 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { } } } + + String getNewIdFromOldId(String oldId) { + String[] parts = oldId.split(ProcessResourceId.ID_SEPARATOR); + if (parts.length != 2) { + throw new IllegalArgumentException("Invalid composite ID format: " + oldId); + } + String processId = ProcessResourceId.decodeShortProcessId(parts[0]) + if (processIdentifierIdMap.containsKey(processId)) { + return new ProcessResourceId(processIdentifierIdMap.get(processId), parts[1]).toString() + } else { + try { + PetriNet petriNet = mongoTemplate.findById(new ObjectId(processId), PetriNet.class) + if (petriNet != null) { + processIdentifierIdMap.put(processId, petriNet.getIdentifier()) + return new ProcessResourceId(petriNet.getIdentifier(), parts[1]).toString() + } + } catch (IllegalArgumentException e) { + log.error("Error while update reference fields", e) + } + } + } } From f14d0faa3cfed2fae57218767675a760ec0fe72f Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Thu, 16 Jul 2026 15:57:46 +0200 Subject: [PATCH 10/14] Refactor `ProcessResourceIdMigration` to simplify role ID migrations and centralize ID translation logic with `getNewIdFromOldId`. --- .../ProcessResourceIdMigration.groovy | 76 ++++++++++++++----- 1 file changed, 58 insertions(+), 18 deletions(-) diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy index 257d9e9a2d..62c80da136 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy @@ -106,29 +106,41 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { if (petriNet.getRoles() != null && !petriNet.getRoles().isEmpty()) { Map newValues = new LinkedHashMap<>() petriNet.getRoles().each { oldRoleStringId, processRole -> - ProcessResourceId oldRoleId = processRole.get_id() - oldRoleId.setShortProcessIdentifier(null) - ProcessResourceId newRoleId = new ProcessResourceId(processRole.getProcessIdentifier(), oldRoleId.getObjectId()) - processRole.set_id(newRoleId) - - mongoTemplate.insert(processRole) - mongoTemplate.remove(Query.query(Criteria.where("_id").is(oldRoleId)), ProcessRole.class) - - newValues.put(newRoleId.toString(), processRole) + if (!processRole.isGlobal()) { + ProcessResourceId oldRoleId = processRole.get_id() + oldRoleId.setShortProcessIdentifier(null) + ProcessResourceId newRoleId = new ProcessResourceId(processRole.getProcessIdentifier(), oldRoleId.getObjectId()) + processRole.set_id(newRoleId) + + mongoTemplate.insert(processRole) + mongoTemplate.remove(Query.query(Criteria.where("_id").is(oldRoleId)), ProcessRole.class) + + newValues.put(newRoleId.toString(), processRole) + } else { + newValues.put(oldRoleStringId, processRole) + } } petriNet.setRoles(newValues) } if (petriNet.getPermissions() != null && !petriNet.getPermissions().isEmpty()) { Map> newValues = new HashMap<>() petriNet.getPermissions().each { oldRoleId, permissions -> - newValues.put(getNewIdFromOldId(oldRoleId), permissions) + if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { + newValues.put(getNewIdFromOldId(oldRoleId), permissions) + } else { + newValues.put(oldRoleId, permissions) + } } petriNet.setPermissions(newValues) } if (petriNet.getNegativeViewRoles() != null && !petriNet.getNegativeViewRoles().isEmpty()) { List newValues = new ArrayList<>() petriNet.getNegativeViewRoles().each { oldRoleId -> - newValues.add(getNewIdFromOldId(oldRoleId)) + if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { + newValues.add(getNewIdFromOldId(oldRoleId)) + } else { + newValues.add(oldRoleId) + } } petriNet.setNegativeViewRoles(newValues) } @@ -151,7 +163,11 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { if (it.getRoles() != null && !it.getRoles().isEmpty()) { Map> newValues = new HashMap<>() it.getRoles().each { oldRoleId, permissions -> - newValues.put(getNewIdFromOldId(oldRoleId), permissions) + if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { + newValues.put(getNewIdFromOldId(oldRoleId), permissions) + } else { + newValues.put(oldRoleId, permissions) + } } it.setRoles(newValues) } @@ -159,7 +175,11 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { if (it.getViewRoles() != null && !it.getViewRoles().isEmpty()) { List newValues = new ArrayList<>() it.getViewRoles().each { oldRoleId -> - newValues.add(getNewIdFromOldId(oldRoleId)) + if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { + newValues.add(getNewIdFromOldId(oldRoleId)) + } else { + newValues.add(oldRoleId) + } } it.setViewRoles(newValues) } @@ -167,7 +187,11 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { if (it.getNegativeViewRoles() != null && !it.getNegativeViewRoles().isEmpty()) { List newValues = new ArrayList<>() it.getNegativeViewRoles().each { oldRoleId -> - newValues.add(getNewIdFromOldId(oldRoleId)) + if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { + newValues.add(getNewIdFromOldId(oldRoleId)) + } else { + newValues.add(oldRoleId) + } } it.setNegativeViewRoles(newValues) } @@ -185,14 +209,22 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { if (useCase.getEnabledRoles() != null && !useCase.getEnabledRoles().isEmpty()) { Set newValues = new HashSet<>() useCase.getEnabledRoles().each { oldRoleId -> - newValues.add(getNewIdFromOldId(oldRoleId)) + if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { + newValues.add(getNewIdFromOldId(oldRoleId)) + } else { + newValues.add(oldRoleId) + } } useCase.setEnabledRoles(newValues) } if (useCase.getViewRoles() != null && !useCase.getViewRoles().isEmpty()) { List newValues = new ArrayList<>() useCase.getViewRoles().each { oldRoleId -> - newValues.add(getNewIdFromOldId(oldRoleId)) + if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { + newValues.add(getNewIdFromOldId(oldRoleId)) + } else { + newValues.add(oldRoleId) + } } useCase.setViewRoles(newValues) } @@ -200,7 +232,11 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { if (useCase.getNegativeViewRoles() != null && !useCase.getNegativeViewRoles().isEmpty()) { List newValues = new ArrayList<>() useCase.getNegativeViewRoles().each { oldRoleId -> - newValues.add(getNewIdFromOldId(oldRoleId)) + if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { + newValues.add(getNewIdFromOldId(oldRoleId)) + } else { + newValues.add(oldRoleId) + } } useCase.setNegativeViewRoles(newValues) } @@ -208,7 +244,11 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { if (useCase.getPermissions() != null && !useCase.getPermissions().isEmpty()) { Map> newValues = new HashMap<>() useCase.getPermissions().each { oldRoleId, permissions -> - newValues.put(getNewIdFromOldId(oldRoleId), permissions) + if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { + newValues.put(getNewIdFromOldId(oldRoleId), permissions) + } else { + newValues.put(oldRoleId, permissions) + } } useCase.setPermissions(newValues) } From 131ce3a7b6f48bacb8e3bc1eb5885f34fc801d45 Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Fri, 17 Jul 2026 10:17:12 +0200 Subject: [PATCH 11/14] Refactor `ProcessResourceIdMigration` by extracting reusable methods for task and Petri net migration logic, adding `@ConditionalOnProperty` for configurability, and improving clarity in variable naming. --- .../ProcessResourceIdMigration.groovy | 280 +++++++++--------- 1 file changed, 136 insertions(+), 144 deletions(-) diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy index 62c80da136..084bd10561 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy @@ -1,14 +1,10 @@ package com.netgrif.application.engine.migration import com.netgrif.application.engine.elastic.service.ElasticCaseService -import com.netgrif.application.engine.elastic.service.ElasticIndexService -import com.netgrif.application.engine.elastic.service.ElasticTaskMappingService import com.netgrif.application.engine.elastic.service.ElasticTaskService import com.netgrif.application.engine.elastic.service.interfaces.IElasticCaseMappingService import com.netgrif.application.engine.elastic.service.interfaces.IElasticTaskMappingService -import com.netgrif.application.engine.objects.elastic.domain.TaskField import com.netgrif.application.engine.objects.petrinet.domain.PetriNet -import com.netgrif.application.engine.objects.petrinet.domain.dataset.CaseField import com.netgrif.application.engine.objects.petrinet.domain.dataset.Field import com.netgrif.application.engine.objects.petrinet.domain.dataset.FieldWithAllowedNets import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole @@ -19,23 +15,24 @@ import com.netgrif.application.engine.objects.workflow.domain.TaskPair import groovy.util.logging.Slf4j import org.bson.types.ObjectId import org.springframework.beans.factory.annotation.Qualifier +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty import org.springframework.data.mongodb.core.MongoTemplate import org.springframework.data.mongodb.core.query.Criteria import org.springframework.data.mongodb.core.query.Query -import org.springframework.data.mongodb.core.query.Update import org.springframework.stereotype.Component import java.util.stream.Stream @Slf4j @Component +@ConditionalOnProperty(value = "netgrif.engine.migration.process-resource-id-migration.enabled", havingValue = "true") class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { MigrationHelper migrationHelper MongoTemplate mongoTemplate - Map processIdentifierIdMap = new HashMap<>() + Map processIdIdentifierMap = new HashMap<>() ElasticCaseService elasticCaseService @@ -61,27 +58,6 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { @Override void migrate() { - Query roleQuery = Query.query(Criteria.where("_id.shortProcessId").exists(true)) - roleQuery.cursorBatchSize(500) - try (Stream cursorStream = mongoTemplate.stream(roleQuery, ProcessRole.class)) { - Iterator cursor = cursorStream.iterator() - while (cursor.hasNext()) { - ProcessRole processRole = cursor.next() - - if (processRole.isGlobal()) { - continue - } - - ProcessResourceId oldRoleId = processRole.get_id(); - oldRoleId.setShortProcessIdentifier(null) - ProcessResourceId newRoleId = new ProcessResourceId(processRole.getProcessIdentifier(), oldRoleId.getObjectId()) - processRole.set_id(newRoleId) - - mongoTemplate.insert(processRole) - mongoTemplate.remove(Query.query(Criteria.where("_id").is(oldRoleId)), ProcessRole.class) - } - } - Query caseQuery = Query.query(Criteria.where("_id.shortProcessId").exists(true)) caseQuery.cursorBatchSize(500) try (Stream cursorStream = mongoTemplate.stream(caseQuery, Case.class)) { @@ -98,126 +74,17 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { continue } - - if (!processIdentifierIdMap.containsKey(useCase.getPetriNetId())) { - PetriNet petriNet = mongoTemplate.findById(useCase.getPetriNetObjectId(), PetriNet.class) - processIdentifierIdMap.put(petriNet.getStringId(), petriNet.getIdentifier()) - - if (petriNet.getRoles() != null && !petriNet.getRoles().isEmpty()) { - Map newValues = new LinkedHashMap<>() - petriNet.getRoles().each { oldRoleStringId, processRole -> - if (!processRole.isGlobal()) { - ProcessResourceId oldRoleId = processRole.get_id() - oldRoleId.setShortProcessIdentifier(null) - ProcessResourceId newRoleId = new ProcessResourceId(processRole.getProcessIdentifier(), oldRoleId.getObjectId()) - processRole.set_id(newRoleId) - - mongoTemplate.insert(processRole) - mongoTemplate.remove(Query.query(Criteria.where("_id").is(oldRoleId)), ProcessRole.class) - - newValues.put(newRoleId.toString(), processRole) - } else { - newValues.put(oldRoleStringId, processRole) - } - } - petriNet.setRoles(newValues) - } - if (petriNet.getPermissions() != null && !petriNet.getPermissions().isEmpty()) { - Map> newValues = new HashMap<>() - petriNet.getPermissions().each { oldRoleId, permissions -> - if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { - newValues.put(getNewIdFromOldId(oldRoleId), permissions) - } else { - newValues.put(oldRoleId, permissions) - } - } - petriNet.setPermissions(newValues) - } - if (petriNet.getNegativeViewRoles() != null && !petriNet.getNegativeViewRoles().isEmpty()) { - List newValues = new ArrayList<>() - petriNet.getNegativeViewRoles().each { oldRoleId -> - if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { - newValues.add(getNewIdFromOldId(oldRoleId)) - } else { - newValues.add(oldRoleId) - } - } - petriNet.setNegativeViewRoles(newValues) - } - mongoTemplate.save(petriNet) - } + migratePetriNet(useCase) if (useCase.getTasks() != null && !useCase.getTasks().isEmpty()) { - Set newTaskPairs = new HashSet<>() - List oldTasks = mongoTemplate.find(Query.query(Criteria.where("caseId").is(oldCaseId.shortProcessId + ProcessResourceId.ID_SEPARATOR + oldCaseId.getObjectId().toString())), Task.class) - oldTasks.forEach { - ProcessResourceId oldTaskId = it.get_id() - oldTaskId.setShortProcessIdentifier(null) - ProcessResourceId newTaskId = new ProcessResourceId(useCase.getProcessIdentifier(), oldTaskId.getObjectId()) - if (newTaskId != oldTaskId) { - it.set_id(newTaskId) - it.setProcessIdentifier(useCase.getProcessIdentifier()) - it.setCaseId(newCaseId.toString()) - } - - if (it.getRoles() != null && !it.getRoles().isEmpty()) { - Map> newValues = new HashMap<>() - it.getRoles().each { oldRoleId, permissions -> - if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { - newValues.put(getNewIdFromOldId(oldRoleId), permissions) - } else { - newValues.put(oldRoleId, permissions) - } - } - it.setRoles(newValues) - } - - if (it.getViewRoles() != null && !it.getViewRoles().isEmpty()) { - List newValues = new ArrayList<>() - it.getViewRoles().each { oldRoleId -> - if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { - newValues.add(getNewIdFromOldId(oldRoleId)) - } else { - newValues.add(oldRoleId) - } - } - it.setViewRoles(newValues) - } - - if (it.getNegativeViewRoles() != null && !it.getNegativeViewRoles().isEmpty()) { - List newValues = new ArrayList<>() - it.getNegativeViewRoles().each { oldRoleId -> - if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { - newValues.add(getNewIdFromOldId(oldRoleId)) - } else { - newValues.add(oldRoleId) - } - } - it.setNegativeViewRoles(newValues) - } - - mongoTemplate.insert(it) - mongoTemplate.remove(Query.query(Criteria.where("_id").is(oldTaskId)), Task.class) - - elasticTaskService.index(elasticTaskMappingService.transform(it)) - elasticTaskService.remove(oldTaskId.getStringId()) - newTaskPairs.add(new TaskPair(newTaskId.toString(), it.transitionId)) - } - useCase.setTasks(newTaskPairs) + migrateTasksOfCase(useCase, oldCaseId, newCaseId) } if (useCase.getEnabledRoles() != null && !useCase.getEnabledRoles().isEmpty()) { - Set newValues = new HashSet<>() - useCase.getEnabledRoles().each { oldRoleId -> - if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { - newValues.add(getNewIdFromOldId(oldRoleId)) - } else { - newValues.add(oldRoleId) - } - } - useCase.setEnabledRoles(newValues) + useCase.setEnabledRoles(new HashSet<>(migrateRoleIds(useCase.getEnabledRoles()))) } if (useCase.getViewRoles() != null && !useCase.getViewRoles().isEmpty()) { + useCase.setViewRoles(migr) List newValues = new ArrayList<>() useCase.getViewRoles().each { oldRoleId -> if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { @@ -277,19 +144,19 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { } } - String getNewIdFromOldId(String oldId) { + private String getNewIdFromOldId(String oldId) { String[] parts = oldId.split(ProcessResourceId.ID_SEPARATOR); if (parts.length != 2) { throw new IllegalArgumentException("Invalid composite ID format: " + oldId); } String processId = ProcessResourceId.decodeShortProcessId(parts[0]) - if (processIdentifierIdMap.containsKey(processId)) { - return new ProcessResourceId(processIdentifierIdMap.get(processId), parts[1]).toString() + if (processIdIdentifierMap.containsKey(processId)) { + return new ProcessResourceId(processIdIdentifierMap.get(processId), parts[1]).toString() } else { try { PetriNet petriNet = mongoTemplate.findById(new ObjectId(processId), PetriNet.class) if (petriNet != null) { - processIdentifierIdMap.put(processId, petriNet.getIdentifier()) + processIdIdentifierMap.put(processId, petriNet.getIdentifier()) return new ProcessResourceId(petriNet.getIdentifier(), parts[1]).toString() } } catch (IllegalArgumentException e) { @@ -297,4 +164,129 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { } } } + + private void migratePetriNet(Case useCase) { + if (!processIdIdentifierMap.containsKey(useCase.getPetriNetId())) { + PetriNet petriNet = mongoTemplate.findById(useCase.getPetriNetObjectId(), PetriNet.class) + processIdIdentifierMap.put(petriNet.getStringId(), petriNet.getIdentifier()) + + if (petriNet.getRoles() != null && !petriNet.getRoles().isEmpty()) { + migrateProcessRoles(petriNet) + } + + if (petriNet.getPermissions() != null && !petriNet.getPermissions().isEmpty()) { + petriNet.setPermissions(migratePetriNetPermissions(petriNet.getPermissions())) + } + if (petriNet.getNegativeViewRoles() != null && !petriNet.getNegativeViewRoles().isEmpty()) { + petriNet.setNegativeViewRoles(migrateRoleIds(petriNet.getNegativeViewRoles())) + } + mongoTemplate.save(petriNet) + } + } + + private void migrateTasksOfCase(Case useCase, ProcessResourceId oldCaseId, ProcessResourceId newCaseId) { + Set newTaskPairs = new HashSet<>() + List oldTasks = mongoTemplate.find(Query.query(Criteria.where("caseId").is(oldCaseId.shortProcessId + ProcessResourceId.ID_SEPARATOR + oldCaseId.getObjectId().toString())), Task.class) + oldTasks.forEach { task -> + migrateTask(useCase, newCaseId, newTaskPairs, task) + } + useCase.setTasks(newTaskPairs) + } + + private void migrateTask(Case useCase, ProcessResourceId newCaseId, Set newTaskPairs, Task task) { + ProcessResourceId oldTaskId = task.get_id() + oldTaskId.setShortProcessIdentifier(null) + ProcessResourceId newTaskId = new ProcessResourceId(useCase.getProcessIdentifier(), oldTaskId.getObjectId()) + if (newTaskId != oldTaskId) { + task.set_id(newTaskId) + task.setProcessIdentifier(useCase.getProcessIdentifier()) + task.setCaseId(newCaseId.toString()) + } + + if (task.getRoles() != null && !task.getRoles().isEmpty()) { + Map> newValues = new HashMap<>() + task.getRoles().each { oldRoleId, permissions -> + if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { + newValues.put(getNewIdFromOldId(oldRoleId), permissions) + } else { + newValues.put(oldRoleId, permissions) + } + } + task.setRoles(newValues) + } + + if (task.getViewRoles() != null && !task.getViewRoles().isEmpty()) { + List newValues = new ArrayList<>() + task.getViewRoles().each { oldRoleId -> + if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { + newValues.add(getNewIdFromOldId(oldRoleId)) + } else { + newValues.add(oldRoleId) + } + } + task.setViewRoles(newValues) + } + + if (task.getNegativeViewRoles() != null && !task.getNegativeViewRoles().isEmpty()) { + List newValues = new ArrayList<>() + task.getNegativeViewRoles().each { oldRoleId -> + if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { + newValues.add(getNewIdFromOldId(oldRoleId)) + } else { + newValues.add(oldRoleId) + } + } + task.setNegativeViewRoles(newValues) + } + + mongoTemplate.insert(task) + mongoTemplate.remove(Query.query(Criteria.where("_id").is(oldTaskId)), Task.class) + + elasticTaskService.index(elasticTaskMappingService.transform(task)) + elasticTaskService.remove(oldTaskId.getStringId()) + newTaskPairs.add(new TaskPair(newTaskId.toString(), task.transitionId)) + } + + private void migrateProcessRoles(PetriNet petriNet) { + Map newValues = new LinkedHashMap<>() + petriNet.getRoles().each { oldRoleStringId, processRole -> + if (!processRole.isGlobal()) { + ProcessResourceId oldRoleId = processRole.get_id() + oldRoleId.setShortProcessIdentifier(null) + ProcessResourceId newRoleId = new ProcessResourceId(processRole.getProcessIdentifier(), oldRoleId.getObjectId()) + processRole.set_id(newRoleId) + + mongoTemplate.insert(processRole) + mongoTemplate.remove(Query.query(Criteria.where("_id").is(oldRoleId)), ProcessRole.class) + + newValues.put(newRoleId.toString(), processRole) + } else { + newValues.put(oldRoleStringId, processRole) + } + } + petriNet.setRoles(newValues) + } + + private Map> migratePetriNetPermissions(Map> rolePermissionMap) { + Map> newValues = new HashMap<>() + rolePermissionMap.each { oldRoleId, permissions -> + if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { + newValues.put(getNewIdFromOldId(oldRoleId), permissions) + } else { + newValues.put(oldRoleId, permissions) + } + } + } + + private List migrateRoleIds(Collection oldRoleIds) { + List newValues = new ArrayList<>() + oldRoleIds.each { oldRoleId -> + if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { + newValues.add(getNewIdFromOldId(oldRoleId)) + } else { + newValues.add(oldRoleId) + } + } + return newValues; + } } From 5b2c4e254bf126e4ffc10efc2e91890c231645a2 Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Fri, 17 Jul 2026 10:55:45 +0200 Subject: [PATCH 12/14] Refactor `ProcessResourceIdMigration` by extracting methods for case permission and data field migration --- .../ProcessResourceIdMigration.groovy | 92 ++++++++----------- 1 file changed, 37 insertions(+), 55 deletions(-) diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy index 084bd10561..4ac12293ce 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy @@ -76,63 +76,11 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { migratePetriNet(useCase) - if (useCase.getTasks() != null && !useCase.getTasks().isEmpty()) { - migrateTasksOfCase(useCase, oldCaseId, newCaseId) - } + migrateTasksOfCase(useCase, oldCaseId, newCaseId) - if (useCase.getEnabledRoles() != null && !useCase.getEnabledRoles().isEmpty()) { - useCase.setEnabledRoles(new HashSet<>(migrateRoleIds(useCase.getEnabledRoles()))) - } - if (useCase.getViewRoles() != null && !useCase.getViewRoles().isEmpty()) { - useCase.setViewRoles(migr) - List newValues = new ArrayList<>() - useCase.getViewRoles().each { oldRoleId -> - if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { - newValues.add(getNewIdFromOldId(oldRoleId)) - } else { - newValues.add(oldRoleId) - } - } - useCase.setViewRoles(newValues) - } + migrateCasePermissions(useCase) - if (useCase.getNegativeViewRoles() != null && !useCase.getNegativeViewRoles().isEmpty()) { - List newValues = new ArrayList<>() - useCase.getNegativeViewRoles().each { oldRoleId -> - if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { - newValues.add(getNewIdFromOldId(oldRoleId)) - } else { - newValues.add(oldRoleId) - } - } - useCase.setNegativeViewRoles(newValues) - } - - if (useCase.getPermissions() != null && !useCase.getPermissions().isEmpty()) { - Map> newValues = new HashMap<>() - useCase.getPermissions().each { oldRoleId, permissions -> - if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { - newValues.put(getNewIdFromOldId(oldRoleId), permissions) - } else { - newValues.put(oldRoleId, permissions) - } - } - useCase.setPermissions(newValues) - } - - useCase.dataSet.each { key, dataField -> - Field field = useCase.getField(key) - if (field instanceof FieldWithAllowedNets) { - List oldValues = (List) dataField.getValue() - List newValues = new ArrayList<>() - if (oldValues != null) { - oldValues.forEach { oldStringId -> - newValues.add(getNewIdFromOldId(oldStringId)) - } - } - dataField.setValue(newValues) - } - } + migrateDataFields(useCase) useCase.set_id(newCaseId) @@ -267,6 +215,39 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { petriNet.setRoles(newValues) } + private void migrateCasePermissions(Case useCase) { + if (useCase.getEnabledRoles() != null && !useCase.getEnabledRoles().isEmpty()) { + useCase.setEnabledRoles(new HashSet<>(migrateRoleIds(useCase.getEnabledRoles()))) + } + if (useCase.getViewRoles() != null && !useCase.getViewRoles().isEmpty()) { + useCase.setViewRoles(migrateRoleIds(useCase.getViewRoles())) + } + + if (useCase.getNegativeViewRoles() != null && !useCase.getNegativeViewRoles().isEmpty()) { + useCase.setNegativeViewRoles(migrateRoleIds(useCase.getNegativeViewRoles())) + } + + if (useCase.getPermissions() != null && !useCase.getPermissions().isEmpty()) { + useCase.setPermissions(migratePetriNetPermissions(useCase.getPermissions())) + } + } + + private void migrateDataFields(Case useCase) { + useCase.dataSet.each { key, dataField -> + Field field = useCase.getField(key) + if (field instanceof FieldWithAllowedNets) { + List oldValues = (List) dataField.getValue() + List newValues = new ArrayList<>() + if (oldValues != null) { + oldValues.forEach { oldStringId -> + newValues.add(getNewIdFromOldId(oldStringId)) + } + } + dataField.setValue(newValues) + } + } + } + private Map> migratePetriNetPermissions(Map> rolePermissionMap) { Map> newValues = new HashMap<>() rolePermissionMap.each { oldRoleId, permissions -> @@ -276,6 +257,7 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { newValues.put(oldRoleId, permissions) } } + return newValues } private List migrateRoleIds(Collection oldRoleIds) { From 6971dda798ade598acb5eff4a579943ce8226ce9 Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Fri, 17 Jul 2026 12:39:51 +0200 Subject: [PATCH 13/14] Refactor `ProcessResourceIdMigration` by extracting methods for case permission and data field migration --- .../ProcessResourceIdMigration.groovy | 30 ++----------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy index 4ac12293ce..33d052c636 100644 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy +++ b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy @@ -152,39 +152,15 @@ class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { } if (task.getRoles() != null && !task.getRoles().isEmpty()) { - Map> newValues = new HashMap<>() - task.getRoles().each { oldRoleId, permissions -> - if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { - newValues.put(getNewIdFromOldId(oldRoleId), permissions) - } else { - newValues.put(oldRoleId, permissions) - } - } - task.setRoles(newValues) + task.setRoles(migratePetriNetPermissions(task.getRoles())) } if (task.getViewRoles() != null && !task.getViewRoles().isEmpty()) { - List newValues = new ArrayList<>() - task.getViewRoles().each { oldRoleId -> - if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { - newValues.add(getNewIdFromOldId(oldRoleId)) - } else { - newValues.add(oldRoleId) - } - } - task.setViewRoles(newValues) + task.setViewRoles(migrateRoleIds(task.getViewRoles())) } if (task.getNegativeViewRoles() != null && !task.getNegativeViewRoles().isEmpty()) { - List newValues = new ArrayList<>() - task.getNegativeViewRoles().each { oldRoleId -> - if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { - newValues.add(getNewIdFromOldId(oldRoleId)) - } else { - newValues.add(oldRoleId) - } - } - task.setNegativeViewRoles(newValues) + task.setNegativeViewRoles(migrateRoleIds(task.getNegativeViewRoles())) } mongoTemplate.insert(task) From f11c250f1b9c37ee4a0e484ad9e7b4ae666a1c7b Mon Sep 17 00:00:00 2001 From: renczesstefan Date: Fri, 17 Jul 2026 13:30:06 +0200 Subject: [PATCH 14/14] Remove `ProcessResourceIdMigration` and related dependencies. --- .../ProcessResourceIdMigration.groovy | 250 ------------------ 1 file changed, 250 deletions(-) delete mode 100644 application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy deleted file mode 100644 index 33d052c636..0000000000 --- a/application-engine/src/main/groovy/com/netgrif/application/engine/migration/ProcessResourceIdMigration.groovy +++ /dev/null @@ -1,250 +0,0 @@ -package com.netgrif.application.engine.migration - -import com.netgrif.application.engine.elastic.service.ElasticCaseService -import com.netgrif.application.engine.elastic.service.ElasticTaskService -import com.netgrif.application.engine.elastic.service.interfaces.IElasticCaseMappingService -import com.netgrif.application.engine.elastic.service.interfaces.IElasticTaskMappingService -import com.netgrif.application.engine.objects.petrinet.domain.PetriNet -import com.netgrif.application.engine.objects.petrinet.domain.dataset.Field -import com.netgrif.application.engine.objects.petrinet.domain.dataset.FieldWithAllowedNets -import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole -import com.netgrif.application.engine.objects.workflow.domain.Case -import com.netgrif.application.engine.objects.workflow.domain.ProcessResourceId -import com.netgrif.application.engine.objects.workflow.domain.Task -import com.netgrif.application.engine.objects.workflow.domain.TaskPair -import groovy.util.logging.Slf4j -import org.bson.types.ObjectId -import org.springframework.beans.factory.annotation.Qualifier -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty -import org.springframework.data.mongodb.core.MongoTemplate -import org.springframework.data.mongodb.core.query.Criteria -import org.springframework.data.mongodb.core.query.Query -import org.springframework.stereotype.Component - -import java.util.stream.Stream - -@Slf4j -@Component -@ConditionalOnProperty(value = "netgrif.engine.migration.process-resource-id-migration.enabled", havingValue = "true") -class ProcessResourceIdMigration extends MigrationOrderedCommandLineRunner { - - MigrationHelper migrationHelper - - MongoTemplate mongoTemplate - - Map processIdIdentifierMap = new HashMap<>() - - ElasticCaseService elasticCaseService - - ElasticTaskService elasticTaskService - - IElasticCaseMappingService elasticCaseMappingService - - IElasticTaskMappingService elasticTaskMappingService - - ProcessResourceIdMigration(MigrationHelper migrationHelper, - @Qualifier("mongoTemplate") MongoTemplate mongoTemplate, - ElasticCaseService elasticCaseService, - ElasticTaskService elasticTaskService, - IElasticCaseMappingService elasticCaseMappingService, - IElasticTaskMappingService elasticTaskMappingService) { - this.migrationHelper = migrationHelper - this.mongoTemplate = mongoTemplate - this.elasticCaseService = elasticCaseService - this.elasticTaskService = elasticTaskService - this.elasticCaseMappingService = elasticCaseMappingService - this.elasticTaskMappingService = elasticTaskMappingService - } - - @Override - void migrate() { - Query caseQuery = Query.query(Criteria.where("_id.shortProcessId").exists(true)) - caseQuery.cursorBatchSize(500) - try (Stream cursorStream = mongoTemplate.stream(caseQuery, Case.class)) { - Iterator cursor = cursorStream.iterator() - - while (cursor.hasNext()) { - Case useCase = cursor.next() - - ProcessResourceId oldCaseId = useCase.get_id() - oldCaseId.setShortProcessIdentifier(null) - ProcessResourceId newCaseId = new ProcessResourceId(useCase.getProcessIdentifier(), oldCaseId.getObjectId()) - - if (newCaseId == oldCaseId) { - continue - } - - migratePetriNet(useCase) - - migrateTasksOfCase(useCase, oldCaseId, newCaseId) - - migrateCasePermissions(useCase) - - migrateDataFields(useCase) - - useCase.set_id(newCaseId) - - mongoTemplate.insert(useCase) - mongoTemplate.remove(Query.query(Criteria.where("_id").is(oldCaseId)), Case.class) - elasticCaseService.index(elasticCaseMappingService.transform(useCase)) - elasticCaseService.remove(oldCaseId.toString()) - } - } - } - - private String getNewIdFromOldId(String oldId) { - String[] parts = oldId.split(ProcessResourceId.ID_SEPARATOR); - if (parts.length != 2) { - throw new IllegalArgumentException("Invalid composite ID format: " + oldId); - } - String processId = ProcessResourceId.decodeShortProcessId(parts[0]) - if (processIdIdentifierMap.containsKey(processId)) { - return new ProcessResourceId(processIdIdentifierMap.get(processId), parts[1]).toString() - } else { - try { - PetriNet petriNet = mongoTemplate.findById(new ObjectId(processId), PetriNet.class) - if (petriNet != null) { - processIdIdentifierMap.put(processId, petriNet.getIdentifier()) - return new ProcessResourceId(petriNet.getIdentifier(), parts[1]).toString() - } - } catch (IllegalArgumentException e) { - log.error("Error while update reference fields", e) - } - } - } - - private void migratePetriNet(Case useCase) { - if (!processIdIdentifierMap.containsKey(useCase.getPetriNetId())) { - PetriNet petriNet = mongoTemplate.findById(useCase.getPetriNetObjectId(), PetriNet.class) - processIdIdentifierMap.put(petriNet.getStringId(), petriNet.getIdentifier()) - - if (petriNet.getRoles() != null && !petriNet.getRoles().isEmpty()) { - migrateProcessRoles(petriNet) - } - - if (petriNet.getPermissions() != null && !petriNet.getPermissions().isEmpty()) { - petriNet.setPermissions(migratePetriNetPermissions(petriNet.getPermissions())) - } - if (petriNet.getNegativeViewRoles() != null && !petriNet.getNegativeViewRoles().isEmpty()) { - petriNet.setNegativeViewRoles(migrateRoleIds(petriNet.getNegativeViewRoles())) - } - mongoTemplate.save(petriNet) - } - } - - private void migrateTasksOfCase(Case useCase, ProcessResourceId oldCaseId, ProcessResourceId newCaseId) { - Set newTaskPairs = new HashSet<>() - List oldTasks = mongoTemplate.find(Query.query(Criteria.where("caseId").is(oldCaseId.shortProcessId + ProcessResourceId.ID_SEPARATOR + oldCaseId.getObjectId().toString())), Task.class) - oldTasks.forEach { task -> - migrateTask(useCase, newCaseId, newTaskPairs, task) - } - useCase.setTasks(newTaskPairs) - } - - private void migrateTask(Case useCase, ProcessResourceId newCaseId, Set newTaskPairs, Task task) { - ProcessResourceId oldTaskId = task.get_id() - oldTaskId.setShortProcessIdentifier(null) - ProcessResourceId newTaskId = new ProcessResourceId(useCase.getProcessIdentifier(), oldTaskId.getObjectId()) - if (newTaskId != oldTaskId) { - task.set_id(newTaskId) - task.setProcessIdentifier(useCase.getProcessIdentifier()) - task.setCaseId(newCaseId.toString()) - } - - if (task.getRoles() != null && !task.getRoles().isEmpty()) { - task.setRoles(migratePetriNetPermissions(task.getRoles())) - } - - if (task.getViewRoles() != null && !task.getViewRoles().isEmpty()) { - task.setViewRoles(migrateRoleIds(task.getViewRoles())) - } - - if (task.getNegativeViewRoles() != null && !task.getNegativeViewRoles().isEmpty()) { - task.setNegativeViewRoles(migrateRoleIds(task.getNegativeViewRoles())) - } - - mongoTemplate.insert(task) - mongoTemplate.remove(Query.query(Criteria.where("_id").is(oldTaskId)), Task.class) - - elasticTaskService.index(elasticTaskMappingService.transform(task)) - elasticTaskService.remove(oldTaskId.getStringId()) - newTaskPairs.add(new TaskPair(newTaskId.toString(), task.transitionId)) - } - - private void migrateProcessRoles(PetriNet petriNet) { - Map newValues = new LinkedHashMap<>() - petriNet.getRoles().each { oldRoleStringId, processRole -> - if (!processRole.isGlobal()) { - ProcessResourceId oldRoleId = processRole.get_id() - oldRoleId.setShortProcessIdentifier(null) - ProcessResourceId newRoleId = new ProcessResourceId(processRole.getProcessIdentifier(), oldRoleId.getObjectId()) - processRole.set_id(newRoleId) - - mongoTemplate.insert(processRole) - mongoTemplate.remove(Query.query(Criteria.where("_id").is(oldRoleId)), ProcessRole.class) - - newValues.put(newRoleId.toString(), processRole) - } else { - newValues.put(oldRoleStringId, processRole) - } - } - petriNet.setRoles(newValues) - } - - private void migrateCasePermissions(Case useCase) { - if (useCase.getEnabledRoles() != null && !useCase.getEnabledRoles().isEmpty()) { - useCase.setEnabledRoles(new HashSet<>(migrateRoleIds(useCase.getEnabledRoles()))) - } - if (useCase.getViewRoles() != null && !useCase.getViewRoles().isEmpty()) { - useCase.setViewRoles(migrateRoleIds(useCase.getViewRoles())) - } - - if (useCase.getNegativeViewRoles() != null && !useCase.getNegativeViewRoles().isEmpty()) { - useCase.setNegativeViewRoles(migrateRoleIds(useCase.getNegativeViewRoles())) - } - - if (useCase.getPermissions() != null && !useCase.getPermissions().isEmpty()) { - useCase.setPermissions(migratePetriNetPermissions(useCase.getPermissions())) - } - } - - private void migrateDataFields(Case useCase) { - useCase.dataSet.each { key, dataField -> - Field field = useCase.getField(key) - if (field instanceof FieldWithAllowedNets) { - List oldValues = (List) dataField.getValue() - List newValues = new ArrayList<>() - if (oldValues != null) { - oldValues.forEach { oldStringId -> - newValues.add(getNewIdFromOldId(oldStringId)) - } - } - dataField.setValue(newValues) - } - } - } - - private Map> migratePetriNetPermissions(Map> rolePermissionMap) { - Map> newValues = new HashMap<>() - rolePermissionMap.each { oldRoleId, permissions -> - if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { - newValues.put(getNewIdFromOldId(oldRoleId), permissions) - } else { - newValues.put(oldRoleId, permissions) - } - } - return newValues - } - - private List migrateRoleIds(Collection oldRoleIds) { - List newValues = new ArrayList<>() - oldRoleIds.each { oldRoleId -> - if (!oldRoleId.startsWith(ProcessResourceId.NONE_SHORT_ID_VALUE)) { - newValues.add(getNewIdFromOldId(oldRoleId)) - } else { - newValues.add(oldRoleId) - } - } - return newValues; - } -}