diff --git a/.ci/jenkins/tests/pom.xml b/.ci/jenkins/tests/pom.xml
index 631f747b248..d790ede2107 100644
--- a/.ci/jenkins/tests/pom.xml
+++ b/.ci/jenkins/tests/pom.xml
@@ -40,7 +40,7 @@
2.4.11
1.6.1
- 29.0-jre
+ 32.0.0-jre
2.0.0
2.334
diff --git a/drools/kogito-scenario-simulation/src/main/java/org/kogito/scenariosimulation/runner/KogitoDMNScenarioRunnerHelper.java b/drools/kogito-scenario-simulation/src/main/java/org/kogito/scenariosimulation/runner/KogitoDMNScenarioRunnerHelper.java
index 9d6f96ef9eb..2babf303133 100644
--- a/drools/kogito-scenario-simulation/src/main/java/org/kogito/scenariosimulation/runner/KogitoDMNScenarioRunnerHelper.java
+++ b/drools/kogito-scenario-simulation/src/main/java/org/kogito/scenariosimulation/runner/KogitoDMNScenarioRunnerHelper.java
@@ -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;
@@ -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
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 12951dfb169..662eefaf914 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.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 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 {}",
@@ -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;
}
@@ -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;
}
}
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 7d26bc7f963..a4aacf1a2c6 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.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 rootPaths;
+ private Set rootPaths;
public FileSystemMigrationPlanFileProvider() {
try {
@@ -57,7 +59,7 @@ public FileSystemMigrationPlanFileProvider() {
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 @@ private Optional toURI(URL e) {
}
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 22ac0cdf039..b938110a994 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 @@
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 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);
}
}
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 2a279c20f14..d417066b969 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 void testReadingFiles() {
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 1e2f141110e..2df1b83775f 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 void testMigrationProcessInstance() {
}
+ @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 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")
@@ -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"));
@@ -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"));
@@ -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"));
@@ -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"));
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 98d93052b2e..9daed6fad12 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_version.mpf b/jbpm/jbpm-flow-migration/src/test/resources/META-INF/migration-plan/simple_migration_version.mpf
new file mode 100644
index 00000000000..98d93052b2e
--- /dev/null
+++ b/jbpm/jbpm-flow-migration/src/test/resources/META-INF/migration-plan/simple_migration_version.mpf
@@ -0,0 +1,23 @@
+{
+ "name" : "my simple migration",
+ "processMigrationPlan" : {
+ "sourceProcessDefinition" : {
+ "processId" : "process_A",
+ "processVersion" : "1"
+ },
+ "targetProcessDefinition" : {
+ "processId" : "process_B",
+ "processVersion" : "2"
+ },
+ "nodeInstanceMigrationPlan" : [
+ {
+ "sourceNodeId" : "node_1",
+ "targetNodeId" : "node_2"
+ },
+ {
+ "sourceNodeId" : "node_2",
+ "targetNodeId" : "node_3"
+ }
+ ]
+ }
+}
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceImpl.java
index 6ab030d9ffc..e23c5b4bc82 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceImpl.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceImpl.java
@@ -257,7 +257,6 @@ public final void trigger(KogitoNodeInstance from, String type) {
}
protected void captureError(Exception e) {
- e.printStackTrace();
logger.error("capture error", e);
getProcessInstance().setErrorState(this, e);
}
diff --git a/kogito-bom/pom.xml b/kogito-bom/pom.xml
index 61ce872c187..b07eec3f819 100755
--- a/kogito-bom/pom.xml
+++ b/kogito-bom/pom.xml
@@ -1941,6 +1941,28 @@
${project.version}
sources
+
+ org.kie.kogito
+ kogito-serverless-workflow-dmn-parser
+ ${project.version}
+
+
+ org.kie.kogito
+ kogito-serverless-workflow-dmn-parser
+ ${project.version}
+ sources
+
+
+ org.kie.kogito
+ kogito-serverless-workflow-dmn
+ ${project.version}
+
+
+ org.kie.kogito
+ kogito-serverless-workflow-dmn
+ ${project.version}
+ sources
+
org.kie.kogito
kogito-serverless-workflow-rest-parser
@@ -2301,52 +2323,6 @@
${project.version}
-
-
- org.jbpm
- jbpm-quarkus-devui
- ${project.version}
-
-
- org.jbpm
- jbpm-quarkus-devui
- ${project.version}
- sources
-
-
- org.jbpm
- jbpm-quarkus-devui-deployment
- ${project.version}
-
-
- org.jbpm
- jbpm-quarkus-devui-deployment
- ${project.version}
- sources
-
-
- org.apache.kie.sonataflow
- sonataflow-quarkus-devui
- ${project.version}
-
-
- org.apache.kie.sonataflow
- sonataflow-quarkus-devui
- ${project.version}
- sources
-
-
- org.apache.kie.sonataflow
- sonataflow-quarkus-devui-deployment
- ${project.version}
-
-
- org.apache.kie.sonataflow
- sonataflow-quarkus-devui-deployment
- ${project.version}
- sources
-
-
org.kie
diff --git a/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/context/impl/AbstractKogitoBuildContext.java b/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/context/impl/AbstractKogitoBuildContext.java
index 25a0e8794da..d46cfdb118a 100644
--- a/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/context/impl/AbstractKogitoBuildContext.java
+++ b/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/context/impl/AbstractKogitoBuildContext.java
@@ -21,7 +21,6 @@
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
-import java.nio.file.Path;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.Collections;
@@ -258,7 +257,7 @@ protected abstract static class AbstractBuilder implements Builder {
protected Predicate classAvailabilityResolver = this::hasClass;
protected Predicate> classSubTypeAvailabilityResolver = c -> false;
// default fallback value (usually overridden)
- protected AppPaths appPaths = AppPaths.fromProjectDir(new File(".").toPath(), Path.of(".", AppPaths.TARGET_DIR));
+ protected AppPaths appPaths = AppPaths.fromProjectDir(new File(".").toPath());
protected KogitoGAV gav;
protected AbstractBuilder() {
diff --git a/kogito-codegen-modules/kogito-codegen-core/src/main/java/org/kie/kogito/codegen/core/utils/GeneratedFileWriter.java b/kogito-codegen-modules/kogito-codegen-core/src/main/java/org/kie/kogito/codegen/core/utils/GeneratedFileWriter.java
deleted file mode 100644
index d596702592a..00000000000
--- a/kogito-codegen-modules/kogito-codegen-core/src/main/java/org/kie/kogito/codegen/core/utils/GeneratedFileWriter.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.kie.kogito.codegen.core.utils;
-
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Collection;
-
-import org.drools.codegen.common.GeneratedFile;
-import org.drools.codegen.common.GeneratedFileType;
-
-/**
- * Writes {@link GeneratedFile} to the right directory, depending on its
- * {@link GeneratedFileType.Category}
- */
-public class GeneratedFileWriter {
-
- public static class Builder {
-
- private final String classesDir;
- private final String sourcesDir;
- private final String resourcePath;
- private final String scaffoldedSourcesDir;
-
- /**
- *
- * @param classesDir usually target/classes/
- * @param sourcesDir usually target/generated-sources/kogito/
- * @param resourcesDir usually target/generated-resources/kogito/
- * @param scaffoldedSourcesDir usually src/main/java/
- */
- public Builder(String classesDir, String sourcesDir, String resourcesDir, String scaffoldedSourcesDir) {
- this.classesDir = classesDir;
- this.sourcesDir = sourcesDir;
- this.resourcePath = resourcesDir;
- this.scaffoldedSourcesDir = scaffoldedSourcesDir;
- }
-
- /**
- * @param basePath the path to which the given subdirectories will be written
- * e.g. ${basePath}/${classesDir}/myfile.ext
- *
- */
- public GeneratedFileWriter build(Path basePath) {
- return new GeneratedFileWriter(
- basePath.resolve(classesDir),
- basePath.resolve(sourcesDir),
- basePath.resolve(resourcePath),
- basePath.resolve(scaffoldedSourcesDir));
- }
- }
-
- private final Path classesDir;
- private final Path sourcesDir;
- private final Path resourcePath;
- private final Path scaffoldedSourcesDir;
-
- public static final String DEFAULT_SOURCES_DIR = "generated-sources/kogito/";
- public static final String DEFAULT_RESOURCE_PATH = "generated-resources/kogito/";
- public static final String DEFAULT_SCAFFOLDED_SOURCES_DIR = "src/main/java/";
- public static final String DEFAULT_CLASSES_DIR = "target/classes";
-
- /**
- *
- * @param classesDir usually {@link #DEFAULT_CLASSES_DIR}
- * @param sourcesDir usually target/generated-sources/kogito/. See {@link #DEFAULT_SOURCES_DIR}
- * @param resourcePath usually target/generated-resources/kogito/ {@link #DEFAULT_RESOURCE_PATH}
- * @param scaffoldedSourcesDir usually {@link #DEFAULT_SCAFFOLDED_SOURCES_DIR}
- */
- public GeneratedFileWriter(Path classesDir, Path sourcesDir, Path resourcePath, Path scaffoldedSourcesDir) {
- this.classesDir = classesDir;
- this.sourcesDir = sourcesDir;
- this.resourcePath = resourcePath;
- this.scaffoldedSourcesDir = scaffoldedSourcesDir;
- }
-
- public void writeAll(Collection generatedFiles) {
- generatedFiles.forEach(this::write);
- }
-
- public void write(GeneratedFile f) throws UncheckedIOException {
- try {
- GeneratedFileType.Category category = f.category();
- switch (category) {
- case INTERNAL_RESOURCE: // since codegen happens after maven-resource-plugin (both in Quarkus and SB), need to manually place in the correct (CP) location
- case STATIC_HTTP_RESOURCE:
- case COMPILED_CLASS:
- writeGeneratedFile(f, classesDir);
- break;
- case SOURCE:
- if (f.type().isCustomizable()) {
- writeGeneratedFile(f, scaffoldedSourcesDir);
- } else {
- writeGeneratedFile(f, sourcesDir);
- }
- break;
- default:
- throw new IllegalArgumentException("Unknown Category " + category.name());
- }
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
- }
-
- public Path getClassesDir() {
- return classesDir;
- }
-
- public Path getSourcesDir() {
- return sourcesDir;
- }
-
- public Path getResourcePath() {
- return resourcePath;
- }
-
- public Path getScaffoldedSourcesDir() {
- return scaffoldedSourcesDir;
- }
-
- private void writeGeneratedFile(GeneratedFile f, Path location) throws IOException {
- if (location == null) {
- return;
- }
- Files.write(
- pathOf(location, f.path()),
- f.contents());
- }
-
- private Path pathOf(Path location, Path end) throws IOException {
- Path path = location.resolve(end);
- Files.createDirectories(path.getParent());
- return path;
- }
-}
diff --git a/kogito-codegen-modules/kogito-codegen-predictions/src/test/java/org/kie/kogito/codegen/prediction/PMMLRestResourceGeneratorTest.java b/kogito-codegen-modules/kogito-codegen-predictions/src/test/java/org/kie/kogito/codegen/prediction/PMMLRestResourceGeneratorTest.java
index 8fe6c0dd94b..b69a9aa614e 100644
--- a/kogito-codegen-modules/kogito-codegen-predictions/src/test/java/org/kie/kogito/codegen/prediction/PMMLRestResourceGeneratorTest.java
+++ b/kogito-codegen-modules/kogito-codegen-predictions/src/test/java/org/kie/kogito/codegen/prediction/PMMLRestResourceGeneratorTest.java
@@ -22,6 +22,7 @@
import java.util.NoSuchElementException;
import java.util.Optional;
+import org.drools.codegen.common.AppPaths;
import org.drools.codegen.common.di.impl.CDIDependencyInjectionAnnotator;
import org.drools.util.StringUtils;
import org.junit.jupiter.api.AfterAll;
@@ -80,7 +81,7 @@ public static void setup() {
String filePrefix = URLEncoder.encode(getSanitizedClassName(KIE_PMML_MODEL.getFileName().replace(".pmml", "")));
String classPrefix = URLEncoder.encode(getSanitizedClassName(KIE_PMML_MODEL.getName()));
expectedUrl = String.format("/%s/%s", filePrefix, classPrefix);
- System.setProperty(INDEXFILE_DIRECTORY_PROPERTY, "target/test-classes");
+ System.setProperty(INDEXFILE_DIRECTORY_PROPERTY, String.format("%s/test-classes", AppPaths.TARGET_DIR));
}
@AfterAll
diff --git a/kogito-codegen-modules/kogito-codegen-predictions/src/test/java/org/kie/kogito/codegen/prediction/PredictionCodegenFactoryTest.java b/kogito-codegen-modules/kogito-codegen-predictions/src/test/java/org/kie/kogito/codegen/prediction/PredictionCodegenFactoryTest.java
index 1c14e042a6f..d378b501f70 100644
--- a/kogito-codegen-modules/kogito-codegen-predictions/src/test/java/org/kie/kogito/codegen/prediction/PredictionCodegenFactoryTest.java
+++ b/kogito-codegen-modules/kogito-codegen-predictions/src/test/java/org/kie/kogito/codegen/prediction/PredictionCodegenFactoryTest.java
@@ -21,6 +21,7 @@
import java.util.Collections;
import java.util.List;
+import org.drools.codegen.common.AppPaths;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
@@ -46,7 +47,7 @@ class PredictionCodegenFactoryTest {
@BeforeAll
public static void setup() {
- System.setProperty(INDEXFILE_DIRECTORY_PROPERTY, "target/test-classes");
+ System.setProperty(INDEXFILE_DIRECTORY_PROPERTY, String.format("%s/test-classes", AppPaths.TARGET_DIR));
}
@AfterAll
diff --git a/kogito-codegen-modules/kogito-codegen-predictions/src/test/java/org/kie/kogito/codegen/prediction/PredictionCodegenGenerateTest.java b/kogito-codegen-modules/kogito-codegen-predictions/src/test/java/org/kie/kogito/codegen/prediction/PredictionCodegenGenerateTest.java
index b26c7bbef86..c563288e284 100644
--- a/kogito-codegen-modules/kogito-codegen-predictions/src/test/java/org/kie/kogito/codegen/prediction/PredictionCodegenGenerateTest.java
+++ b/kogito-codegen-modules/kogito-codegen-predictions/src/test/java/org/kie/kogito/codegen/prediction/PredictionCodegenGenerateTest.java
@@ -29,6 +29,7 @@
import java.util.function.Function;
import java.util.stream.Stream;
+import org.drools.codegen.common.AppPaths;
import org.drools.codegen.common.GeneratedFile;
import org.drools.codegen.common.GeneratedFileType;
import org.junit.jupiter.api.AfterAll;
@@ -68,7 +69,7 @@ class PredictionCodegenGenerateTest {
@BeforeAll
public static void setup() {
- System.setProperty(INDEXFILE_DIRECTORY_PROPERTY, "target/test-classes");
+ System.setProperty(INDEXFILE_DIRECTORY_PROPERTY, String.format("%s/test-classes", AppPaths.TARGET_DIR));
}
@AfterAll
diff --git a/kogito-codegen-modules/kogito-codegen-predictions/src/test/java/org/kie/kogito/codegen/prediction/PredictionCodegenInternalGenerateTest.java b/kogito-codegen-modules/kogito-codegen-predictions/src/test/java/org/kie/kogito/codegen/prediction/PredictionCodegenInternalGenerateTest.java
index 27b91deb5b7..6f6229c4dee 100644
--- a/kogito-codegen-modules/kogito-codegen-predictions/src/test/java/org/kie/kogito/codegen/prediction/PredictionCodegenInternalGenerateTest.java
+++ b/kogito-codegen-modules/kogito-codegen-predictions/src/test/java/org/kie/kogito/codegen/prediction/PredictionCodegenInternalGenerateTest.java
@@ -25,6 +25,7 @@
import java.util.function.Function;
import java.util.stream.Stream;
+import org.drools.codegen.common.AppPaths;
import org.drools.codegen.common.GeneratedFile;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
@@ -51,7 +52,7 @@ class PredictionCodegenInternalGenerateTest {
@BeforeAll
public static void setup() {
- System.setProperty(INDEXFILE_DIRECTORY_PROPERTY, "target/test-classes");
+ System.setProperty(INDEXFILE_DIRECTORY_PROPERTY, String.format("%s/test-classes", AppPaths.TARGET_DIR));
}
@AfterAll
diff --git a/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/AbstractKieMojo.java b/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/AbstractKieMojo.java
index 81eb6a6c262..b279c5eafc1 100644
--- a/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/AbstractKieMojo.java
+++ b/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/AbstractKieMojo.java
@@ -22,6 +22,7 @@
import java.lang.reflect.Modifier;
import java.net.URL;
import java.net.URLClassLoader;
+import java.nio.file.Path;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
@@ -37,13 +38,13 @@
import org.drools.codegen.common.AppPaths;
import org.drools.codegen.common.DroolsModelBuildContext;
import org.drools.codegen.common.GeneratedFile;
+import org.drools.codegen.common.GeneratedFileWriter;
import org.kie.kogito.KogitoGAV;
import org.kie.kogito.codegen.api.Generator;
import org.kie.kogito.codegen.api.context.KogitoBuildContext;
import org.kie.kogito.codegen.api.context.impl.JavaKogitoBuildContext;
import org.kie.kogito.codegen.api.context.impl.QuarkusKogitoBuildContext;
import org.kie.kogito.codegen.api.context.impl.SpringBootKogitoBuildContext;
-import org.kie.kogito.codegen.core.utils.GeneratedFileWriter;
import org.kie.kogito.codegen.decision.DecisionCodegen;
import org.kie.kogito.codegen.prediction.PredictionCodegen;
import org.kie.kogito.codegen.process.ProcessCodegen;
@@ -55,6 +56,8 @@
public abstract class AbstractKieMojo extends AbstractMojo {
+ protected static final GeneratedFileWriter.Builder generatedFileWriterBuilder = GeneratedFileWriter.builder("kogito", "kogito.codegen.resources.directory", "kogito.codegen.sources.directory");
+
@Parameter(required = true, defaultValue = "${project.basedir}")
protected File projectDir;
@@ -67,11 +70,8 @@ public abstract class AbstractKieMojo extends AbstractMojo {
@Parameter(required = true, defaultValue = "${project.build.outputDirectory}")
protected File outputDirectory;
- @Parameter(defaultValue = "${project.build.directory}/" + GeneratedFileWriter.DEFAULT_SOURCES_DIR)
- protected File generatedSources;
-
- @Parameter(defaultValue = "${project.build.directory}/" + GeneratedFileWriter.DEFAULT_RESOURCE_PATH)
- protected File generatedResources;
+ @Parameter(required = true, defaultValue = "${project.basedir}")
+ protected File baseDir;
@Parameter(property = "kogito.codegen.persistence", defaultValue = "true")
protected boolean persistence;
@@ -102,7 +102,7 @@ protected void setSystemProperties(Map properties) {
}
protected KogitoBuildContext discoverKogitoRuntimeContext(ClassLoader classLoader) {
- AppPaths appPaths = AppPaths.fromProjectDir(projectDir.toPath(), outputDirectory.toPath());
+ AppPaths appPaths = AppPaths.fromProjectDir(projectDir.toPath());
KogitoBuildContext context = contextBuilder()
.withClassAvailabilityResolver(this::hasClassOnClasspath)
.withClassSubTypeAvailabilityResolver(classSubTypeAvailabilityResolver())
@@ -250,20 +250,27 @@ private boolean hasClassOnClasspath(String className) {
}
protected void writeGeneratedFiles(Collection generatedFiles) {
- generatedFiles.forEach(this::writeGeneratedFile);
+ GeneratedFileWriter writer = getGeneratedFileWriter();
+ generatedFiles.forEach(generatedFile -> writeGeneratedFile(generatedFile, writer));
}
protected void writeGeneratedFile(GeneratedFile generatedFile) {
- GeneratedFileWriter writer = new GeneratedFileWriter(outputDirectory.toPath(),
- generatedSources.toPath(),
- generatedResources.toPath(),
- getSourcesPath().toPath());
+ writeGeneratedFile(generatedFile, getGeneratedFileWriter());
+ }
+ protected void writeGeneratedFile(GeneratedFile generatedFile, GeneratedFileWriter writer) {
getLog().info("Generating: " + generatedFile.relativePath());
writer.write(generatedFile);
}
protected File getSourcesPath() {
- return generatedSources;
+ // using runtime BT instead of static AppPaths.MAVEN to allow
+ // invocation from GRADLE
+ return Path.of(baseDir.getAbsolutePath(), AppPaths.BT.GENERATED_SOURCES_PATH.toString()).toFile();
+ }
+
+ protected GeneratedFileWriter getGeneratedFileWriter() {
+ return generatedFileWriterBuilder
+ .build(Path.of(baseDir.getAbsolutePath()));
}
}
diff --git a/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/GenerateModelMojo.java b/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/GenerateModelMojo.java
index 9b101d390d4..b1c3c675102 100644
--- a/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/GenerateModelMojo.java
+++ b/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/GenerateModelMojo.java
@@ -54,9 +54,6 @@ public class GenerateModelMojo extends AbstractKieMojo {
public static final PathMatcher drlFileMatcher = FileSystems.getDefault().getPathMatcher("glob:**.drl");
- @Parameter(property = "kogito.codegen.sources.directory", defaultValue = "${project.build.directory}/generated-sources/kogito")
- private File customizableSourcesPath;
-
/**
* Partial generation can be used when reprocessing a pre-compiled project
* for faster code-generation. It only generates code for rules and processes,
@@ -72,19 +69,16 @@ public class GenerateModelMojo extends AbstractKieMojo {
@Parameter(property = "kogito.sources.keep", defaultValue = "false")
private boolean keepSources;
- @Parameter(property = "build.output.directory", readonly = true, defaultValue = "${project.build.directory}/classes/")
- private String buildOutputDirectory;
-
@Override
public void execute() throws MojoExecutionException {
// TODO to be removed with DROOLS-7090
boolean indexFileDirectorySet = false;
- getLog().debug("execute -> " + buildOutputDirectory);
- if (buildOutputDirectory == null) {
+ getLog().debug("execute -> " + outputDirectory);
+ if (outputDirectory == null) {
throw new MojoExecutionException("${project.build.directory} is null");
}
if (System.getProperty(INDEXFILE_DIRECTORY_PROPERTY) == null) {
- System.setProperty(INDEXFILE_DIRECTORY_PROPERTY, buildOutputDirectory);
+ System.setProperty(INDEXFILE_DIRECTORY_PROPERTY, outputDirectory.toString());
indexFileDirectorySet = true;
}
addCompileSourceRoots();
@@ -103,14 +97,8 @@ protected boolean isOnDemand() {
return onDemand;
}
- @Override
- protected File getSourcesPath() {
- return customizableSourcesPath;
- }
-
protected void addCompileSourceRoots() {
- project.addCompileSourceRoot(getSourcesPath().getPath());
- project.addCompileSourceRoot(generatedSources.getPath());
+ project.addCompileSourceRoot(getGeneratedFileWriter().getScaffoldedSourcesDir().toString());
}
protected void generateModel() throws MojoExecutionException {
@@ -129,9 +117,11 @@ protected void generateModel() throws MojoExecutionException {
Map> mappedGeneratedFiles = generatedFiles.stream()
.collect(Collectors.groupingBy(GeneratedFile::type));
- mappedGeneratedFiles.entrySet().stream()
+ List generatedUncompiledFiles = mappedGeneratedFiles.entrySet().stream()
.filter(entry -> !entry.getKey().equals(COMPILED_CLASS))
- .forEach(entry -> writeGeneratedFiles(entry.getValue()));
+ .flatMap(entry -> entry.getValue().stream())
+ .toList();
+ writeGeneratedFiles(generatedUncompiledFiles);
List generatedCompiledFiles = mappedGeneratedFiles.getOrDefault(COMPILED_CLASS,
Collections.emptyList())
diff --git a/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/ProcessClassesMojo.java b/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/ProcessClassesMojo.java
index f5ffd9b3d85..ef491c7eca3 100644
--- a/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/ProcessClassesMojo.java
+++ b/kogito-maven-plugin/src/main/java/org/kie/kogito/maven/plugin/ProcessClassesMojo.java
@@ -98,14 +98,14 @@ public void execute() throws MojoExecutionException {
compileAndWriteClasses(generatedClasses, classLoader, settings);
// Dump resources
- generatedResources.forEach(this::writeGeneratedFile);
+ this.writeGeneratedFiles(generatedResources);
// Json schema generation
Stream> processClassStream = getReflections().getTypesAnnotatedWith(ProcessInput.class).stream();
- generateJsonSchema(processClassStream).forEach(this::writeGeneratedFile);
+ writeGeneratedFiles(generateJsonSchema(processClassStream));
Stream> userTaskClassStream = getReflections().getTypesAnnotatedWith(UserTask.class).stream();
- generateJsonSchema(userTaskClassStream).forEach(this::writeGeneratedFile);
+ writeGeneratedFiles(generateJsonSchema(userTaskClassStream));
} catch (Exception e) {
throw new MojoExecutionException("Error during processing model classes", e);
}
diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/io/ClassPathContentLoader.java b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/io/ClassPathContentLoader.java
index 56b80a8beba..413c199a674 100644
--- a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/io/ClassPathContentLoader.java
+++ b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/io/ClassPathContentLoader.java
@@ -24,6 +24,8 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
+import java.net.URLDecoder;
+import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.Optional;
@@ -40,7 +42,7 @@ public class ClassPathContentLoader extends CachedContentLoader {
static String getPath(URI uri) {
final String classPathPrefix = "classpath:";
- String str = uri.toString();
+ String str = URLDecoder.decode(uri.toString(), Charset.defaultCharset());
if (str.toLowerCase().startsWith(classPathPrefix)) {
str = str.substring(classPathPrefix.length());
while (str.startsWith("/")) {
diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/io/URIContentLoaderFactory.java b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/io/URIContentLoaderFactory.java
index 002174e876a..6e5b806594a 100644
--- a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/io/URIContentLoaderFactory.java
+++ b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/io/URIContentLoaderFactory.java
@@ -23,6 +23,8 @@
import java.io.UncheckedIOException;
import java.net.URI;
import java.net.URISyntaxException;
+import java.net.URLEncoder;
+import java.nio.charset.Charset;
import java.util.Optional;
import org.kie.kogito.serverless.workflow.parser.ParserContext;
@@ -91,7 +93,7 @@ public static Builder builder(URI uri) {
}
public static Builder builder(String uri) {
- return new Builder(URI.create(uri));
+ return new Builder(URI.create(URLEncoder.encode(uri, Charset.defaultCharset())));
}
public static class Builder {
diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/parser/handlers/MappingSetter.java b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/parser/handlers/MappingSetter.java
new file mode 100644
index 00000000000..adfa6a4e627
--- /dev/null
+++ b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/parser/handlers/MappingSetter.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.kie.kogito.serverless.workflow.parser.handlers;
+
+public interface MappingSetter {
+
+ void accept(Object value);
+
+ void accept(String key, Object value);
+}
diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/parser/handlers/MappingUtils.java b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/parser/handlers/MappingUtils.java
new file mode 100644
index 00000000000..ec644248312
--- /dev/null
+++ b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/parser/handlers/MappingUtils.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.kie.kogito.serverless.workflow.parser.handlers;
+
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.jbpm.ruleflow.core.factory.MappableNodeFactory;
+import org.kie.kogito.jackson.utils.JsonNodeVisitor;
+import org.kie.kogito.jackson.utils.JsonObjectUtils;
+import org.kie.kogito.serverless.workflow.SWFConstants;
+import org.kie.kogito.serverless.workflow.utils.ExpressionHandlerUtils;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import io.serverlessworkflow.api.Workflow;
+
+public class MappingUtils {
+
+ public static > T addMapping(T nodeFactory, String inputVar, String outputVar) {
+ return (T) nodeFactory.inMapping(inputVar, SWFConstants.MODEL_WORKFLOW_VAR)
+ .outMapping(SWFConstants.RESULT, outputVar);
+ }
+
+ public static final void processArgs(Workflow workflow,
+ JsonNode functionArgs, MappingSetter setter) {
+ if (functionArgs.isObject()) {
+ functionsToMap(workflow, functionArgs).forEach((key, value) -> setter.accept(key, value));
+ } else {
+ Object object = functionReference(workflow, JsonObjectUtils.simpleToJavaValue(functionArgs));
+ setter.accept(object);
+ }
+ }
+
+ private static Map functionsToMap(Workflow workflow, JsonNode jsonNode) {
+ Map map = new LinkedHashMap<>();
+ if (jsonNode != null) {
+ Iterator> iter = jsonNode.fields();
+ while (iter.hasNext()) {
+ Entry entry = iter.next();
+ map.put(entry.getKey(), functionReference(workflow, JsonObjectUtils.simpleToJavaValue(entry.getValue())));
+ }
+ }
+ return map;
+ }
+
+ private static Object functionReference(Workflow workflow, Object object) {
+ if (object instanceof JsonNode) {
+ return JsonNodeVisitor.transformTextNode((JsonNode) object, node -> JsonObjectUtils.fromValue(ExpressionHandlerUtils.replaceExpr(workflow, node.asText())));
+ } else if (object instanceof CharSequence) {
+ return ExpressionHandlerUtils.replaceExpr(workflow, object.toString());
+ } else {
+ return object;
+ }
+ }
+}
diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/utils/WorkItemBuilder.java b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/utils/WorkItemBuilder.java
index bd7b522b47c..fbb03806de0 100644
--- a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/utils/WorkItemBuilder.java
+++ b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/main/java/org/kie/kogito/serverless/workflow/utils/WorkItemBuilder.java
@@ -19,20 +19,17 @@
package org.kie.kogito.serverless.workflow.utils;
import java.util.Collection;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
import java.util.Map;
-import java.util.Map.Entry;
import org.jbpm.process.core.datatype.DataType;
import org.jbpm.process.core.datatype.DataTypeResolver;
import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
import org.jbpm.ruleflow.core.factory.WorkItemNodeFactory;
-import org.kie.kogito.jackson.utils.JsonNodeVisitor;
-import org.kie.kogito.jackson.utils.JsonObjectUtils;
import org.kie.kogito.process.expr.ExpressionHandlerFactory;
import org.kie.kogito.serverless.workflow.SWFConstants;
import org.kie.kogito.serverless.workflow.parser.ParserContext;
+import org.kie.kogito.serverless.workflow.parser.handlers.MappingSetter;
+import org.kie.kogito.serverless.workflow.parser.handlers.MappingUtils;
import org.kie.kogito.serverless.workflow.suppliers.ExpressionParametersFactorySupplier;
import org.kie.kogito.serverless.workflow.suppliers.ObjectResolverSupplier;
@@ -45,8 +42,6 @@
public abstract class WorkItemBuilder {
- private static final String RESULT = "Result";
-
protected > WorkItemNodeFactory addFunctionArgs(Workflow workflow, WorkItemNodeFactory node, FunctionRef functionRef) {
JsonNode functionArgs = functionRef.getArguments();
if (functionArgs != null) {
@@ -72,59 +67,40 @@ protected WorkItemNodeFactory> buildWorkItem(RuleFlowNodeContainerFactory, ?
ParserContext parserContext,
String inputVar,
String outputVar) {
- return embeddedSubProcess.workItemNode(parserContext.newId())
- .inMapping(inputVar, SWFConstants.MODEL_WORKFLOW_VAR)
- .outMapping(RESULT, outputVar);
+ return MappingUtils.addMapping(embeddedSubProcess.workItemNode(parserContext.newId()), inputVar, outputVar);
}
protected final void processArgs(Workflow workflow, WorkItemNodeFactory> workItemFactory,
JsonNode functionArgs, String paramName) {
- if (functionArgs.isObject()) {
- functionsToMap(workflow, functionArgs).forEach((key, value) -> processArg(workflow, key, value, workItemFactory, paramName));
- } else {
- Object object = functionReference(workflow, JsonObjectUtils.simpleToJavaValue(functionArgs));
- boolean isExpr = isExpression(workflow, object);
- if (isExpr) {
- workItemFactory.workParameterFactory(new ExpressionParametersFactorySupplier(workflow.getExpressionLang(), object, paramName));
- } else {
- workItemFactory.workParameter(SWFConstants.CONTENT_DATA, object);
+ MappingUtils.processArgs(workflow, functionArgs, new MappingSetter() {
+ @Override
+ public void accept(String key, Object value) {
+ boolean isExpr = isExpression(workflow, value);
+ workItemFactory
+ .workParameter(key,
+ isExpr ? new ObjectResolverSupplier(workflow.getExpressionLang(), value, paramName) : value)
+ .workParameterDefinition(key,
+ getDataType(value, isExpr));
}
- workItemFactory.workParameterDefinition(SWFConstants.CONTENT_DATA, getDataType(object, isExpr));
- }
- }
- private Map functionsToMap(Workflow workflow, JsonNode jsonNode) {
- Map map = new LinkedHashMap<>();
- if (jsonNode != null) {
- Iterator> iter = jsonNode.fields();
- while (iter.hasNext()) {
- Entry entry = iter.next();
- map.put(entry.getKey(), functionReference(workflow, JsonObjectUtils.simpleToJavaValue(entry.getValue())));
+ @Override
+ public void accept(Object value) {
+ boolean isExpr = isExpression(workflow, value);
+ if (isExpr) {
+ workItemFactory.workParameterFactory(new ExpressionParametersFactorySupplier(workflow.getExpressionLang(), value, paramName));
+ } else {
+ workItemFactory.workParameter(SWFConstants.CONTENT_DATA, value);
+ }
+ workItemFactory.workParameterDefinition(SWFConstants.CONTENT_DATA, getDataType(value, isExpr));
}
- }
- return map;
+ });
}
- private Object functionReference(Workflow workflow, Object object) {
- if (object instanceof JsonNode) {
- return JsonNodeVisitor.transformTextNode((JsonNode) object, node -> JsonObjectUtils.fromValue(ExpressionHandlerUtils.replaceExpr(workflow, node.asText())));
- } else if (object instanceof CharSequence) {
- return ExpressionHandlerUtils.replaceExpr(workflow, object.toString());
- } else {
- return object;
- }
- }
-
- private void processArg(Workflow workflow, String key, Object value, WorkItemNodeFactory> workItemFactory, String paramName) {
- boolean isExpr = isExpression(workflow, value);
- workItemFactory
- .workParameter(key,
- isExpr ? new ObjectResolverSupplier(workflow.getExpressionLang(), value, paramName) : value)
- .workParameterDefinition(key,
- getDataType(value, isExpr));
+ private static boolean isExpression(Workflow workflow, Object value) {
+ return value instanceof CharSequence && ExpressionHandlerFactory.get(workflow.getExpressionLang(), value.toString()).isValid() || value instanceof JsonNode;
}
- DataType getDataType(Object object, boolean isExpr) {
+ private static DataType getDataType(Object object, boolean isExpr) {
if (object instanceof ObjectNode) {
return DataTypeResolver.fromClass(Map.class);
} else if (object instanceof ArrayNode) {
@@ -133,8 +109,4 @@ DataType getDataType(Object object, boolean isExpr) {
return DataTypeResolver.fromObject(object, isExpr);
}
}
-
- private boolean isExpression(Workflow workflow, Object value) {
- return value instanceof CharSequence && ExpressionHandlerFactory.get(workflow.getExpressionLang(), value.toString()).isValid() || value instanceof JsonNode;
- }
}
diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/test/java/org/kie/kogito/serverless/workflow/io/URIContentLoaderTest.java b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/test/java/org/kie/kogito/serverless/workflow/io/URIContentLoaderTest.java
index d3d9ac9b3d6..e3c2ec36962 100644
--- a/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/test/java/org/kie/kogito/serverless/workflow/io/URIContentLoaderTest.java
+++ b/kogito-serverless-workflow/kogito-serverless-workflow-builder/src/test/java/org/kie/kogito/serverless/workflow/io/URIContentLoaderTest.java
@@ -27,7 +27,6 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.kie.kogito.serverless.workflow.io.URIContentLoaderFactory.builder;
import static org.kie.kogito.serverless.workflow.io.URIContentLoaderFactory.compoundURI;
import static org.kie.kogito.serverless.workflow.io.URIContentLoaderFactory.readString;
@@ -53,7 +52,7 @@ void testNotExistingFile() {
@Test
void testNotExistingClasspath() {
Builder builder = builder("classpath:/noPepe.txt");
- assertThatIllegalArgumentException().isThrownBy(() -> readString(builder));
+ assertThatExceptionOfType(UncheckedIOException.class).isThrownBy(() -> readString(builder));
}
@Test
diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-dmn-parser/pom.xml b/kogito-serverless-workflow/kogito-serverless-workflow-dmn-parser/pom.xml
new file mode 100644
index 00000000000..cbb756c105a
--- /dev/null
+++ b/kogito-serverless-workflow/kogito-serverless-workflow-dmn-parser/pom.xml
@@ -0,0 +1,62 @@
+
+ 4.0.0
+
+ org.kie.kogito
+ kogito-serverless-workflow
+ 999-SNAPSHOT
+
+ Kogito :: Serverless Workflow :: DMN :: Parser
+
+
+ org.kie.kogito.serverless.workflow.dmn.parser
+
+
+ kogito-serverless-workflow-dmn-parser
+
+
+ org.kie.kogito
+ kogito-serverless-workflow-builder
+
+
+ org.kie.kogito
+ kogito-serverless-workflow-dmn
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-params
+ test
+
+
+ ch.qos.logback
+ logback-classic
+ test
+
+
+ org.kie.kogito
+ kogito-serverless-workflow-fluent
+ test
+
+
+ org.kie.kogito
+ kogito-serverless-workflow-executor-core
+ test
+
+
+ org.kie
+ kie-dmn-test-resources
+ tests
+ ${project.version}
+ test
+
+
+ org.assertj
+ assertj-core
+ test
+
+
+
\ No newline at end of file
diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-dmn-parser/src/main/java/org/kie/kogito/serverless/workflow/parser/types/DMNTypeHandler.java b/kogito-serverless-workflow/kogito-serverless-workflow-dmn-parser/src/main/java/org/kie/kogito/serverless/workflow/parser/types/DMNTypeHandler.java
new file mode 100644
index 00000000000..0b98f50dc24
--- /dev/null
+++ b/kogito-serverless-workflow/kogito-serverless-workflow-dmn-parser/src/main/java/org/kie/kogito/serverless/workflow/parser/types/DMNTypeHandler.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.kie.kogito.serverless.workflow.parser.types;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UncheckedIOException;
+import java.util.Map;
+import java.util.Objects;
+
+import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
+import org.jbpm.ruleflow.core.factory.NodeFactory;
+import org.jbpm.ruleflow.core.factory.RuleSetNodeFactory;
+import org.kie.kogito.decision.DecisionModel;
+import org.kie.kogito.dmn.DMNKogito;
+import org.kie.kogito.dmn.DmnDecisionModel;
+import org.kie.kogito.serverless.workflow.SWFConstants;
+import org.kie.kogito.serverless.workflow.dmn.SWFDecisionEngine;
+import org.kie.kogito.serverless.workflow.io.URIContentLoaderFactory;
+import org.kie.kogito.serverless.workflow.parser.FunctionTypeHandler;
+import org.kie.kogito.serverless.workflow.parser.ParserContext;
+import org.kie.kogito.serverless.workflow.parser.VariableInfo;
+import org.kie.kogito.serverless.workflow.parser.handlers.MappingSetter;
+import org.kie.kogito.serverless.workflow.parser.handlers.MappingUtils;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import io.serverlessworkflow.api.Workflow;
+import io.serverlessworkflow.api.functions.FunctionDefinition;
+import io.serverlessworkflow.api.functions.FunctionRef;
+
+public class DMNTypeHandler implements FunctionTypeHandler {
+
+ private static final String DMN_TYPE = "dmn";
+ public static final String NAMESPACE = "namespace";
+ public static final String MODEL = "model";
+ public static final String FILE = "file";
+
+ private static final String REQUIRED_MESSAGE = "%s is required on metadata for DMN";
+
+ @Override
+ public String type() {
+ return DMN_TYPE;
+ }
+
+ @Override
+ public boolean isCustom() {
+ return true;
+ }
+
+ @Override
+ public NodeFactory, ?> getActionNode(Workflow workflow, ParserContext context,
+ RuleFlowNodeContainerFactory, ?> embeddedSubProcess, FunctionDefinition functionDef,
+ FunctionRef functionRef, VariableInfo varInfo) {
+ Map metadata = Objects.requireNonNull(functionDef.getMetadata(), "Metadata is required for DMN");
+ String namespace = Objects.requireNonNull(metadata.get(NAMESPACE), String.format(REQUIRED_MESSAGE, NAMESPACE));
+ String model = Objects.requireNonNull(metadata.get(MODEL), String.format(REQUIRED_MESSAGE, MODEL));
+ String file = Objects.requireNonNull(metadata.get(FILE), String.format(REQUIRED_MESSAGE, FILE));
+ RuleSetNodeFactory> nodeFactory = MappingUtils.addMapping(embeddedSubProcess.ruleSetNode(context.newId()).decision(namespace, model, model, () -> loadDMNFromFile(namespace, model, file)),
+ varInfo.getInputVar(), varInfo.getOutputVar());
+ JsonNode functionArgs = functionRef.getArguments();
+ if (functionArgs != null) {
+ nodeFactory.metaData(SWFDecisionEngine.EXPR_LANG, workflow.getExpressionLang());
+ MappingUtils.processArgs(workflow, functionArgs, new MappingSetter() {
+ @Override
+ public void accept(String key, Object value) {
+ nodeFactory.parameter(key, value);
+ }
+
+ @Override
+ public void accept(Object value) {
+ nodeFactory.parameter(SWFConstants.CONTENT_DATA, value);
+ }
+ });
+ }
+ return nodeFactory;
+ }
+
+ private DecisionModel loadDMNFromFile(String namespace, String model, String file) {
+ try (Reader reader = new InputStreamReader(URIContentLoaderFactory.builder(file).withClassloader(this.getClass().getClassLoader()).build().getInputStream())) {
+ return new DmnDecisionModel(DMNKogito.createGenericDMNRuntime(reader), namespace, model);
+ } catch (IOException io) {
+ throw new UncheckedIOException(io);
+ }
+ }
+}
diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-dmn-parser/src/main/resources/META-INF/services/org.kie.kogito.serverless.workflow.parser.FunctionTypeHandler b/kogito-serverless-workflow/kogito-serverless-workflow-dmn-parser/src/main/resources/META-INF/services/org.kie.kogito.serverless.workflow.parser.FunctionTypeHandler
new file mode 100644
index 00000000000..8169c5bf60a
--- /dev/null
+++ b/kogito-serverless-workflow/kogito-serverless-workflow-dmn-parser/src/main/resources/META-INF/services/org.kie.kogito.serverless.workflow.parser.FunctionTypeHandler
@@ -0,0 +1 @@
+org.kie.kogito.serverless.workflow.parser.types.DMNTypeHandler
diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-dmn-parser/src/test/java/org/kie/kogito/serverless/workflow/dmn/SWFDMNTest.java b/kogito-serverless-workflow/kogito-serverless-workflow-dmn-parser/src/test/java/org/kie/kogito/serverless/workflow/dmn/SWFDMNTest.java
new file mode 100644
index 00000000000..d2828b98930
--- /dev/null
+++ b/kogito-serverless-workflow/kogito-serverless-workflow-dmn-parser/src/test/java/org/kie/kogito/serverless/workflow/dmn/SWFDMNTest.java
@@ -0,0 +1,57 @@
+package org.kie.kogito.serverless.workflow.dmn;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Map;
+
+import org.junit.jupiter.api.Test;
+import org.kie.kogito.serverless.workflow.executor.StaticWorkflowApplication;
+import org.kie.kogito.serverless.workflow.parser.types.DMNTypeHandler;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.TextNode;
+
+import io.serverlessworkflow.api.Workflow;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.kie.kogito.serverless.workflow.fluent.ActionBuilder.call;
+import static org.kie.kogito.serverless.workflow.fluent.FunctionBuilder.custom;
+import static org.kie.kogito.serverless.workflow.fluent.StateBuilder.operation;
+import static org.kie.kogito.serverless.workflow.fluent.WorkflowBuilder.workflow;
+
+public class SWFDMNTest {
+ @Test
+ void testDMNFile() throws IOException {
+ doIt(buildWorkflow(Collections.emptyMap()));
+ }
+
+ @Test
+ void testDMNFileWithArgs() throws IOException {
+ doIt(buildWorkflow(Map.of("Driver", ".Driver", "Violation", ".Violation")));
+ }
+
+ @Test
+ void testDMNFileWithExprArg() throws IOException {
+ doIt(buildWorkflow("{Driver:.Driver,Violation:.Violation}"));
+ }
+
+ private void doIt(Workflow workflow) {
+ try (StaticWorkflowApplication application = StaticWorkflowApplication.create()) {
+ JsonNode response = application.execute(workflow, Map.of("Driver", Map.of("Name", "Pepe", "Age", 19, "Points", 0, "State", "Spain", "City", "Zaragoza"), "Violation", Map.of("Code", "12",
+ "Date", new Date(System.currentTimeMillis()), "Type", "parking"))).getWorkflowdata();
+ assertThat(response.get("Should the driver be suspended?")).isEqualTo(new TextNode("No"));
+ response = application.execute(workflow, Map.of("Driver", Map.of("Name", "Pepe", "Age", 19, "Points", 19, "State", "Spain", "City", "Zaragoza"), "Violation", Map.of("Code", "12",
+ "Date", new Date(System.currentTimeMillis()), "Type", "speed", "Speed Limit", "120", "Actual Speed", "180"))).getWorkflowdata();
+ assertThat(response.get("Should the driver be suspended?")).isEqualTo(new TextNode("Yes"));
+ }
+ }
+
+ private Workflow buildWorkflow(Object args) {
+ return workflow("PlayingWithDMN")
+ .start(operation().action(call(custom("DMNTest", "dmn").metadata(DMNTypeHandler.FILE, "classpath:valid_models/DMNv1_x/Traffic Violation Simple.dmn")
+ .metadata(DMNTypeHandler.MODEL, "Traffic Violation")
+ .metadata(DMNTypeHandler.NAMESPACE, "https://github.com/kiegroup/drools/kie-dmn/_A4BCA8B8-CF08-433F-93B2-A2598F19ECFF"), args)))
+ .end().build();
+ }
+}
diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-dmn/pom.xml b/kogito-serverless-workflow/kogito-serverless-workflow-dmn/pom.xml
new file mode 100644
index 00000000000..7a8d68802b3
--- /dev/null
+++ b/kogito-serverless-workflow/kogito-serverless-workflow-dmn/pom.xml
@@ -0,0 +1,24 @@
+
+ 4.0.0
+
+ org.kie.kogito
+ kogito-serverless-workflow
+ 999-SNAPSHOT
+
+ kogito-serverless-workflow-dmn
+ Kogito :: Serverless Workflow :: DMN :: Runtime
+
+ org.kie.kogito.serverless.workflow.dmn.runtime
+
+
+
+
+ org.kie.kogito
+ kogito-serverless-workflow-runtime
+
+
+ org.kie.kogito
+ kogito-dmn
+
+
+
\ No newline at end of file
diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-dmn/src/main/java/org/kie/kogito/serverless/workflow/dmn/SWFDecisionEngine.java b/kogito-serverless-workflow/kogito-serverless-workflow-dmn/src/main/java/org/kie/kogito/serverless/workflow/dmn/SWFDecisionEngine.java
new file mode 100644
index 00000000000..c84acfc652a
--- /dev/null
+++ b/kogito-serverless-workflow/kogito-serverless-workflow-dmn/src/main/java/org/kie/kogito/serverless/workflow/dmn/SWFDecisionEngine.java
@@ -0,0 +1,96 @@
+package org.kie.kogito.serverless.workflow.dmn;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.jbpm.util.ContextFactory;
+import org.jbpm.workflow.core.impl.NodeIoHelper;
+import org.jbpm.workflow.core.node.RuleSetNode;
+import org.jbpm.workflow.instance.node.RuleSetNodeInstance;
+import org.jbpm.workflow.instance.rule.DecisionRuleTypeEngine;
+import org.kie.api.runtime.KieSession;
+import org.kie.dmn.api.core.DMNContext;
+import org.kie.dmn.api.core.DMNMessage;
+import org.kie.dmn.api.core.DMNResult;
+import org.kie.dmn.api.core.DMNRuntime;
+import org.kie.kogito.decision.DecisionModel;
+import org.kie.kogito.dmn.DmnDecisionModel;
+import org.kie.kogito.dmn.rest.DMNJSONUtils;
+import org.kie.kogito.internal.process.runtime.KogitoProcessContext;
+import org.kie.kogito.jackson.utils.JsonObjectUtils;
+import org.kie.kogito.process.expr.Expression;
+import org.kie.kogito.process.expr.ExpressionHandlerFactory;
+import org.kie.kogito.serverless.workflow.SWFConstants;
+
+import static org.kie.kogito.serverless.workflow.SWFConstants.CONTENT_DATA;
+
+public class SWFDecisionEngine implements DecisionRuleTypeEngine {
+
+ public static final String EXPR_LANG = "lang";
+
+ @Override
+ public void evaluate(RuleSetNodeInstance rsni, String inputNamespace, String inputModel, String decision) {
+ String namespace = rsni.resolveExpression(inputNamespace);
+ String model = rsni.resolveExpression(inputModel);
+ DecisionModel modelInstance =
+ Optional.ofNullable(rsni.getRuleSetNode().getDecisionModel())
+ .orElse(() -> new DmnDecisionModel(
+ ((KieSession) getKieRuntime(rsni)).getKieRuntime(DMNRuntime.class),
+ namespace,
+ model))
+ .get();
+
+ //Input Binding
+ DMNContext context = DMNJSONUtils.ctx(modelInstance, getInputParameters(rsni));
+ DMNResult dmnResult = modelInstance.evaluateAll(context);
+ if (dmnResult.hasErrors()) {
+ String errors = dmnResult.getMessages(DMNMessage.Severity.ERROR).stream()
+ .map(Object::toString)
+ .collect(Collectors.joining(", "));
+
+ throw new RuntimeException("DMN result errors:: " + errors);
+ }
+ //Output Binding
+ Map outputSet = Map.of(SWFConstants.RESULT, dmnResult.getContext().getAll());
+ NodeIoHelper.processOutputs(rsni, outputSet::get, rsni::getVariable);
+
+ rsni.triggerCompleted();
+ }
+
+ private Map getInputParameters(RuleSetNodeInstance rsni) {
+ RuleSetNode node = rsni.getRuleSetNode();
+ Map inputParameters = node.getParameters();
+ int size = inputParameters.size();
+ if (size == 0) {
+ inputParameters = JsonObjectUtils.convertValue(getInputs(rsni).get(SWFConstants.MODEL_WORKFLOW_VAR), Map.class);
+ } else if (size == 1 && inputParameters.containsKey(CONTENT_DATA)) {
+ return eval(ContextFactory.fromNode(rsni), ExpressionHandlerFactory.get((String) node.getMetaData().get(EXPR_LANG), (String) inputParameters.get(CONTENT_DATA)));
+ } else {
+ inputParameters = getInputParameters(ContextFactory.fromNode(rsni), (String) node.getMetaData().get(EXPR_LANG), new HashMap<>(inputParameters));
+ }
+ return inputParameters;
+
+ }
+
+ private Map getInputParameters(KogitoProcessContext context, String exprLang, Map inputParameters) {
+ for (Map.Entry entry : inputParameters.entrySet()) {
+ Object value = entry.getValue();
+ if (value instanceof Map) {
+ entry.setValue(getInputParameters(context, exprLang, (Map) value));
+ } else if (value instanceof CharSequence) {
+ Expression expr = ExpressionHandlerFactory.get(exprLang, value.toString());
+ if (expr.isValid()) {
+ entry.setValue(eval(context, expr));
+ }
+ }
+ }
+ return inputParameters;
+ }
+
+ private Map eval(KogitoProcessContext context, Expression expr) {
+ return expr.eval(JsonObjectUtils.fromValue(context.getVariable(SWFConstants.DEFAULT_WORKFLOW_VAR)), Map.class, context);
+ }
+
+}
diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-dmn/src/main/resources/META-INF/services/org.jbpm.workflow.instance.rule.DecisionRuleTypeEngine b/kogito-serverless-workflow/kogito-serverless-workflow-dmn/src/main/resources/META-INF/services/org.jbpm.workflow.instance.rule.DecisionRuleTypeEngine
new file mode 100644
index 00000000000..077e0fb2c7d
--- /dev/null
+++ b/kogito-serverless-workflow/kogito-serverless-workflow-dmn/src/main/resources/META-INF/services/org.jbpm.workflow.instance.rule.DecisionRuleTypeEngine
@@ -0,0 +1 @@
+org.kie.kogito.serverless.workflow.dmn.SWFDecisionEngine
\ No newline at end of file
diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-fluent/src/main/java/org/kie/kogito/serverless/workflow/fluent/FunctionBuilder.java b/kogito-serverless-workflow/kogito-serverless-workflow-fluent/src/main/java/org/kie/kogito/serverless/workflow/fluent/FunctionBuilder.java
index cc2182c414e..1abe1d2fca1 100644
--- a/kogito-serverless-workflow/kogito-serverless-workflow-fluent/src/main/java/org/kie/kogito/serverless/workflow/fluent/FunctionBuilder.java
+++ b/kogito-serverless-workflow/kogito-serverless-workflow-fluent/src/main/java/org/kie/kogito/serverless/workflow/fluent/FunctionBuilder.java
@@ -76,12 +76,15 @@ public static FunctionBuilder python(String funcName, String moduleName, String
}
private static FunctionBuilder service(String name, String langName, String moduleName, String methodName) {
- return new FunctionBuilder(new FunctionDefinition(name).withType(Type.CUSTOM)
- .withOperation(ServiceTypeHandler.SERVICE_TYPE + CUSTOM_TYPE_SEPARATOR + langName + CUSTOM_TYPE_SEPARATOR + moduleName + ServiceTypeHandler.INTFC_SEPARATOR + methodName));
+ return custom(name, ServiceTypeHandler.SERVICE_TYPE + CUSTOM_TYPE_SEPARATOR + langName + CUSTOM_TYPE_SEPARATOR + moduleName + ServiceTypeHandler.INTFC_SEPARATOR + methodName);
}
public static FunctionBuilder log(String name, WorkflowLogLevel level) {
- return new FunctionBuilder(new FunctionDefinition(name).withType(Type.CUSTOM).withOperation(SYSOUT_TYPE + CUSTOM_TYPE_SEPARATOR + level));
+ return custom(name, SYSOUT_TYPE + CUSTOM_TYPE_SEPARATOR + level);
+ }
+
+ public static FunctionBuilder custom(String name, String operation) {
+ return new FunctionBuilder(new FunctionDefinition(name).withType(Type.CUSTOM).withOperation(operation));
}
private FunctionBuilder(FunctionDefinition functionDefinition) {
diff --git a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/SWFConstants.java b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/SWFConstants.java
index 20a7b7d5ad0..3d822ab0be3 100644
--- a/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/SWFConstants.java
+++ b/kogito-serverless-workflow/kogito-serverless-workflow-runtime/src/main/java/org/kie/kogito/serverless/workflow/SWFConstants.java
@@ -21,6 +21,7 @@
public class SWFConstants {
public static final String DEFAULT_WORKFLOW_VAR = "workflowdata";
+ public static final String RESULT = "Result";
public static final String MODEL_WORKFLOW_VAR = "Parameter";
public static final String CONTENT_DATA = "ContentData";
public static final String SCRIPT = "script";
diff --git a/kogito-serverless-workflow/pom.xml b/kogito-serverless-workflow/pom.xml
index f752d16d206..cfca4a918e3 100644
--- a/kogito-serverless-workflow/pom.xml
+++ b/kogito-serverless-workflow/pom.xml
@@ -55,6 +55,8 @@
kogito-jq-expression
kogito-serverless-workflow-executor
kogito-serverless-workflow-executor-tests
+ kogito-serverless-workflow-dmn-parser
+ kogito-serverless-workflow-dmn
diff --git a/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common-deployment/src/main/java/org/kie/kogito/quarkus/common/deployment/KogitoAssetsProcessor.java b/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common-deployment/src/main/java/org/kie/kogito/quarkus/common/deployment/KogitoAssetsProcessor.java
index ab63a083fdb..346a0f5a40d 100644
--- a/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common-deployment/src/main/java/org/kie/kogito/quarkus/common/deployment/KogitoAssetsProcessor.java
+++ b/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common-deployment/src/main/java/org/kie/kogito/quarkus/common/deployment/KogitoAssetsProcessor.java
@@ -34,6 +34,7 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import org.drools.codegen.common.AppPaths;
import org.drools.codegen.common.DroolsModelBuildContext;
import org.drools.codegen.common.GeneratedFile;
import org.drools.codegen.common.GeneratedFileType;
@@ -107,10 +108,9 @@ public class KogitoAssetsProcessor {
@BuildStep
public KogitoBuildContextBuildItem generateKogitoBuildContext(List attributes) {
// configure the application generator
- PathCollection rootPaths = getRootPaths(root.getResolvedPaths());
+ PathCollection rootPaths = getRootPaths(root.getResolvedPaths(), AppPaths.BT);
KogitoBuildContext context =
- kogitoBuildContext(outputTargetBuildItem.getOutputDirectory(),
- rootPaths,
+ kogitoBuildContext(rootPaths,
combinedIndexBuildItem.getIndex(),
curateOutcomeBuildItem.getApplicationModel().getAppArtifact());
attributes.forEach(attribute -> context.addContextAttribute(attribute.getName(), attribute.getValue()));
@@ -218,26 +218,26 @@ public EfestoGeneratedClassBuildItem reflectiveEfestoGeneratedClassBuildItem(Kog
return new EfestoGeneratedClassBuildItem(kogitoGeneratedSourcesBuildItem.getGeneratedFiles());
}
- static PathCollection getRootPaths(PathCollection resolvedPaths) {
- AtomicReference toReturnRef = new AtomicReference<>(resolvedPaths);
- if (resolvedPaths.stream().noneMatch(path -> path.endsWith(File.separator + "generated-resources"))) {
- Optional optClassesPath =
- resolvedPaths.stream().filter(path -> {
- String fullPath = path.toString();
- String dir = fullPath.substring(fullPath.lastIndexOf(File.separator) + 1);
- return dir.equals("classes");
- }).findFirst();
- optClassesPath.ifPresent(classesPath -> {
- Path toAdd = Path.of(classesPath.toString().replace(File.separator + "classes",
- File.separator +
- "generated" +
- "-resources"));
- List prevPaths = toReturnRef.get().stream().collect(Collectors.toList());
- prevPaths.add(toAdd);
- toReturnRef.set(PathList.from(prevPaths));
- });
+ static PathCollection getRootPaths(PathCollection resolvedPaths, AppPaths.BuildTool bt) {
+ // Needed hack because during MAVEN build, resolvedPaths point to root of project,
+ // while during GRADLE build, resolved paths contains {root_project}/build/classes/java/main and
+ // {root_project}/build/resources/main
+ switch (bt) {
+ case GRADLE -> {
+ AtomicReference toReturnRef = new AtomicReference<>(resolvedPaths);
+ Optional optClassesPath =
+ resolvedPaths.stream().filter(path -> {
+ String fullPath = path.toString();
+ String lookingFor = "build/classes/java/main".replace("/", File.separator);
+ return fullPath.endsWith(lookingFor);
+ }).findFirst();
+ optClassesPath.ifPresent(classesPath -> toReturnRef.set(PathList.of(classesPath)));
+ return toReturnRef.get();
+ }
+ default -> {
+ return resolvedPaths;
+ }
}
- return toReturnRef.get();
}
private Collection collectGeneratedFiles(KogitoGeneratedSourcesBuildItem sources, List preSources,
diff --git a/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common-deployment/src/main/java/org/kie/kogito/quarkus/common/deployment/KogitoQuarkusResourceUtils.java b/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common-deployment/src/main/java/org/kie/kogito/quarkus/common/deployment/KogitoQuarkusResourceUtils.java
index 3b10caeaa95..6a83445f27e 100644
--- a/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common-deployment/src/main/java/org/kie/kogito/quarkus/common/deployment/KogitoQuarkusResourceUtils.java
+++ b/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common-deployment/src/main/java/org/kie/kogito/quarkus/common/deployment/KogitoQuarkusResourceUtils.java
@@ -34,6 +34,7 @@
import org.drools.codegen.common.DroolsModelBuildContext;
import org.drools.codegen.common.GeneratedFile;
import org.drools.codegen.common.GeneratedFileType;
+import org.drools.codegen.common.GeneratedFileWriter;
import org.drools.quarkus.util.deployment.QuarkusAppPaths;
import org.drools.util.PortablePath;
import org.eclipse.microprofile.config.ConfigProvider;
@@ -44,7 +45,6 @@
import org.kie.kogito.codegen.api.SourceFileCodegenBindNotifier;
import org.kie.kogito.codegen.api.context.KogitoBuildContext;
import org.kie.kogito.codegen.api.context.impl.QuarkusKogitoBuildContext;
-import org.kie.kogito.codegen.core.utils.GeneratedFileWriter;
import org.kie.memorycompiler.resources.ResourceReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -76,16 +76,11 @@ private KogitoQuarkusResourceUtils() {
// since quarkus-maven-plugin is later phase of maven-resources-plugin,
// need to manually late-provide the resource in the expected location for quarkus:dev phase --so not: writeGeneratedFile( f, resourcePath )
- private static final GeneratedFileWriter.Builder generatedFileWriterBuilder =
- new GeneratedFileWriter.Builder(
- "target/classes",
- System.getProperty("kogito.codegen.sources.directory", "target/generated-sources/kogito/"),
- System.getProperty("kogito.codegen.resources.directory", "target/generated-resources/kogito/"),
- "target/generated-sources/kogito/");
-
- public static KogitoBuildContext kogitoBuildContext(Path outputTarget, Iterable paths, IndexView index, Dependency appArtifact) {
+ private static final GeneratedFileWriter.Builder generatedFileWriterBuilder = GeneratedFileWriter.builder("kogito", "kogito.codegen.resources.directory", "kogito.codegen.sources.directory");
+
+ public static KogitoBuildContext kogitoBuildContext(Iterable paths, IndexView index, Dependency appArtifact) {
// scan and parse paths
- AppPaths appPaths = QuarkusAppPaths.from(outputTarget, paths, AppPaths.BuildTool.findBuildTool());
+ AppPaths appPaths = QuarkusAppPaths.from(paths);
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
KogitoBuildContext context = QuarkusKogitoBuildContext.builder()
.withApplicationPropertyProvider(new KogitoQuarkusApplicationPropertiesProvider())
@@ -111,9 +106,7 @@ public static KogitoBuildContext kogitoBuildContext(Path outputTarget, Iterable<
private static Predicate> classSubTypeAvailabilityResolver(IndexView index) {
return clazz -> index.getAllKnownImplementors(DotName.createSimple(clazz.getCanonicalName()))
.stream()
- .filter(c -> !Modifier.isInterface(c.flags()) && !Modifier.isAbstract(c.flags()))
- .findFirst()
- .isPresent();
+ .anyMatch(c -> !Modifier.isInterface(c.flags()) && !Modifier.isAbstract(c.flags()));
}
/**
diff --git a/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common-deployment/src/test/java/org/kie/kogito/quarkus/common/deployment/KogitoAssetsProcessorTest.java b/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common-deployment/src/test/java/org/kie/kogito/quarkus/common/deployment/KogitoAssetsProcessorTest.java
index f641e28af93..fd7483bb677 100644
--- a/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common-deployment/src/test/java/org/kie/kogito/quarkus/common/deployment/KogitoAssetsProcessorTest.java
+++ b/quarkus/extensions/kogito-quarkus-extension-common/kogito-quarkus-common-deployment/src/test/java/org/kie/kogito/quarkus/common/deployment/KogitoAssetsProcessorTest.java
@@ -22,7 +22,9 @@
import java.nio.file.Path;
import java.util.Arrays;
-import org.junit.jupiter.api.Test;
+import org.drools.codegen.common.AppPaths;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
import io.quarkus.bootstrap.model.PathsCollection;
import io.quarkus.paths.PathCollection;
@@ -32,34 +34,45 @@
class KogitoAssetsProcessorTest {
- @Test
- void getRootPathsWithoutClasses() {
+ @ParameterizedTest
+ @ValueSource(booleans = { true, false })
+ void getRootPathsWithoutClasses(boolean withGradle) {
String projectDirPath = "projectDir";
- String outputTargetPath = "outputTarget";
Path projectDir = Path.of(projectDirPath);
- Path outputTarget = Path.of(outputTargetPath);
+ AppPaths.BuildTool bt;
+ if (withGradle) {
+ bt = AppPaths.BuildTool.GRADLE;
+ } else {
+ bt = AppPaths.BuildTool.MAVEN;
+ }
+ Path outputTarget = Path.of(bt.OUTPUT_DIRECTORY);
Iterable paths = Arrays.asList(projectDir, outputTarget);
-
PathCollection resolvedPaths = PathsCollection.from(paths);
- PathCollection retrieved = KogitoAssetsProcessor.getRootPaths(resolvedPaths);
+ PathCollection retrieved = KogitoAssetsProcessor.getRootPaths(resolvedPaths, bt);
assertEquals(resolvedPaths.size(), retrieved.size());
paths.forEach(expected -> assertTrue(retrieved.contains(expected)));
}
- @Test
- void getRootPathsWithClasses() {
+ @ParameterizedTest
+ @ValueSource(booleans = { true, false })
+ void getRootPathsWithClasses(boolean withGradle) {
String projectDirPath = "projectDir";
- String outputTargetPath = "outputTarget";
- String outputTargetPathClasses = String.format("%s/%s/classes", projectDirPath, outputTargetPath).replace("/", File.separator);
+ AppPaths.BuildTool bt;
+ if (withGradle) {
+ bt = AppPaths.BuildTool.GRADLE;
+ } else {
+ bt = AppPaths.BuildTool.MAVEN;
+ }
+ String outputTargetPathClasses = String.format("%s/%s", projectDirPath, bt.CLASSES_PATH.toString()).replace("./", "").replace("/", File.separator);
Path projectDir = Path.of(projectDirPath);
Path outputTarget = Path.of(outputTargetPathClasses);
Iterable paths = Arrays.asList(projectDir, outputTarget);
PathCollection resolvedPaths = PathsCollection.from(paths);
- PathCollection retrieved = KogitoAssetsProcessor.getRootPaths(resolvedPaths);
- assertEquals(resolvedPaths.size() + 1, retrieved.size());
- paths.forEach(expected -> assertTrue(retrieved.contains(expected)));
- String expectedPath = String.format("%s/%s/generated-resources", projectDirPath, outputTargetPath).replace("/", File.separator);
+ PathCollection retrieved = KogitoAssetsProcessor.getRootPaths(resolvedPaths, bt);
+ int expectedSize = withGradle ? 1 : resolvedPaths.size();
+ assertEquals(expectedSize, retrieved.size());
+ String expectedPath = String.format("%s/%s", projectDirPath, bt.CLASSES_PATH).replace("/", File.separator);
assertTrue(retrieved.contains(Path.of(expectedPath)));
}
}