This is an automated email from the ASF dual-hosted git repository.
egonzalez pushed a commit to branch main
in repository
https://gitbox.apache.org/repos/asf/incubator-kie-kogito-runtimes.git
The following commit(s) were added to refs/heads/main by this push:
new 5ef8b2f5b6 [incubator-kie-issues-1086] PIM revisited functionality
feature (#3472)
5ef8b2f5b6 is described below
commit 5ef8b2f5b666cf875be4db1a7f4087983dbbffd0
Author: Enrique <[email protected]>
AuthorDate: Fri Apr 19 11:50:04 2024 +0200
[incubator-kie-issues-1086] PIM revisited functionality feature (#3472)
* [incubator-kie-issues-1086] PIM revisited functionality feature
---
.../jbpm/flow/migration/MigrationPlanService.java | 76 ++++++++++++++++++---
.../impl/FileSystemMigrationPlanFileProvider.java | 8 ++-
...MigrationProcessInstanceMarshallerListener.java | 18 +++--
.../flow/migration/MigrationPlanProviderTest.java | 4 +-
.../flow/migration/MigrationPlanServiceTest.java | 79 +++++++++++++++++++---
.../META-INF/migration-plan/simple_migration.mpf | 6 +-
..._migration.mpf => simple_migration_version.mpf} | 0
7 files changed, 158 insertions(+), 33 deletions(-)
diff --git
a/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/MigrationPlanService.java
b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/MigrationPlanService.java
index 12951dfb16..662eefaf91 100644
---
a/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/MigrationPlanService.java
+++
b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/MigrationPlanService.java
@@ -25,14 +25,21 @@ import org.jbpm.flow.migration.model.MigrationPlan;
import org.jbpm.flow.migration.model.ProcessDefinitionMigrationPlan;
import org.jbpm.ruleflow.instance.RuleFlowProcessInstance;
import org.jbpm.workflow.instance.impl.NodeInstanceImpl;
+import org.kie.kogito.Model;
import org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcessInstance;
+import org.kie.kogito.process.Processes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.google.common.base.Functions.identity;
import static java.util.stream.Collectors.toMap;
+/**
+ * The migration system is limited in this way.
+ * Cannot have more that one identifier process deployed (version is fixed)
+ * if there are several migration plans defined for the same source only one
is taken into account
+ */
public class MigrationPlanService {
private static final Logger LOGGER =
LoggerFactory.getLogger(MigrationPlanService.class);
@@ -49,8 +56,8 @@ public class MigrationPlanService {
this.migrations.putAll(this.migrationPlanProvider.findMigrationPlans().stream().collect(toMap(MigrationPlan::getSource,
identity())));
}
- public void migrateProcessElement(KogitoWorkflowProcessInstance
processInstance) {
- MigrationPlan plan = getMigrationPlan(processInstance);
+ public void migrateProcessElement(Processes processes,
KogitoWorkflowProcessInstance processInstance) {
+ MigrationPlan plan = getMigrationPlan(processes, processInstance);
if (plan != null) {
// the process will have to do nothing as it is done by the engine
itself
LOGGER.info("Process instance {} will be migrated from {} to {}
with plan {}",
@@ -67,9 +74,9 @@ public class MigrationPlanService {
}
}
- public void migrateNodeElement(KogitoNodeInstance nodeInstance) {
+ public void migrateNodeElement(Processes processes, KogitoNodeInstance
nodeInstance) {
KogitoWorkflowProcessInstance pi = (KogitoWorkflowProcessInstance)
nodeInstance.getProcessInstance();
- MigrationPlan plan = getMigrationPlan(pi);
+ MigrationPlan plan = getMigrationPlan(processes, pi);
if (plan == null) {
return;
}
@@ -79,14 +86,63 @@ public class MigrationPlanService {
impl.setNodeId(plan.getProcessMigrationPlan().getNodeMigratedFor(nodeInstance));
}
- private MigrationPlan getMigrationPlan(KogitoWorkflowProcessInstance
processInstance) {
+ // we check the target deployed in the container is the same as the target
in the migration plan
+ private MigrationPlan getMigrationPlan(Processes processes,
KogitoWorkflowProcessInstance processInstance) {
+ // first check if we need a migration as the process being set should
be not be the same as the process set in the
+ // process being loaded.
+ String currentProcessId = processInstance.getProcess().getId();
+ String currentVersion = processInstance.getProcess().getVersion();
+ ProcessDefinitionMigrationPlan currentProcessDefinition = new
ProcessDefinitionMigrationPlan(currentProcessId, currentVersion);
+
+ RuleFlowProcessInstance pi = (RuleFlowProcessInstance) processInstance;
+ ProcessDefinitionMigrationPlan processStateDefinition = new
ProcessDefinitionMigrationPlan(pi.getProcessId(), pi.getProcessVersion());
+
+ // check if definition and state match. we don't need to perform any
migration.
+ if (currentProcessDefinition.equals(processStateDefinition)) {
+ return null;
+ }
+
+ // there is no migration plan define for the source
+ MigrationPlan plan = migrations.get(processStateDefinition);
+ if (plan == null) {
+ LOGGER.debug("No migration plan defined for process state {}.",
processStateDefinition);
+ return null;
+ }
+
+ // current process definition matches the target process of the
migration plan
+ ProcessDefinitionMigrationPlan targetDefinition =
plan.getProcessMigrationPlan().getTargetProcessDefinition();
+ if (!targetDefinition.equals(currentProcessDefinition)) {
+ LOGGER.debug("Migration plan found for {} does not match target
definition {}, Found plan to {}.", processStateDefinition,
currentProcessDefinition, targetDefinition);
+ return null;
+ }
+
+ // target process not being deployed
+ if (!processes.processIds().contains(targetDefinition.getProcessId()))
{
+ LOGGER.debug("No migration target defintion deployed in this
container {} for migrating {}.", targetDefinition, processStateDefinition);
+ return null;
+ }
+
+ // target process not matching version
+ org.kie.kogito.process.Process<? extends Model> process =
processes.processById(targetDefinition.getProcessId());
+ ProcessDefinitionMigrationPlan targetDeployed =
+ new ProcessDefinitionMigrationPlan(process.id(),
process.version());
+
+ return targetDeployed.equals(targetDefinition) ? plan : null;
+ }
+
+ public boolean isEqualVersion(Processes processes,
KogitoWorkflowProcessInstance processInstance) {
+ String currentProcessId = processInstance.getProcess().getId();
+ String currentVersion = processInstance.getProcess().getVersion();
+ ProcessDefinitionMigrationPlan currentProcessDefinition = new
ProcessDefinitionMigrationPlan(currentProcessId, currentVersion);
+
RuleFlowProcessInstance pi = (RuleFlowProcessInstance) processInstance;
- ProcessDefinitionMigrationPlan pd =
- new ProcessDefinitionMigrationPlan(pi.getProcessId(),
pi.getProcessVersion());
- return migrations.get(pd);
+ ProcessDefinitionMigrationPlan processStateDefinition = new
ProcessDefinitionMigrationPlan(pi.getProcessId(), pi.getProcessVersion());
+
+ // check if definition and state match. we don't need to perform any
migration.
+ return currentProcessDefinition.equals(processStateDefinition);
}
- public boolean shouldMigrate(KogitoWorkflowProcessInstance
processInstance) {
- return getMigrationPlan(processInstance) != null;
+ public boolean hasMigrationPlan(Processes processes,
KogitoWorkflowProcessInstance processInstance) {
+ return getMigrationPlan(processes, processInstance) != null;
}
}
diff --git
a/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/impl/FileSystemMigrationPlanFileProvider.java
b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/impl/FileSystemMigrationPlanFileProvider.java
index 7d26bc7f96..a4aacf1a2c 100644
---
a/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/impl/FileSystemMigrationPlanFileProvider.java
+++
b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/impl/FileSystemMigrationPlanFileProvider.java
@@ -31,7 +31,9 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
+import java.util.Set;
import java.util.function.Predicate;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.jbpm.flow.migration.MigrationPlanFile;
@@ -49,7 +51,7 @@ public class FileSystemMigrationPlanFileProvider implements
MigrationPlanFilePro
public static final String EXPLODED_MIGRATION_PLAN_FOLDER =
"META-INF/migration-plan/";
public static final String MIGRATION_PLAN_FOLDER =
"/META-INF/migration-plan/";
- private List<URI> rootPaths;
+ private Set<URI> rootPaths;
public FileSystemMigrationPlanFileProvider() {
try {
@@ -57,7 +59,7 @@ public class FileSystemMigrationPlanFileProvider implements
MigrationPlanFilePro
if (url.isEmpty()) {
url =
Collections.list(JbpmClassLoaderUtil.findClassLoader().getResources(EXPLODED_MIGRATION_PLAN_FOLDER));
}
- this.rootPaths =
url.stream().map(this::toURI).filter(Optional::isPresent).map(Optional::get).toList();
+ this.rootPaths =
url.stream().map(this::toURI).filter(Optional::isPresent).map(Optional::get).collect(Collectors.toSet());
} catch (IOException e) {
throw new IllegalArgumentException("error trying to get Migration
Plan folder");
}
@@ -72,7 +74,7 @@ public class FileSystemMigrationPlanFileProvider implements
MigrationPlanFilePro
}
public FileSystemMigrationPlanFileProvider(URI rootPath) {
- this.rootPaths = List.of(rootPath);
+ this.rootPaths = Set.of(rootPath);
}
@Override
diff --git
a/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/serialization/migration/StandardMigrationProcessInstanceMarshallerListener.java
b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/serialization/migration/StandardMigrationProcessInstanceMarshallerListener.java
index 22ac0cdf03..b938110a99 100644
---
a/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/serialization/migration/StandardMigrationProcessInstanceMarshallerListener.java
+++
b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/serialization/migration/StandardMigrationProcessInstanceMarshallerListener.java
@@ -20,9 +20,11 @@ package org.jbpm.flow.serialization.migration;
import org.jbpm.flow.migration.MigrationPlanService;
import org.jbpm.flow.serialization.ProcessInstanceMarshallerListener;
+import org.jbpm.ruleflow.instance.RuleFlowProcessInstance;
import org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime;
import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcessInstance;
+import org.kie.kogito.process.Processes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -41,22 +43,28 @@ public class
StandardMigrationProcessInstanceMarshallerListener implements Proce
@SuppressWarnings("deprecation")
@Override
public void afterUnmarshallProcess(KogitoProcessRuntime runtime,
KogitoWorkflowProcessInstance processInstance) {
- if (!migrationPlanService.shouldMigrate(processInstance)) {
+ if
(!migrationPlanService.hasMigrationPlan(runtime.getApplication().get(Processes.class),
processInstance)) {
+ if
(!this.migrationPlanService.isEqualVersion(runtime.getApplication().get(Processes.class),
processInstance)) {
+ LOGGER.debug("Process State version and process container
mismatch. Migrating process without plan.");
+ RuleFlowProcessInstance ruleFlowProcessInstance =
(RuleFlowProcessInstance) processInstance;
+
ruleFlowProcessInstance.setProcess(ruleFlowProcessInstance.getProcess());
+ }
return;
}
- LOGGER.debug("Migration processInstance {}", processInstance);
- migrationPlanService.migrateProcessElement(processInstance);
+ LOGGER.debug("Migration processInstance state {}-{} and definition
{}-{}",
+ processInstance.getProcessId(),
processInstance.getProcessVersion(), processInstance.getProcess().getId(),
processInstance.getProcess().getVersion());
+
migrationPlanService.migrateProcessElement(runtime.getApplication().get(Processes.class),
processInstance);
runtime.getProcessEventSupport().fireOnMigration(processInstance,
runtime.getKieRuntime());
}
@Override
public void afterUnmarshallNode(KogitoProcessRuntime runtime,
KogitoNodeInstance nodeInstance) {
- if
(!migrationPlanService.shouldMigrate((KogitoWorkflowProcessInstance)
nodeInstance.getProcessInstance())) {
+ if
(!migrationPlanService.hasMigrationPlan(runtime.getApplication().get(Processes.class),
(KogitoWorkflowProcessInstance) nodeInstance.getProcessInstance())) {
return;
}
LOGGER.debug("Migration nodeInstance {}", nodeInstance);
- migrationPlanService.migrateNodeElement(nodeInstance);
+
migrationPlanService.migrateNodeElement(runtime.getApplication().get(Processes.class),
nodeInstance);
}
}
diff --git
a/jbpm/jbpm-flow-migration/src/test/java/org/jbpm/flow/migration/MigrationPlanProviderTest.java
b/jbpm/jbpm-flow-migration/src/test/java/org/jbpm/flow/migration/MigrationPlanProviderTest.java
index 2a279c20f1..d417066b96 100644
---
a/jbpm/jbpm-flow-migration/src/test/java/org/jbpm/flow/migration/MigrationPlanProviderTest.java
+++
b/jbpm/jbpm-flow-migration/src/test/java/org/jbpm/flow/migration/MigrationPlanProviderTest.java
@@ -55,8 +55,8 @@ public class MigrationPlanProviderTest {
plan.setProcessMigrationPlan(pdmp);
assertThat(plans)
- .hasSize(1)
- .containsExactly(plan);
+ .hasSize(2)
+ .contains(plan);
}
diff --git
a/jbpm/jbpm-flow-migration/src/test/java/org/jbpm/flow/migration/MigrationPlanServiceTest.java
b/jbpm/jbpm-flow-migration/src/test/java/org/jbpm/flow/migration/MigrationPlanServiceTest.java
index 1e2f141110..2df1b83775 100644
---
a/jbpm/jbpm-flow-migration/src/test/java/org/jbpm/flow/migration/MigrationPlanServiceTest.java
+++
b/jbpm/jbpm-flow-migration/src/test/java/org/jbpm/flow/migration/MigrationPlanServiceTest.java
@@ -18,23 +18,64 @@
*/
package org.jbpm.flow.migration;
+import java.util.Collections;
+
import org.jbpm.ruleflow.instance.RuleFlowProcessInstance;
import org.jbpm.workflow.instance.impl.ExtendedNodeInstanceImpl;
import org.jbpm.workflow.instance.impl.WorkflowProcessInstanceImpl;
+import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.junit.jupiter.api.TestInstance.Lifecycle;
+import org.kie.kogito.process.Processes;
+import org.mockito.Mockito;
import static org.assertj.core.api.Assertions.assertThat;
import static
org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory.fromExternalFormat;
+import static org.mockito.Mockito.when;
+@TestInstance(Lifecycle.PER_CLASS)
public class MigrationPlanServiceTest {
+ Processes processes;
+ org.kie.kogito.process.Process processB;
+
+ @BeforeAll
+ public void init() {
+ processes = Mockito.mock(Processes.class);
+
when(processes.processIds()).thenReturn(Collections.singletonList("process_B"));
+
+ processB = Mockito.mock(org.kie.kogito.process.Process.class);
+ when(processes.processById("process_B")).thenReturn(processB);
+ when(processB.id()).thenReturn("process_B");
+ when(processB.version()).thenReturn("2");
+ }
+
+ @Test
+ public void testMigrationProcessInstanceSameProcessDefinition() {
+ MigrationPlanService service = new MigrationPlanService();
+
+ WorkflowProcessInstanceImpl processImpl = new
RuleFlowProcessInstance();
+ processImpl.setInternalProcess(new DummyProcess("process_A", "1"));
+ processImpl.setProcessId("process_A");
+ processImpl.setProcessVersion("1");
+ service.migrateProcessElement(processes, processImpl);
+
+ assertThat(processImpl)
+ .hasFieldOrPropertyWithValue("processId", "process_A")
+ .hasFieldOrPropertyWithValue("processVersion", "1");
+
+ }
+
@Test
public void testMigrationProcessInstance() {
MigrationPlanService service = new MigrationPlanService();
WorkflowProcessInstanceImpl processImpl = new
RuleFlowProcessInstance();
- processImpl.setProcess(new DummyProcess("process_A", "1"));
- service.migrateProcessElement(processImpl);
+ processImpl.setInternalProcess(new DummyProcess("process_B", "2"));
+ processImpl.setProcessId("process_A");
+ processImpl.setProcessVersion("1");
+ service.migrateProcessElement(processes, processImpl);
assertThat(processImpl)
.hasFieldOrPropertyWithValue("processId", "process_B")
@@ -42,12 +83,26 @@ public class MigrationPlanServiceTest {
}
+ @Test
+ public void testMigrationProcessInstanceNotMatchingVersion() {
+ MigrationPlanService service = new MigrationPlanService();
+
+ WorkflowProcessInstanceImpl processImpl = new
RuleFlowProcessInstance();
+ processImpl.setProcess(new DummyProcess("process_D", "1"));
+ service.migrateProcessElement(processes, processImpl);
+
+ assertThat(processImpl)
+ .hasFieldOrPropertyWithValue("processId", "process_D")
+ .hasFieldOrPropertyWithValue("processVersion", "1");
+
+ }
+
@Test
public void testMigrationProcessNonExisting() {
MigrationPlanService service = new MigrationPlanService();
WorkflowProcessInstanceImpl processImpl = new
RuleFlowProcessInstance();
processImpl.setProcess(new DummyProcess("process_C", "1"));
- service.migrateProcessElement(processImpl);
+ service.migrateProcessElement(processes, processImpl);
assertThat(processImpl)
.hasFieldOrPropertyWithValue("processId", "process_C")
@@ -59,7 +114,7 @@ public class MigrationPlanServiceTest {
MigrationPlanService service = new MigrationPlanService();
WorkflowProcessInstanceImpl processImpl = new
RuleFlowProcessInstance();
processImpl.setProcess(new DummyProcess("process_A", "3"));
- service.migrateProcessElement(processImpl);
+ service.migrateProcessElement(processes, processImpl);
assertThat(processImpl)
.hasFieldOrPropertyWithValue("processId", "process_A")
@@ -70,12 +125,14 @@ public class MigrationPlanServiceTest {
public void testMigrationNode() {
MigrationPlanService service = new MigrationPlanService();
WorkflowProcessInstanceImpl processImpl = new
RuleFlowProcessInstance();
- processImpl.setProcess(new DummyProcess("process_A", "1"));
+ processImpl.setInternalProcess(new DummyProcess("process_B", "2"));
+ processImpl.setProcessId("process_A");
+ processImpl.setProcessVersion("1");
ExtendedNodeInstanceImpl nodeInstanceImpl = new
ExtendedNodeInstanceImpl() {
};
nodeInstanceImpl.setProcessInstance(processImpl);
nodeInstanceImpl.setNodeId(fromExternalFormat("node_1"));
- service.migrateNodeElement(nodeInstanceImpl);
+ service.migrateNodeElement(processes, nodeInstanceImpl);
assertThat(nodeInstanceImpl)
.hasFieldOrPropertyWithValue("nodeId",
fromExternalFormat("node_2"));
@@ -85,12 +142,14 @@ public class MigrationPlanServiceTest {
public void testMigrationNodeNextItem() {
MigrationPlanService service = new MigrationPlanService();
WorkflowProcessInstanceImpl processImpl = new
RuleFlowProcessInstance();
- processImpl.setProcess(new DummyProcess("process_A", "1"));
+ processImpl.setInternalProcess(new DummyProcess("process_B", "2"));
+ processImpl.setProcessId("process_A");
+ processImpl.setProcessVersion("1");
ExtendedNodeInstanceImpl nodeInstanceImpl = new
ExtendedNodeInstanceImpl() {
};
nodeInstanceImpl.setProcessInstance(processImpl);
nodeInstanceImpl.setNodeId(fromExternalFormat("node_2"));
- service.migrateNodeElement(nodeInstanceImpl);
+ service.migrateNodeElement(processes, nodeInstanceImpl);
assertThat(nodeInstanceImpl)
.hasFieldOrPropertyWithValue("nodeId",
fromExternalFormat("node_3"));
@@ -105,7 +164,7 @@ public class MigrationPlanServiceTest {
};
nodeInstanceImpl.setProcessInstance(processImpl);
nodeInstanceImpl.setNodeId(fromExternalFormat("node_3"));
- service.migrateNodeElement(nodeInstanceImpl);
+ service.migrateNodeElement(processes, nodeInstanceImpl);
assertThat(nodeInstanceImpl)
.hasFieldOrPropertyWithValue("nodeId",
fromExternalFormat("node_3"));
@@ -120,7 +179,7 @@ public class MigrationPlanServiceTest {
};
nodeInstanceImpl.setProcessInstance(processImpl);
nodeInstanceImpl.setNodeId(fromExternalFormat("node_3"));
- service.migrateNodeElement(nodeInstanceImpl);
+ service.migrateNodeElement(processes, nodeInstanceImpl);
assertThat(nodeInstanceImpl)
.hasFieldOrPropertyWithValue("nodeId",
fromExternalFormat("node_3"));
diff --git
a/jbpm/jbpm-flow-migration/src/test/resources/META-INF/migration-plan/simple_migration.mpf
b/jbpm/jbpm-flow-migration/src/test/resources/META-INF/migration-plan/simple_migration.mpf
index 98d93052b2..9daed6fad1 100644
---
a/jbpm/jbpm-flow-migration/src/test/resources/META-INF/migration-plan/simple_migration.mpf
+++
b/jbpm/jbpm-flow-migration/src/test/resources/META-INF/migration-plan/simple_migration.mpf
@@ -1,13 +1,13 @@
{
- "name" : "my simple migration",
+ "name" : "my simple migration versioned",
"processMigrationPlan" : {
"sourceProcessDefinition" : {
- "processId" : "process_A",
+ "processId" : "process_D",
"processVersion" : "1"
},
"targetProcessDefinition" : {
"processId" : "process_B",
- "processVersion" : "2"
+ "processVersion" : "3"
},
"nodeInstanceMigrationPlan" : [
{
diff --git
a/jbpm/jbpm-flow-migration/src/test/resources/META-INF/migration-plan/simple_migration.mpf
b/jbpm/jbpm-flow-migration/src/test/resources/META-INF/migration-plan/simple_migration_version.mpf
similarity index 100%
copy from
jbpm/jbpm-flow-migration/src/test/resources/META-INF/migration-plan/simple_migration.mpf
copy to
jbpm/jbpm-flow-migration/src/test/resources/META-INF/migration-plan/simple_migration_version.mpf
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]