Skip to content

Commit

Permalink
Merge pull request #34 from rgdoliveira/sync_main
Browse files Browse the repository at this point in the history
Sync main branch with Apache main branch
  • Loading branch information
rgdoliveira authored Apr 23, 2024
2 parents ca08665 + fe4ce9b commit de803de
Show file tree
Hide file tree
Showing 39 changed files with 787 additions and 385 deletions.
2 changes: 1 addition & 1 deletion .ci/jenkins/tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

<groovy.core.version>2.4.11</groovy.core.version>
<groovy.gmaven.pluginVersion>1.6.1</groovy.gmaven.pluginVersion>
<google.guava.version>29.0-jre</google.guava.version>
<google.guava.version>32.0.0-jre</google.guava.version>

<jenkins-spock.version>2.0.0</jenkins-spock.version>
<jenkins.version>2.334</jenkins.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.Map;
import java.util.stream.Stream;

import org.drools.codegen.common.AppPaths;
import org.drools.io.FileSystemResource;
import org.drools.scenariosimulation.api.model.ScenarioSimulationModel;
import org.drools.scenariosimulation.api.model.ScesimModelDescriptor;
Expand All @@ -53,7 +54,7 @@ public class KogitoDMNScenarioRunnerHelper extends DMNScenarioRunnerHelper {

private DMNRuntime dmnRuntime = initDmnRuntime();

private static final String targetFolder = File.separator + "target" + File.separator;
private static final String targetFolder = File.separator + AppPaths.TARGET_DIR + File.separator;
private static final String generatedResourcesFolder = targetFolder + "generated-resources" + File.separator;

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,21 @@
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);

Expand All @@ -49,8 +56,8 @@ public MigrationPlanService(MigrationPlanProvider migrationPlanProvider) {
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 {}",
Expand All @@ -67,9 +74,9 @@ public void migrateProcessElement(KogitoWorkflowProcessInstance processInstance)
}
}

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;
}
Expand All @@ -79,14 +86,63 @@ public void migrateNodeElement(KogitoNodeInstance nodeInstance) {
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@
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;
Expand All @@ -49,15 +51,15 @@ 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 {
List<URL> url = Collections.list(JbpmClassLoaderUtil.findClassLoader().getResources(MIGRATION_PLAN_FOLDER));
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");
}
Expand All @@ -72,7 +74,7 @@ private Optional<URI> toURI(URL e) {
}

public FileSystemMigrationPlanFileProvider(URI rootPath) {
this.rootPaths = List.of(rootPath);
this.rootPaths = Set.of(rootPath);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@

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;

Expand All @@ -41,22 +43,28 @@ public StandardMigrationProcessInstanceMarshallerListener() {
@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);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ public void testReadingFiles() {
plan.setProcessMigrationPlan(pdmp);

assertThat(plans)
.hasSize(1)
.containsExactly(plan);
.hasSize(2)
.contains(plan);

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,36 +18,91 @@
*/
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")
.hasFieldOrPropertyWithValue("processVersion", "2");

}

@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")
Expand All @@ -59,7 +114,7 @@ public void testMigrationProcessNotRightVersion() {
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")
Expand All @@ -70,12 +125,14 @@ public void testMigrationProcessNotRightVersion() {
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"));
Expand All @@ -85,12 +142,14 @@ public void testMigrationNode() {
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"));
Expand All @@ -105,7 +164,7 @@ public void testMigrationNodeNonExistent() {
};
nodeInstanceImpl.setProcessInstance(processImpl);
nodeInstanceImpl.setNodeId(fromExternalFormat("node_3"));
service.migrateNodeElement(nodeInstanceImpl);
service.migrateNodeElement(processes, nodeInstanceImpl);

assertThat(nodeInstanceImpl)
.hasFieldOrPropertyWithValue("nodeId", fromExternalFormat("node_3"));
Expand All @@ -120,7 +179,7 @@ public void testMigrationNodeNotMigratedWrongProcess() {
};
nodeInstanceImpl.setProcessInstance(processImpl);
nodeInstanceImpl.setNodeId(fromExternalFormat("node_3"));
service.migrateNodeElement(nodeInstanceImpl);
service.migrateNodeElement(processes, nodeInstanceImpl);

assertThat(nodeInstanceImpl)
.hasFieldOrPropertyWithValue("nodeId", fromExternalFormat("node_3"));
Expand Down
Loading

0 comments on commit de803de

Please sign in to comment.