This is an automated email from the ASF dual-hosted git repository.
pefernan pushed a commit to branch main
in repository
https://gitbox.apache.org/repos/asf/incubator-kie-kogito-runtimes.git
The following commit(s) were added to refs/heads/main by this push:
new a114543f17 [incubator-kie-issues#2040] [Data Index Spring-Boot]:
Create Spring-Boot version of the Source Files addon (#4001)
a114543f17 is described below
commit a114543f17aef499582a08032ae7cf55b94303cb
Author: Pere Fernández <[email protected]>
AuthorDate: Wed Jul 30 10:47:49 2025 +0200
[incubator-kie-issues#2040] [Data Index Spring-Boot]: Create Spring-Boot
version of the Source Files addon (#4001)
* [incubator-kie-issues#2040] [Data Index Spring-Boot]: Create Spring Boot
version of the Source Files addon
* - fix
* - add it test
---
addons/common/pom.xml | 1 +
addons/common/source-files/pom.xml | 45 +++
.../source/files/BaseSourceFilesResource.java | 70 +++++
.../kie/kogito/addon/source/files/SourceFiles.java | 15 +-
kogito-bom/pom.xml | 22 ++
.../org/kie/kogito/codegen/api/AddonsConfig.java | 18 +-
.../codegen/api/utils/AddonsConfigDiscovery.java | 4 +
.../kie/kogito/codegen/api/AddonsConfigTest.java | 4 +
.../codegen/manager/util/CodeGenManagerUtil.java | 2 +
.../kie/kogito/codegen/process/ProcessCodegen.java | 22 ++
.../util/SourceFilesProviderProducerUtil.java | 106 +++++++
.../SourceFilesProviderProducerTemplate.java | 24 +-
.../codegen/process/ProcessGenerationUtils.java | 12 +-
.../util/SourceFilesProviderProducerUtilTest.java | 167 +++++++++++
quarkus/addons/source-files/deployment/pom.xml | 4 -
.../KogitoAddOnSourceFilesProcessor.java | 29 --
.../SourceFileCodegenBindListenerImpl.java | 64 ----
.../SourceFileProcessBindListenerImpl.java | 30 --
...urceFileServerlessWorkflowBindListenerImpl.java | 30 --
.../files/deployment/FakeSourceFilesRecorder.java | 42 ---
.../SourceFileCodegenBindListenerImplTest.java | 56 ----
quarkus/addons/source-files/runtime/pom.xml | 21 +-
.../addon/source/files/SourceFilesResource.java | 60 ++--
.../source/files/SourceFilesResourceTest.java | 11 +-
.../integration-tests-quarkus-usertasks/pom.xml | 2 +-
springboot/addons/pom.xml | 1 +
springboot/addons/source-files/pom.xml | 75 +++++
.../source/files/SourceFilesRestController.java | 81 ++++++
.../src/main/resources/META-INF/kogito.addon | 1 +
.../files/SourceFilesRestControllerTest.java | 26 +-
.../src/test/resources/petstore.sw.json | 31 ++
.../pom.xml | 5 +
.../{ => org/kie/kogito/examples}/cinema.bpmn | 0
.../{ => org/kie/kogito/examples}/timers.bpmn | 0
.../springboot/SourceFilesAddOnIT.java | 109 +++++++
.../src/test/resources/approval.bpmn | 323 +++++++++++++++++++++
36 files changed, 1165 insertions(+), 348 deletions(-)
diff --git a/addons/common/pom.xml b/addons/common/pom.xml
index fe7ccb1dcf..019b0c76ba 100644
--- a/addons/common/pom.xml
+++ b/addons/common/pom.xml
@@ -56,6 +56,7 @@
<module>marshallers</module>
<module>flyway</module>
<module>jbpm-usertask-storage-jpa</module>
+ <module>source-files</module>
</modules>
<dependencyManagement>
diff --git a/addons/common/source-files/pom.xml
b/addons/common/source-files/pom.xml
new file mode 100644
index 0000000000..c14a41f511
--- /dev/null
+++ b/addons/common/source-files/pom.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>kogito-addons-common-parent</artifactId>
+ <groupId>org.kie</groupId>
+ <version>999-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>kie-addons-source-files</artifactId>
+ <name>KIE :: Add-Ons :: Source Files :: Common</name>
+
+ <properties>
+
<java.module.name>org.kie.kogito.addon.source.files.common</java.module.name>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.kie.kogito</groupId>
+ <artifactId>kogito-services</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
diff --git
a/addons/common/source-files/src/main/java/org/kie/kogito/addon/source/files/BaseSourceFilesResource.java
b/addons/common/source-files/src/main/java/org/kie/kogito/addon/source/files/BaseSourceFilesResource.java
new file mode 100644
index 0000000000..9eda6705be
--- /dev/null
+++
b/addons/common/source-files/src/main/java/org/kie/kogito/addon/source/files/BaseSourceFilesResource.java
@@ -0,0 +1,70 @@
+/*
+ * 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.addon.source.files;
+
+import java.util.Collection;
+import java.util.Optional;
+
+import org.kie.kogito.source.files.SourceFile;
+import org.kie.kogito.source.files.SourceFilesProvider;
+
+import static java.nio.file.Path.of;
+
+public abstract class BaseSourceFilesResource<T> implements SourceFiles<T> {
+
+ private final SourceFilesProvider sourceFilesProvider;
+
+ public BaseSourceFilesResource(SourceFilesProvider sourceFilesProvider) {
+ this.sourceFilesProvider = sourceFilesProvider;
+ }
+
+ @Override
+ public T getSourceFileByUri(String uri) throws Exception {
+ Optional<SourceFile> sourceFile =
sourceFilesProvider.getSourceFilesByUri(uri);
+
+ if (sourceFile.isEmpty()) {
+ return buildNotFoundResponse();
+ }
+
+ return buildStreamResponse(sourceFile.get().readContents(),
of(sourceFile.get().getUri()).getFileName().toString());
+ }
+
+ @Override
+ public Collection<SourceFile> getSourceFilesByProcessId(String processId) {
+ return sourceFilesProvider.getProcessSourceFiles(processId);
+ }
+
+ @Override
+ public T getSourceFileByProcessId(String processId) throws Exception {
+ Optional<SourceFile> sourceFile =
sourceFilesProvider.getProcessSourceFile(processId);
+
+ if (sourceFile.isEmpty()) {
+ return buildNotFoundResponse();
+ }
+
+ return buildPlainResponse(sourceFile.get().readContents());
+ }
+
+ protected abstract T buildPlainResponse(byte[] content);
+
+ protected abstract T buildStreamResponse(byte[] content, String fileName);
+
+ protected abstract T buildNotFoundResponse();
+}
diff --git
a/quarkus/addons/source-files/runtime/src/main/java/org/kie/kogito/addon/source/files/SourceFilesRecorder.java
b/addons/common/source-files/src/main/java/org/kie/kogito/addon/source/files/SourceFiles.java
similarity index 71%
rename from
quarkus/addons/source-files/runtime/src/main/java/org/kie/kogito/addon/source/files/SourceFilesRecorder.java
rename to
addons/common/source-files/src/main/java/org/kie/kogito/addon/source/files/SourceFiles.java
index 44c137a1e2..4b5e542f1e 100644
---
a/quarkus/addons/source-files/runtime/src/main/java/org/kie/kogito/addon/source/files/SourceFilesRecorder.java
+++
b/addons/common/source-files/src/main/java/org/kie/kogito/addon/source/files/SourceFiles.java
@@ -16,19 +16,18 @@
* specific language governing permissions and limitations
* under the License.
*/
+
package org.kie.kogito.addon.source.files;
+import java.util.Collection;
+
import org.kie.kogito.source.files.SourceFile;
-import org.kie.kogito.source.files.SourceFilesProviderImpl;
-import io.quarkus.runtime.annotations.Recorder;
+public interface SourceFiles<T> {
-import jakarta.enterprise.inject.spi.CDI;
+ T getSourceFileByUri(String uri) throws Exception;
-@Recorder
-public class SourceFilesRecorder {
+ Collection<SourceFile> getSourceFilesByProcessId(String processId);
- public void addSourceFile(String id, SourceFile sourceFile) {
-
CDI.current().select(SourceFilesProviderImpl.class).get().addSourceFile(id,
sourceFile);
- }
+ T getSourceFileByProcessId(String processId) throws Exception;
}
diff --git a/kogito-bom/pom.xml b/kogito-bom/pom.xml
index c2abfcae10..b74307f399 100755
--- a/kogito-bom/pom.xml
+++ b/kogito-bom/pom.xml
@@ -1260,6 +1260,17 @@
<classifier>sources</classifier>
</dependency>
+ <dependency>
+ <groupId>org.kie</groupId>
+ <artifactId>kie-addons-source-files</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.kie</groupId>
+ <artifactId>kie-addons-source-files</artifactId>
+ <version>${project.version}</version>
+ <classifier>sources</classifier>
+ </dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-addons-quarkus-source-files</artifactId>
@@ -1282,6 +1293,17 @@
<version>${project.version}</version>
<classifier>sources</classifier>
</dependency>
+ <dependency>
+ <groupId>org.kie</groupId>
+ <artifactId>kie-addons-springboot-source-files</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.kie</groupId>
+ <artifactId>kie-addons-springboot-source-files</artifactId>
+ <version>${project.version}</version>
+ <classifier>sources</classifier>
+ </dependency>
<dependency>
<groupId>org.kie</groupId>
diff --git
a/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/AddonsConfig.java
b/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/AddonsConfig.java
index 12bd38e583..98fa0872fd 100644
---
a/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/AddonsConfig.java
+++
b/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/AddonsConfig.java
@@ -39,9 +39,10 @@ public class AddonsConfig {
private final boolean useProcessSVG;
private final boolean useEventDrivenDecisions;
private final boolean useEventDrivenRules;
+ private final boolean useSourceFiles;
private AddonsConfig(boolean usePersistence, boolean useTracing, boolean
useMonitoring, boolean usePrometheusMonitoring, boolean useCloudEvents,
- boolean useExplainability, boolean useProcessSVG, boolean
useEventDrivenDecisions, boolean useEventDrivenRules) {
+ boolean useExplainability, boolean useProcessSVG, boolean
useEventDrivenDecisions, boolean useEventDrivenRules, boolean useSourceFiles) {
this.usePersistence = usePersistence;
this.useTracing = useTracing;
this.useMonitoring = useMonitoring;
@@ -51,6 +52,7 @@ public class AddonsConfig {
this.useProcessSVG = useProcessSVG;
this.useEventDrivenDecisions = useEventDrivenDecisions;
this.useEventDrivenRules = useEventDrivenRules;
+ this.useSourceFiles = useSourceFiles;
}
public static AddonsConfigBuilder builder() {
@@ -93,6 +95,10 @@ public class AddonsConfig {
return useEventDrivenRules;
}
+ public boolean useSourceFiles() {
+ return useSourceFiles;
+ }
+
@Override
public String toString() {
return "AddonsConfig{" +
@@ -105,6 +111,7 @@ public class AddonsConfig {
", useProcessSVG=" + useProcessSVG +
", useEventDrivenDecisions=" + useEventDrivenDecisions +
", useEventDrivenRules=" + useEventDrivenRules +
+ ", useProcessSources=" + useSourceFiles +
'}';
}
@@ -119,6 +126,7 @@ public class AddonsConfig {
private boolean useProcessSVG;
private boolean useEventDrivenDecisions;
private boolean useEventDrivenRules;
+ private boolean useSourceFiles;
private AddonsConfigBuilder() {
}
@@ -168,8 +176,14 @@ public class AddonsConfig {
return this;
}
+ public AddonsConfigBuilder withSourceFiles(boolean useSourceFiles) {
+ this.useSourceFiles = useSourceFiles;
+ return this;
+ }
+
public AddonsConfig build() {
- return new AddonsConfig(usePersistence, useTracing, useMonitoring,
usePrometheusMonitoring, useCloudEvents, useExplainability, useProcessSVG,
useEventDrivenDecisions, useEventDrivenRules);
+ return new AddonsConfig(usePersistence, useTracing, useMonitoring,
usePrometheusMonitoring, useCloudEvents, useExplainability, useProcessSVG,
useEventDrivenDecisions, useEventDrivenRules,
+ useSourceFiles);
}
}
}
diff --git
a/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/utils/AddonsConfigDiscovery.java
b/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/utils/AddonsConfigDiscovery.java
index 6e3e9ec0cf..ae0bc3227e 100644
---
a/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/utils/AddonsConfigDiscovery.java
+++
b/kogito-codegen-modules/kogito-codegen-api/src/main/java/org/kie/kogito/codegen/api/utils/AddonsConfigDiscovery.java
@@ -42,6 +42,8 @@ public class AddonsConfigDiscovery {
private static final String SPRING_PROCESS_SVG =
"org.kie.kogito.svg.service.SpringBootProcessSvgService";
private static final String EVENT_DRIVEN_DECISIONS_CLASS =
"org.kie.kogito.eventdriven.decision.EventDrivenDecisionController";
private static final String EVENT_DRIVEN_RULES_CLASS =
"org.kie.kogito.eventdriven.rules.EventDrivenRulesController";
+ private static final String QUARKUS_SOURCE_FILES_CLASS =
"org.kie.kogito.addon.source.files.SourceFilesResource";
+ private static final String SPRING_SOURCE_FILES_CLASS =
"org.kie.kogito.addon.source.files.SourceFilesRestController";
private static final Logger LOGGER =
LoggerFactory.getLogger(AddonsConfigDiscovery.class);
@@ -63,6 +65,7 @@ public class AddonsConfigDiscovery {
boolean useProcessSVG =
classAvailabilityResolver.test(QUARKUS_PROCESS_SVG) ||
classAvailabilityResolver.test(SPRING_PROCESS_SVG);
boolean useEventDrivenDecisions =
classAvailabilityResolver.test(EVENT_DRIVEN_DECISIONS_CLASS);
boolean useEventDrivenRules =
classAvailabilityResolver.test(EVENT_DRIVEN_RULES_CLASS);
+ boolean useSourceFiles =
classAvailabilityResolver.test(QUARKUS_SOURCE_FILES_CLASS) ||
classAvailabilityResolver.test(SPRING_SOURCE_FILES_CLASS);
AddonsConfig addonsConfig = AddonsConfig.builder()
.withPersistence(usePersistence)
@@ -74,6 +77,7 @@ public class AddonsConfigDiscovery {
.withProcessSVG(useProcessSVG)
.withEventDrivenDecisions(useEventDrivenDecisions)
.withEventDrivenRules(useEventDrivenRules)
+ .withSourceFiles(useSourceFiles)
.build();
LOGGER.info("Performed addonsConfig discovery, found: {}",
addonsConfig);
diff --git
a/kogito-codegen-modules/kogito-codegen-api/src/test/java/org/kie/kogito/codegen/api/AddonsConfigTest.java
b/kogito-codegen-modules/kogito-codegen-api/src/test/java/org/kie/kogito/codegen/api/AddonsConfigTest.java
index cc6337a11b..e019d8a849 100644
---
a/kogito-codegen-modules/kogito-codegen-api/src/test/java/org/kie/kogito/codegen/api/AddonsConfigTest.java
+++
b/kogito-codegen-modules/kogito-codegen-api/src/test/java/org/kie/kogito/codegen/api/AddonsConfigTest.java
@@ -36,6 +36,7 @@ public class AddonsConfigTest {
assertThat(addonsConfig.usePersistence()).isFalse();
assertThat(addonsConfig.useCloudEvents()).isFalse();
assertThat(addonsConfig.useProcessSVG()).isFalse();
+ assertThat(addonsConfig.useSourceFiles()).isFalse();
}
@Test
@@ -61,5 +62,8 @@ public class AddonsConfigTest {
assertThat(DEFAULT.useProcessSVG()).isFalse();
assertThat(builder().withProcessSVG(true).build().useProcessSVG()).isTrue();
+
+ assertThat(DEFAULT.useSourceFiles()).isFalse();
+
assertThat(builder().withSourceFiles(true).build().useSourceFiles()).isTrue();
}
}
diff --git
a/kogito-codegen-modules/kogito-codegen-manager/src/main/java/org/kie/kogito/codegen/manager/util/CodeGenManagerUtil.java
b/kogito-codegen-modules/kogito-codegen-manager/src/main/java/org/kie/kogito/codegen/manager/util/CodeGenManagerUtil.java
index ced206c650..9fac05c91b 100644
---
a/kogito-codegen-modules/kogito-codegen-manager/src/main/java/org/kie/kogito/codegen/manager/util/CodeGenManagerUtil.java
+++
b/kogito-codegen-modules/kogito-codegen-manager/src/main/java/org/kie/kogito/codegen/manager/util/CodeGenManagerUtil.java
@@ -36,6 +36,7 @@ import org.drools.codegen.common.DroolsModelBuildContext;
import org.drools.model.codegen.project.RuleCodegen;
import org.kie.kogito.KogitoGAV;
import org.kie.kogito.codegen.api.Generator;
+import org.kie.kogito.codegen.api.SourceFileCodegenBindNotifier;
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;
@@ -82,6 +83,7 @@ public class CodeGenManagerUtil {
.withClassLoader(projectClassLoader)
.withAppPaths(appPaths)
.withGAV(kogitoGAV)
+ .withSourceFileProcessBindNotifier(new
SourceFileCodegenBindNotifier())
.build();
additionalProperties(context, projectParameters);
diff --git
a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java
index c6f55b8fc7..ee8b0c7509 100644
---
a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java
+++
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java
@@ -68,6 +68,7 @@ import org.xml.sax.SAXException;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import static com.github.javaparser.StaticJavaParser.parse;
import static java.lang.String.format;
import static java.util.stream.Collectors.toList;
import static
org.jbpm.process.core.constants.CalendarConstants.BUSINESS_CALENDAR_PATH;
@@ -75,6 +76,7 @@ import static
org.kie.kogito.codegen.process.util.BusinessCalendarUtil.condition
import static
org.kie.kogito.codegen.process.util.CodegenUtil.generatorProperty;
import static
org.kie.kogito.codegen.process.util.CodegenUtil.isFaultToleranceEnabled;
import static
org.kie.kogito.codegen.process.util.CodegenUtil.isTransactionEnabled;
+import static
org.kie.kogito.codegen.process.util.SourceFilesProviderProducerUtil.addSourceFilesToProvider;
import static
org.kie.kogito.grafana.GrafanaConfigurationWriter.buildDashboardName;
import static
org.kie.kogito.grafana.GrafanaConfigurationWriter.generateOperationalDashboard;
import static org.kie.kogito.internal.utils.ConversionUtils.sanitizeClassName;
@@ -100,6 +102,8 @@ public class ProcessCodegen extends AbstractGenerator {
private static final String GLOBAL_OPERATIONAL_DASHBOARD_TEMPLATE =
"/grafana-dashboard-template/processes/global-operational-dashboard-template.json";
private static final String PROCESS_OPERATIONAL_DASHBOARD_TEMPLATE =
"/grafana-dashboard-template/processes/process-operational-dashboard-template.json";
public static final String BUSINESS_CALENDAR_PRODUCER_TEMPLATE =
"BusinessCalendarProducer";
+ public static final String SOURCE_FILE_PROVIDER_PRODUCER =
"SourceFilesProviderProducer";
+
private static final String IS_BUSINESS_CALENDAR_PRESENT =
"isBusinessCalendarPresent";
static {
@@ -455,6 +459,8 @@ public class ProcessCodegen extends AbstractGenerator {
generateBusinessCalendarProducer();
+ generateSourceFileProviderProducer();
+
if (CodegenUtil.isTransactionEnabled(this, context()) &&
!isServerless) {
String template = "ExceptionHandlerTransaction";
TemplatedGenerator generator = TemplatedGenerator.builder()
@@ -601,4 +607,20 @@ public class ProcessCodegen extends AbstractGenerator {
storeFile(PRODUCER_TYPE, generator.generatedFilePath(),
compilationUnit.toString());
}
+
+ private void generateSourceFileProviderProducer() {
+
+ if (!context().getAddonsConfig().useSourceFiles()) {
+ return;
+ }
+
+ CompilationUnit compilationUnit =
parse(this.getClass().getResourceAsStream("/class-templates/producer/" +
SOURCE_FILE_PROVIDER_PRODUCER + "Template.java"));
+ compilationUnit.setPackageDeclaration(context().getPackageName());
+
+ addSourceFilesToProvider(compilationUnit, processes, context());
+
+ String generatedPath = context().getPackageName().replace(".", "/") +
"/" + SOURCE_FILE_PROVIDER_PRODUCER + ".java";
+
+ storeFile(PRODUCER_TYPE, generatedPath, compilationUnit.toString());
+ }
}
diff --git
a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/util/SourceFilesProviderProducerUtil.java
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/util/SourceFilesProviderProducerUtil.java
new file mode 100644
index 0000000000..5da214b251
--- /dev/null
+++
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/util/SourceFilesProviderProducerUtil.java
@@ -0,0 +1,106 @@
+/*
+ * 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.process.util;
+
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Map;
+
+import org.kie.api.io.Resource;
+import org.kie.kogito.codegen.api.context.KogitoBuildContext;
+import org.kie.kogito.codegen.process.ProcessCodegenException;
+import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcess;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.InitializerDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.Statement;
+
+public class SourceFilesProviderProducerUtil {
+
+ private SourceFilesProviderProducerUtil() {
+ // utility class, shouldn't be initialized
+ }
+
+ public static void addSourceFilesToProvider(CompilationUnit
compilationUnit, Map<String, KogitoWorkflowProcess> workflows,
KogitoBuildContext context) {
+
+ ClassOrInterfaceDeclaration producerClass =
compilationUnit.findFirst(ClassOrInterfaceDeclaration.class)
+ .orElseThrow(() -> new
ProcessCodegenException("SourceFileProviderProducerTemplate does not contain a
class declaration"));
+
+
context.getDependencyInjectionAnnotator().withFactoryClass(producerClass);
+
+ MethodDeclaration producerMethod =
producerClass.getMethodsByName("getSourceFilesProvider")
+ .iterator()
+ .next();
+
+
context.getDependencyInjectionAnnotator().withFactoryMethod(producerMethod);
+
+ InitializerDeclaration staticInitDeclaration =
producerClass.findFirst(InitializerDeclaration.class)
+ .stream()
+ .filter(InitializerDeclaration::isStatic)
+ .findFirst()
+ .orElseThrow(() -> new
ProcessCodegenException("SourceFileProviderProducerTemplate does not contain a
class declaration"));
+
+ if (workflows.isEmpty()) {
+ producerClass.remove(staticInitDeclaration);
+ } else {
+ registerWorkflows(staticInitDeclaration, workflows, context);
+ }
+ }
+
+ private static void registerWorkflows(InitializerDeclaration staticInit,
Map<String, KogitoWorkflowProcess> workflows, KogitoBuildContext context) {
+
+ BlockStmt initBody = staticInit.getBody();
+
+ Statement statementTemplate = initBody.getStatement(0);
+
+ initBody.remove(statementTemplate);
+
+ workflows.forEach((id, workflowProcess) -> {
+ Statement newProcessSourceStatement = statementTemplate.clone();
+ String resourcePath = getResourceRelativePath(context,
workflowProcess.getResource());
+ newProcessSourceStatement.findAll(StringLiteralExpr.class)
+ .forEach(stringLiteralExpr ->
interpolateStrings(stringLiteralExpr, id, resourcePath));
+ initBody.addStatement(newProcessSourceStatement);
+ });
+ }
+
+ private static void interpolateStrings(StringLiteralExpr stringLiteral,
String id, String resourcePath) {
+ String stringValue = stringLiteral.getValue();
+ String interpolated = stringValue.replace("$processId$", id);
+ interpolated = interpolated.replace("$sourcePath$", resourcePath);
+ stringLiteral.setString(interpolated);
+ }
+
+ static String getResourceRelativePath(KogitoBuildContext context, Resource
resource) {
+ String resourcePath = resource.getSourcePath();
+
+ Path sourceFilePath = Path.of(resourcePath);
+
+ return Arrays.stream(context.getAppPaths().getResourcePaths())
+ .filter(sourceFilePath::startsWith)
+ .findFirst()
+ .map(appPath -> appPath.relativize(sourceFilePath).toString())
+ .orElse(resourcePath);
+ }
+}
diff --git
a/quarkus/addons/source-files/runtime/src/main/java/org/kie/kogito/addon/source/files/SourceFilesProviderProducer.java
b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/SourceFilesProviderProducerTemplate.java
similarity index 66%
rename from
quarkus/addons/source-files/runtime/src/main/java/org/kie/kogito/addon/source/files/SourceFilesProviderProducer.java
rename to
kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/SourceFilesProviderProducerTemplate.java
index 19ab1f0ebe..8f4609ea8a 100644
---
a/quarkus/addons/source-files/runtime/src/main/java/org/kie/kogito/addon/source/files/SourceFilesProviderProducer.java
+++
b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/producer/SourceFilesProviderProducerTemplate.java
@@ -16,24 +16,22 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.kie.kogito.addon.source.files;
+package $Package$;
+
+import org.kie.kogito.source.files.SourceFile;
+import org.kie.kogito.source.files.SourceFilesProvider;
import org.kie.kogito.source.files.SourceFilesProviderImpl;
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.enterprise.inject.Default;
-import jakarta.enterprise.inject.Produces;
+public class SourceFilesProviderProducer {
-@ApplicationScoped
-public final class SourceFilesProviderProducer {
+ private static final SourceFilesProviderImpl INSTANCE = new
SourceFilesProviderImpl();
- SourceFilesProviderProducer() {
+ static {
+ INSTANCE.addSourceFile("$processId$", new SourceFile("$sourcePath$"));
}
- @Produces
- @Default
- @ApplicationScoped
- public SourceFilesProviderImpl sourceFilesProvider() {
- return new SourceFilesProviderImpl();
+ public SourceFilesProvider getSourceFilesProvider() {
+ return INSTANCE;
}
-}
+}
\ No newline at end of file
diff --git
a/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/ProcessGenerationUtils.java
b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/ProcessGenerationUtils.java
index 3dc9c88943..a350f3434d 100644
---
a/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/ProcessGenerationUtils.java
+++
b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/ProcessGenerationUtils.java
@@ -56,15 +56,21 @@ public class ProcessGenerationUtils {
return processExecutableModelGenerators;
}
- private static List<Process> parseProcesses(Collection<File> processFiles)
{
+ public static List<Process> parseProcesses(Collection<File> processFiles) {
List<Process> processes = new ArrayList<>();
for (File processSourceFile : processFiles) {
try {
FileSystemResource r = new
FileSystemResource(processSourceFile);
if
(SupportedExtensions.getBPMNExtensions().stream().anyMatch(processSourceFile.getPath()::endsWith))
{
- processes.addAll(ProcessCodegen.parseProcessFile(r));
+ ProcessCodegen.parseProcessFile(r)
+ .forEach(process -> {
+ process.setResource(r);
+ processes.add(process);
+ });
} else if
(SupportedExtensions.getSWFExtensions().stream().anyMatch(processSourceFile.getPath()::endsWith))
{
- processes.add(ProcessCodegen.parseWorkflowFile(r,
JavaKogitoBuildContext.builder().build()).info());
+ KogitoWorkflowProcess swfWorkflow =
ProcessCodegen.parseWorkflowFile(r,
JavaKogitoBuildContext.builder().build()).info();
+ swfWorkflow.setResource(r);
+ processes.add(swfWorkflow);
}
if (processes.isEmpty()) {
throw new IllegalArgumentException("Unable to process file
with unsupported extension: " + processSourceFile);
diff --git
a/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/util/SourceFilesProviderProducerUtilTest.java
b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/util/SourceFilesProviderProducerUtilTest.java
new file mode 100644
index 0000000000..af19119fcb
--- /dev/null
+++
b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/util/SourceFilesProviderProducerUtilTest.java
@@ -0,0 +1,167 @@
+/*
+ * 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.process.util;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import org.drools.codegen.common.AppPaths;
+import org.drools.compiler.kie.builder.impl.KieBuilderSetImpl;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.kie.api.definition.process.Process;
+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.internal.process.runtime.KogitoWorkflowProcess;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.InitializerDeclaration;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.ObjectCreationExpr;
+import com.github.javaparser.ast.stmt.BlockStmt;
+
+import static com.github.javaparser.StaticJavaParser.parse;
+import static org.assertj.core.api.Assertions.assertThat;
+import static
org.kie.kogito.codegen.process.ProcessCodegen.SOURCE_FILE_PROVIDER_PRODUCER;
+import static
org.kie.kogito.codegen.process.ProcessGenerationUtils.parseProcesses;
+import static
org.kie.kogito.codegen.process.util.SourceFilesProviderProducerUtil.addSourceFilesToProvider;
+import static
org.kie.kogito.codegen.process.util.SourceFilesProviderProducerUtil.getResourceRelativePath;
+
+public class SourceFilesProviderProducerUtilTest {
+ private static final String WORKFLOW_RELATIVE_PATH =
"org/kie/kogito/process.bpmn";
+
+ private AppPaths appPaths;
+ private KogitoBuildContext context;
+
+ @BeforeEach
+ public void setup() {
+ this.appPaths = AppPaths.fromTestDir(new
File("").getAbsoluteFile().toPath());
+ this.context = QuarkusKogitoBuildContext.builder()
+ .withAppPaths(appPaths)
+ .withSourceFileProcessBindNotifier(new
SourceFileCodegenBindNotifier())
+ .build();
+ }
+
+ @Test
+ public void testGetResourceRelativePathWithResourceWithRelativePath() {
+ String calculatedRelativePath = getResourceRelativePath(context, new
KieBuilderSetImpl.DummyResource(WORKFLOW_RELATIVE_PATH));
+ assertThat(calculatedRelativePath).isEqualTo(WORKFLOW_RELATIVE_PATH);
+ }
+
+ @Test
+ public void testGetResourceRelativePath() {
+ for (Path appResourcePath : appPaths.getResourcePaths()) {
+ String fullWorkflowPath =
appResourcePath.resolve(WORKFLOW_RELATIVE_PATH).toString();
+ String calculatedRelativePath = getResourceRelativePath(context,
new KieBuilderSetImpl.DummyResource(fullWorkflowPath));
+
assertThat(calculatedRelativePath).isEqualTo(WORKFLOW_RELATIVE_PATH);
+ }
+ }
+
+ @Test
+ public void testAddSourceFilesToProvider() {
+ // Loading Process from test resources
+ final Path testResourcesPath =
Paths.get("src/test/resources/usertask").toAbsolutePath();
+ File[] testProcessFiles =
testResourcesPath.toFile().listFiles(pathname ->
pathname.getName().endsWith(".bpmn2"));
+ List<Process> testProcesses =
parseProcesses(List.of(testProcessFiles));
+
+ Map<String, KogitoWorkflowProcess> workflows = testProcesses.stream()
+ .collect(Collectors.toMap(Process::getId,
KogitoWorkflowProcess.class::cast));
+
+ CompilationUnit compilationUnit = getCompilationUnit();
+
+ addSourceFilesToProvider(compilationUnit, workflows, context);
+
+ ClassOrInterfaceDeclaration producerClass =
compilationUnit.findFirst(ClassOrInterfaceDeclaration.class).orElseThrow();
+
+ InitializerDeclaration staticInit =
producerClass.findFirst(InitializerDeclaration.class)
+ .filter(InitializerDeclaration::isStatic)
+ .stream()
+ .findFirst()
+ .orElseThrow();
+
+ BlockStmt staticInitBody = staticInit.getBody();
+
+ assertThat(staticInitBody.getStatements())
+ .hasSize(2);
+
+ List<MethodCallExpr> initStatements =
staticInitBody.findAll(MethodCallExpr.class);
+
+ assertThat(initStatements)
+ .hasSize(2);
+
+ initStatements.forEach(initStatement -> {
+ assertThat(initStatement.getScope())
+ .isPresent()
+ .get()
+ .extracting(Node::toString)
+ .isEqualTo("INSTANCE");
+
+ assertThat(initStatement.getNameAsString())
+ .isEqualTo("addSourceFile");
+
+ assertThat(initStatement.getArguments())
+ .hasSize(2);
+
+ String workflowId =
initStatement.getArguments().get(0).asStringLiteralExpr().asString();
+
+ KogitoWorkflowProcess kogitoWorkflow = workflows.get(workflowId);
+
+ assertThat(kogitoWorkflow)
+ .isNotNull();
+
+ ObjectCreationExpr sourceCreationExpr =
initStatement.getArguments().get(1).asObjectCreationExpr();
+
+ assertThat(sourceCreationExpr.getType().toString())
+ .isEqualTo("SourceFile");
+
+ String expectedResourceRelativePath =
getResourceRelativePath(context, kogitoWorkflow.getResource());
+
+ assertThat(sourceCreationExpr.getArguments())
+ .hasSize(1)
+ .extracting(argumentExpr ->
argumentExpr.asStringLiteralExpr().asString())
+ .contains(expectedResourceRelativePath);
+ });
+ }
+
+ @Test
+ public void testAddSourceFilesToProviderWithEmptyWorkflows() {
+ CompilationUnit compilationUnit = getCompilationUnit();
+
+ addSourceFilesToProvider(compilationUnit, Map.of(), context);
+
+ ClassOrInterfaceDeclaration producerClass =
compilationUnit.findFirst(ClassOrInterfaceDeclaration.class).orElseThrow();
+
+ Optional<InitializerDeclaration> staticInit =
producerClass.findFirst(InitializerDeclaration.class)
+ .filter(InitializerDeclaration::isStatic)
+ .stream().findFirst();
+
+ assertThat(staticInit).isEmpty();
+ }
+
+ CompilationUnit getCompilationUnit() {
+ return
parse(this.getClass().getResourceAsStream("/class-templates/producer/" +
SOURCE_FILE_PROVIDER_PRODUCER + "Template.java"));
+ }
+}
diff --git a/quarkus/addons/source-files/deployment/pom.xml
b/quarkus/addons/source-files/deployment/pom.xml
index f0e82f8cf8..a1cd1b2be9 100644
--- a/quarkus/addons/source-files/deployment/pom.xml
+++ b/quarkus/addons/source-files/deployment/pom.xml
@@ -44,10 +44,6 @@
<groupId>org.kie</groupId>
<artifactId>kogito-addons-quarkus-common-deployment</artifactId>
</dependency>
- <dependency>
- <groupId>org.kie.kogito</groupId>
- <artifactId>kogito-codegen-processes</artifactId>
- </dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc-deployment</artifactId>
diff --git
a/quarkus/addons/source-files/deployment/src/main/java/org/kie/kogito/addon/source/files/deployment/KogitoAddOnSourceFilesProcessor.java
b/quarkus/addons/source-files/deployment/src/main/java/org/kie/kogito/addon/source/files/deployment/KogitoAddOnSourceFilesProcessor.java
index 8ab5587f56..24cbcef653 100644
---
a/quarkus/addons/source-files/deployment/src/main/java/org/kie/kogito/addon/source/files/deployment/KogitoAddOnSourceFilesProcessor.java
+++
b/quarkus/addons/source-files/deployment/src/main/java/org/kie/kogito/addon/source/files/deployment/KogitoAddOnSourceFilesProcessor.java
@@ -26,18 +26,12 @@ import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
-import org.kie.kogito.addon.source.files.SourceFilesProviderProducer;
-import org.kie.kogito.addon.source.files.SourceFilesRecorder;
-import org.kie.kogito.codegen.api.context.KogitoBuildContext;
import org.kie.kogito.internal.SupportedExtensions;
import org.kie.kogito.quarkus.addons.common.deployment.KogitoCapability;
import
org.kie.kogito.quarkus.addons.common.deployment.OneOfCapabilityKogitoAddOnProcessor;
import org.kie.kogito.quarkus.common.deployment.KogitoBuildContextBuildItem;
-import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.deployment.annotations.BuildStep;
-import io.quarkus.deployment.annotations.ExecutionTime;
-import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.FeatureBuildItem;
import
io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
@@ -54,29 +48,6 @@ class KogitoAddOnSourceFilesProcessor extends
OneOfCapabilityKogitoAddOnProcesso
return new FeatureBuildItem(FEATURE);
}
- @BuildStep
- AdditionalBeanBuildItem sourceFilesProviderProducer() {
- return new AdditionalBeanBuildItem(SourceFilesProviderProducer.class);
- }
-
- @BuildStep
- @Record(ExecutionTime.RUNTIME_INIT)
- void addSourceFileProcessBindListener(KogitoBuildContextBuildItem
ctxBuildItem,
- SourceFilesRecorder sourceFilesRecorder) {
- KogitoBuildContext kogitoBuildContext =
ctxBuildItem.getKogitoBuildContext();
-
- SourceFileProcessBindListenerImpl processListener = new
SourceFileProcessBindListenerImpl(
- kogitoBuildContext.getAppPaths().getResourceFiles(),
- sourceFilesRecorder);
-
- SourceFileServerlessWorkflowBindListenerImpl
serverlessWorkflowListener = new SourceFileServerlessWorkflowBindListenerImpl(
- kogitoBuildContext.getAppPaths().getResourceFiles(),
- sourceFilesRecorder);
-
- kogitoBuildContext.getSourceFileCodegenBindNotifier()
- .ifPresent(notifier -> notifier.addListeners(processListener,
serverlessWorkflowListener));
- }
-
@BuildStep
NativeImageResourceBuildItem
nativeImageResourceBuildItem(KogitoBuildContextBuildItem ctxBuildItem) throws
IOException {
return new
NativeImageResourceBuildItem(getSourceFiles(ctxBuildItem.getKogitoBuildContext().getAppPaths().getResourceFiles()));
diff --git
a/quarkus/addons/source-files/deployment/src/main/java/org/kie/kogito/addon/source/files/deployment/SourceFileCodegenBindListenerImpl.java
b/quarkus/addons/source-files/deployment/src/main/java/org/kie/kogito/addon/source/files/deployment/SourceFileCodegenBindListenerImpl.java
deleted file mode 100644
index 280b1f580e..0000000000
---
a/quarkus/addons/source-files/deployment/src/main/java/org/kie/kogito/addon/source/files/deployment/SourceFileCodegenBindListenerImpl.java
+++ /dev/null
@@ -1,64 +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.addon.source.files.deployment;
-
-import java.io.File;
-import java.nio.file.Path;
-import java.util.Arrays;
-
-import org.kie.kogito.addon.source.files.SourceFilesRecorder;
-import org.kie.kogito.codegen.api.SourceFileCodegenBindEvent;
-import org.kie.kogito.codegen.api.SourceFileCodegenBindListener;
-import org.kie.kogito.source.files.SourceFile;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-abstract class SourceFileCodegenBindListenerImpl implements
SourceFileCodegenBindListener {
-
- private static final Logger LOGGER =
LoggerFactory.getLogger(SourceFileCodegenBindListenerImpl.class);
-
- private final File[] resourcePaths;
-
- private final SourceFilesRecorder sourceFilesRecorder;
-
- protected SourceFileCodegenBindListenerImpl(File[] resourcePaths,
SourceFilesRecorder sourceFilesRecorder) {
- this.resourcePaths = resourcePaths;
- this.sourceFilesRecorder = sourceFilesRecorder;
- }
-
- @Override
- public void onSourceFileCodegenBind(SourceFileCodegenBindEvent event) {
- LOGGER.debug("Received event {}", event);
-
- Path sourceFilePath = Path.of(event.getUri());
-
- Arrays.stream(resourcePaths)
- .map(File::toPath)
- .filter(sourceFilePath::startsWith)
- .findFirst()
- .ifPresentOrElse(resourcePath -> {
- SourceFile sourceFile = new
SourceFile(resolveSourceFilePath(sourceFilePath, resourcePath));
- sourceFilesRecorder.addSourceFile(event.getSourceFileId(),
sourceFile);
- }, () ->
sourceFilesRecorder.addSourceFile(event.getSourceFileId(), new
SourceFile(event.getUri())));
- }
-
- private String resolveSourceFilePath(Path sourceFilePath, Path
locationPath) {
- return sourceFilePath.subpath(locationPath.getNameCount(),
sourceFilePath.getNameCount()).toString();
- }
-}
diff --git
a/quarkus/addons/source-files/deployment/src/main/java/org/kie/kogito/addon/source/files/deployment/SourceFileProcessBindListenerImpl.java
b/quarkus/addons/source-files/deployment/src/main/java/org/kie/kogito/addon/source/files/deployment/SourceFileProcessBindListenerImpl.java
deleted file mode 100644
index 940155e468..0000000000
---
a/quarkus/addons/source-files/deployment/src/main/java/org/kie/kogito/addon/source/files/deployment/SourceFileProcessBindListenerImpl.java
+++ /dev/null
@@ -1,30 +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.addon.source.files.deployment;
-
-import java.io.File;
-
-import org.kie.kogito.addon.source.files.SourceFilesRecorder;
-
-final class SourceFileProcessBindListenerImpl extends
SourceFileCodegenBindListenerImpl {
-
- SourceFileProcessBindListenerImpl(File[] resourcePaths,
SourceFilesRecorder sourceFilesRecorder) {
- super(resourcePaths, sourceFilesRecorder);
- }
-}
diff --git
a/quarkus/addons/source-files/deployment/src/main/java/org/kie/kogito/addon/source/files/deployment/SourceFileServerlessWorkflowBindListenerImpl.java
b/quarkus/addons/source-files/deployment/src/main/java/org/kie/kogito/addon/source/files/deployment/SourceFileServerlessWorkflowBindListenerImpl.java
deleted file mode 100644
index 57de99a420..0000000000
---
a/quarkus/addons/source-files/deployment/src/main/java/org/kie/kogito/addon/source/files/deployment/SourceFileServerlessWorkflowBindListenerImpl.java
+++ /dev/null
@@ -1,30 +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.addon.source.files.deployment;
-
-import java.io.File;
-
-import org.kie.kogito.addon.source.files.SourceFilesRecorder;
-
-final class SourceFileServerlessWorkflowBindListenerImpl extends
SourceFileCodegenBindListenerImpl {
-
- SourceFileServerlessWorkflowBindListenerImpl(File[] resourcePaths,
SourceFilesRecorder sourceFilesRecorder) {
- super(resourcePaths, sourceFilesRecorder);
- }
-}
diff --git
a/quarkus/addons/source-files/deployment/src/test/java/org/kie/kogito/addon/source/files/deployment/FakeSourceFilesRecorder.java
b/quarkus/addons/source-files/deployment/src/test/java/org/kie/kogito/addon/source/files/deployment/FakeSourceFilesRecorder.java
deleted file mode 100644
index 454f5c837d..0000000000
---
a/quarkus/addons/source-files/deployment/src/test/java/org/kie/kogito/addon/source/files/deployment/FakeSourceFilesRecorder.java
+++ /dev/null
@@ -1,42 +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.addon.source.files.deployment;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.kie.kogito.addon.source.files.SourceFilesRecorder;
-import org.kie.kogito.source.files.SourceFile;
-
-final class FakeSourceFilesRecorder extends SourceFilesRecorder {
-
- private final Map<String, Collection<SourceFile>> files = new HashMap<>();
-
- @Override
- public void addSourceFile(String id, SourceFile sourceFile) {
- files.computeIfAbsent(id, k -> new ArrayList<>()).add(sourceFile);
- }
-
- boolean containsRecordFor(String processId, SourceFile sourceFile) {
- return files.getOrDefault(processId, List.of()).contains(sourceFile);
- }
-}
diff --git
a/quarkus/addons/source-files/deployment/src/test/java/org/kie/kogito/addon/source/files/deployment/SourceFileCodegenBindListenerImplTest.java
b/quarkus/addons/source-files/deployment/src/test/java/org/kie/kogito/addon/source/files/deployment/SourceFileCodegenBindListenerImplTest.java
deleted file mode 100644
index fe3525efa9..0000000000
---
a/quarkus/addons/source-files/deployment/src/test/java/org/kie/kogito/addon/source/files/deployment/SourceFileCodegenBindListenerImplTest.java
+++ /dev/null
@@ -1,56 +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.addon.source.files.deployment;
-
-import java.io.File;
-import java.util.stream.Stream;
-
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.Arguments;
-import org.junit.jupiter.params.provider.MethodSource;
-import org.kie.kogito.codegen.api.SourceFileCodegenBindEvent;
-import org.kie.kogito.source.files.SourceFile;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-class SourceFileCodegenBindListenerImplTest {
-
- public static Stream<Arguments> testOnSourceFileProcessBindEventSources() {
- return Stream.of(
-
Arguments.arguments("/dev/proj/other_resources/org/acme/process/a_process.bpmn",
"org/acme/process/a_process.bpmn"),
- Arguments.arguments("file://restcountries.json",
"file://restcountries.json"),
- Arguments.arguments("/a/random/directory/a_process.bpmn",
"/a/random/directory/a_process.bpmn"));
- }
-
- @ParameterizedTest
- @MethodSource("testOnSourceFileProcessBindEventSources")
- void testOnSourceFileProcessBindEvent(String eventSourceFile, String
expectedSourceFile) {
- File[] resourcePaths = new File[] { new File("/dev/proj/resources/"),
new File("/dev/proj/other_resources/") };
-
- String processId = "a_process";
-
- SourceFileCodegenBindEvent event = new
SourceFileCodegenBindEvent(processId, eventSourceFile);
-
- FakeSourceFilesRecorder sourceFilesRecorder = new
FakeSourceFilesRecorder();
-
- new SourceFileProcessBindListenerImpl(resourcePaths,
sourceFilesRecorder).onSourceFileCodegenBind(event);
-
- assertThat(sourceFilesRecorder.containsRecordFor(processId, new
SourceFile(expectedSourceFile))).isTrue();
- }
-}
diff --git a/quarkus/addons/source-files/runtime/pom.xml
b/quarkus/addons/source-files/runtime/pom.xml
index 09c8542d34..fa8a1dce14 100644
--- a/quarkus/addons/source-files/runtime/pom.xml
+++ b/quarkus/addons/source-files/runtime/pom.xml
@@ -54,18 +54,10 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
</dependency>
- <dependency>
- <groupId>org.kie.kogito</groupId>
- <artifactId>kogito-services</artifactId>
- </dependency>
- <dependency>
- <groupId>org.kie.kogito</groupId>
- <artifactId>kogito-codegen-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.kie.kogito</groupId>
- <artifactId>kogito-codegen-core</artifactId>
- </dependency>
+ <dependency>
+ <groupId>org.kie</groupId>
+ <artifactId>kie-addons-source-files</artifactId>
+ </dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-addons-quarkus-rest-exception-handler</artifactId>
@@ -117,6 +109,11 @@
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-junit-jupiter</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
diff --git
a/quarkus/addons/source-files/runtime/src/main/java/org/kie/kogito/addon/source/files/SourceFilesResource.java
b/quarkus/addons/source-files/runtime/src/main/java/org/kie/kogito/addon/source/files/SourceFilesResource.java
index 29ca134938..53e39701f9 100644
---
a/quarkus/addons/source-files/runtime/src/main/java/org/kie/kogito/addon/source/files/SourceFilesResource.java
+++
b/quarkus/addons/source-files/runtime/src/main/java/org/kie/kogito/addon/source/files/SourceFilesResource.java
@@ -19,70 +19,64 @@
package org.kie.kogito.addon.source.files;
import java.io.ByteArrayInputStream;
-import java.io.InputStream;
import java.util.Collection;
-import java.util.Optional;
import org.kie.kogito.source.files.SourceFile;
import org.kie.kogito.source.files.SourceFilesProvider;
-import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.PathParam;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
-@ApplicationScoped
@Path("/management/processes/")
-public final class SourceFilesResource {
+public class SourceFilesResource extends BaseSourceFilesResource<Response> {
- SourceFilesProvider sourceFilesProvider;
+ public SourceFilesResource() {
+ this(null);
+ // CDI
+ }
+
+ @Inject
+ public SourceFilesResource(SourceFilesProvider sourceFilesProvider) {
+ super(sourceFilesProvider);
+ }
@GET
@Path("sources")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getSourceFileByUri(@QueryParam("uri") String uri) throws
Exception {
- Optional<SourceFile> sourceFile =
sourceFilesProvider.getSourceFilesByUri(uri);
-
- if (sourceFile.isEmpty()) {
- return Response.status(Response.Status.NOT_FOUND).build();
- }
-
- try (InputStream file = new
ByteArrayInputStream(sourceFile.get().readContents())) {
- return Response.ok(file, MediaType.APPLICATION_OCTET_STREAM)
- .header("Content-Disposition", "inline; filename=\"" +
java.nio.file.Path.of(sourceFile.get().getUri()).getFileName() + "\"")
- .build();
- }
-
+ return super.getSourceFileByUri(uri);
}
@GET
@Path("{processId}/sources")
@Produces(MediaType.APPLICATION_JSON)
public Collection<SourceFile>
getSourceFilesByProcessId(@PathParam("processId") String processId) {
- return sourceFilesProvider.getProcessSourceFiles(processId);
+ return super.getSourceFilesByProcessId(processId);
}
@GET
@Path("{processId}/source")
@Produces(MediaType.TEXT_PLAIN)
public Response getSourceFileByProcessId(@PathParam("processId") String
processId) throws Exception {
- Optional<SourceFile> sourceFile =
sourceFilesProvider.getProcessSourceFile(processId);
-
- if (sourceFile.isEmpty()) {
- return Response.status(Response.Status.NOT_FOUND).build();
- }
+ return super.getSourceFileByProcessId(processId);
+ }
- return Response.ok(sourceFile.get().readContents()).build();
+ @Override
+ protected Response buildPlainResponse(byte[] content) {
+ return Response.ok(content).build();
+ }
+ @Override
+ protected Response buildStreamResponse(byte[] content, String fileName) {
+ return Response.ok(new ByteArrayInputStream(content),
MediaType.APPLICATION_OCTET_STREAM)
+ .header("Content-Disposition", "inline; filename=\"" +
fileName + "\"")
+ .build();
}
- @Inject
- void setSourceFilesProvider(SourceFilesProvider sourceFilesProvider) {
- this.sourceFilesProvider = sourceFilesProvider;
+ @Override
+ protected Response buildNotFoundResponse() {
+ return Response.status(Response.Status.NOT_FOUND).build();
}
}
diff --git
a/quarkus/addons/source-files/runtime/src/test/java/org/kie/kogito/addon/source/files/SourceFilesResourceTest.java
b/quarkus/addons/source-files/runtime/src/test/java/org/kie/kogito/addon/source/files/SourceFilesResourceTest.java
index 2968fe78d6..639eeb417e 100644
---
a/quarkus/addons/source-files/runtime/src/test/java/org/kie/kogito/addon/source/files/SourceFilesResourceTest.java
+++
b/quarkus/addons/source-files/runtime/src/test/java/org/kie/kogito/addon/source/files/SourceFilesResourceTest.java
@@ -22,20 +22,19 @@ import java.util.Optional;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
import org.kie.kogito.source.files.SourceFile;
import org.kie.kogito.source.files.SourceFilesProvider;
import org.mockito.Mock;
-
-import io.quarkus.test.junit.QuarkusTest;
+import org.mockito.junit.jupiter.MockitoExtension;
import jakarta.ws.rs.core.Response;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-@QuarkusTest
+@ExtendWith(MockitoExtension.class)
class SourceFilesResourceTest {
private static final String PROCESS_ID = "processId";
@@ -46,9 +45,7 @@ class SourceFilesResourceTest {
@BeforeEach
void setup() {
- sourceFilesTestResource = new SourceFilesResource();
- mockSourceFileProvider = mock(SourceFilesProvider.class);
- sourceFilesTestResource.setSourceFilesProvider(mockSourceFileProvider);
+ sourceFilesTestResource = new
SourceFilesResource(mockSourceFileProvider);
}
@Test
diff --git
a/quarkus/integration-tests/integration-tests-quarkus-usertasks/pom.xml
b/quarkus/integration-tests/integration-tests-quarkus-usertasks/pom.xml
index e648118be0..d002aa7f5e 100644
--- a/quarkus/integration-tests/integration-tests-quarkus-usertasks/pom.xml
+++ b/quarkus/integration-tests/integration-tests-quarkus-usertasks/pom.xml
@@ -27,7 +27,7 @@
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>integration-tests-quarkus-usertasks</artifactId>
- <name>Kogito :: Integration Tests :: Quarkus :: Processes :: Source
Files</name>
+ <name>Kogito :: Integration Tests :: Quarkus :: User Tasks</name>
<properties>
<java.module.name>org.jbpm.usertask.storage.jpa.quarkus.it</java.module.name>
diff --git a/springboot/addons/pom.xml b/springboot/addons/pom.xml
index 3aee177ac6..9dc176ea13 100644
--- a/springboot/addons/pom.xml
+++ b/springboot/addons/pom.xml
@@ -52,6 +52,7 @@
<module>flyway</module>
<module>persistence</module>
<module>jbpm-usertask-storage-jpa</module>
+ <module>source-files</module>
</modules>
<dependencyManagement>
diff --git a/springboot/addons/source-files/pom.xml
b/springboot/addons/source-files/pom.xml
new file mode 100644
index 0000000000..f42c8da207
--- /dev/null
+++ b/springboot/addons/source-files/pom.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>kogito-addons-springboot-parent</artifactId>
+ <groupId>org.kie</groupId>
+ <version>999-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>kie-addons-springboot-source-files</artifactId>
+ <name>KIE :: Add-Ons :: Source Files :: Spring Boot Addon</name>
+ <description>Provides access to source files for Spring Boot</description>
+
+ <properties>
+
<java.module.name>org.kie.kogito.springboot.addon.source.files</java.module.name>
+ </properties>
+
+
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.kie</groupId>
+ <artifactId>kie-addons-source-files</artifactId>
+ </dependency>
+
+ <!-- test dependencies -->
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-engine</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-junit-jupiter</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.kie</groupId>
+
<artifactId>kie-addons-springboot-rest-exception-handler</artifactId>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
diff --git
a/springboot/addons/source-files/src/main/java/org/kie/kogito/addon/source/files/SourceFilesRestController.java
b/springboot/addons/source-files/src/main/java/org/kie/kogito/addon/source/files/SourceFilesRestController.java
new file mode 100644
index 0000000000..d24695f5c7
--- /dev/null
+++
b/springboot/addons/source-files/src/main/java/org/kie/kogito/addon/source/files/SourceFilesRestController.java
@@ -0,0 +1,81 @@
+/*
+ * 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.addon.source.files;
+
+import java.util.Collection;
+
+import org.kie.kogito.source.files.SourceFile;
+import org.kie.kogito.source.files.SourceFilesProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.core.io.ByteArrayResource;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/management/processes")
+public class SourceFilesRestController extends
BaseSourceFilesResource<ResponseEntity> {
+
+ @Autowired
+ @Lazy
+ public SourceFilesRestController(SourceFilesProvider sourceFilesProvider) {
+ super(sourceFilesProvider);
+ }
+
+ @Override
+ @GetMapping(value = "sources", produces =
MediaType.APPLICATION_OCTET_STREAM_VALUE)
+ public ResponseEntity getSourceFileByUri(@RequestParam("uri") String uri)
throws Exception {
+ return super.getSourceFileByUri(uri);
+ }
+
+ @Override
+ @GetMapping(value = "{processId}/sources", produces =
MediaType.APPLICATION_JSON_VALUE)
+ public Collection<SourceFile>
getSourceFilesByProcessId(@PathVariable("processId") String processId) {
+ return super.getSourceFilesByProcessId(processId);
+ }
+
+ @Override
+ @GetMapping(value = "{processId}/source", produces =
MediaType.TEXT_PLAIN_VALUE)
+ public ResponseEntity getSourceFileByProcessId(@PathVariable("processId")
String processId) throws Exception {
+ return super.getSourceFileByProcessId(processId);
+ }
+
+ @Override
+ protected ResponseEntity buildPlainResponse(byte[] content) {
+ return ResponseEntity.ok(content);
+ }
+
+ @Override
+ protected ResponseEntity buildStreamResponse(byte[] content, String
fileName) {
+ ByteArrayResource byteArrayResource = new ByteArrayResource(content);
+ return ResponseEntity.ok()
+ .contentType(MediaType.APPLICATION_OCTET_STREAM)
+ .contentLength(byteArrayResource.contentLength())
+ .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\""
+ fileName + "\"")
+ .body(content);
+ }
+
+ @Override
+ protected ResponseEntity buildNotFoundResponse() {
+ return ResponseEntity.notFound().build();
+ }
+}
diff --git
a/springboot/addons/source-files/src/main/resources/META-INF/kogito.addon
b/springboot/addons/source-files/src/main/resources/META-INF/kogito.addon
new file mode 100644
index 0000000000..4e2be1d005
--- /dev/null
+++ b/springboot/addons/source-files/src/main/resources/META-INF/kogito.addon
@@ -0,0 +1 @@
+source-files
\ No newline at end of file
diff --git
a/quarkus/addons/source-files/runtime/src/test/java/org/kie/kogito/addon/source/files/SourceFilesResourceTest.java
b/springboot/addons/source-files/src/test/java/org/kie/kogito/addon/source/files/SourceFilesRestControllerTest.java
similarity index 72%
copy from
quarkus/addons/source-files/runtime/src/test/java/org/kie/kogito/addon/source/files/SourceFilesResourceTest.java
copy to
springboot/addons/source-files/src/test/java/org/kie/kogito/addon/source/files/SourceFilesRestControllerTest.java
index 2968fe78d6..ae4d0409d9 100644
---
a/quarkus/addons/source-files/runtime/src/test/java/org/kie/kogito/addon/source/files/SourceFilesResourceTest.java
+++
b/springboot/addons/source-files/src/test/java/org/kie/kogito/addon/source/files/SourceFilesRestControllerTest.java
@@ -16,58 +16,56 @@
* specific language governing permissions and limitations
* under the License.
*/
+
package org.kie.kogito.addon.source.files;
import java.util.Optional;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
import org.kie.kogito.source.files.SourceFile;
import org.kie.kogito.source.files.SourceFilesProvider;
import org.mockito.Mock;
-
-import io.quarkus.test.junit.QuarkusTest;
-
-import jakarta.ws.rs.core.Response;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.http.HttpStatus;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-@QuarkusTest
-class SourceFilesResourceTest {
+@ExtendWith(MockitoExtension.class)
+public class SourceFilesRestControllerTest {
+
private static final String PROCESS_ID = "processId";
- private SourceFilesResource sourceFilesTestResource;
+ private SourceFilesRestController sourceFilesRestController;
@Mock
private SourceFilesProvider mockSourceFileProvider;
@BeforeEach
void setup() {
- sourceFilesTestResource = new SourceFilesResource();
- mockSourceFileProvider = mock(SourceFilesProvider.class);
- sourceFilesTestResource.setSourceFilesProvider(mockSourceFileProvider);
+ sourceFilesRestController = new
SourceFilesRestController(mockSourceFileProvider);
}
@Test
void getSourceFilesByProcessIdTest() {
- sourceFilesTestResource.getSourceFilesByProcessId(PROCESS_ID);
+ sourceFilesRestController.getSourceFilesByProcessId(PROCESS_ID);
verify(mockSourceFileProvider).getProcessSourceFiles(PROCESS_ID);
}
@Test
void getEmptySourceFileByProcessIdTest() throws Exception {
when(mockSourceFileProvider.getProcessSourceFile(PROCESS_ID)).thenReturn(Optional.empty());
-
assertThat(sourceFilesTestResource.getSourceFileByProcessId(PROCESS_ID).getStatus()).isEqualTo(Response.Status.NOT_FOUND.getStatusCode());
+
assertThat(sourceFilesRestController.getSourceFileByProcessId(PROCESS_ID).getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
verify(mockSourceFileProvider).getProcessSourceFile(PROCESS_ID);
}
@Test
void getValidSourceFileByProcessIdTest() throws Exception {
when(mockSourceFileProvider.getProcessSourceFile(PROCESS_ID)).thenReturn(Optional.of(new
SourceFile("petstore.sw.json")));
-
assertThat(sourceFilesTestResource.getSourceFileByProcessId(PROCESS_ID).getStatus()).isEqualTo(Response.Status.OK.getStatusCode());
+
assertThat(sourceFilesRestController.getSourceFileByProcessId(PROCESS_ID).getStatusCode()).isEqualTo(HttpStatus.OK);
verify(mockSourceFileProvider).getProcessSourceFile(PROCESS_ID);
}
}
diff --git a/springboot/addons/source-files/src/test/resources/petstore.sw.json
b/springboot/addons/source-files/src/test/resources/petstore.sw.json
new file mode 100644
index 0000000000..cd995605c0
--- /dev/null
+++ b/springboot/addons/source-files/src/test/resources/petstore.sw.json
@@ -0,0 +1,31 @@
+{
+ "id": "petstore",
+ "version": "1.0",
+ "name": "Send CloudEvent after creating Pluto",
+ "start": "AddPluto",
+ "functions": [
+ {
+ "name": "addPet",
+ "operation": "petstore.json#addPet"
+ }
+ ],
+ "states": [
+ {
+ "name": "AddPluto",
+ "type": "operation",
+ "actions": [
+ {
+ "functionRef": {
+ "refName": "addPet",
+ "parameters": {
+ "body": {
+ "name": "Pluto"
+ }
+ }
+ }
+ }
+ ],
+ "end": true
+ }
+ ]
+}
\ No newline at end of file
diff --git
a/springboot/integration-tests/integration-tests-springboot-processes-it/pom.xml
b/springboot/integration-tests/integration-tests-springboot-processes-it/pom.xml
index b214930f9b..8b16d78ba7 100644
---
a/springboot/integration-tests/integration-tests-springboot-processes-it/pom.xml
+++
b/springboot/integration-tests/integration-tests-springboot-processes-it/pom.xml
@@ -67,6 +67,11 @@
<artifactId>jbpm-addons-springboot-task-management</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.kie</groupId>
+ <artifactId>kie-addons-springboot-source-files</artifactId>
+ </dependency>
+
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-addons-springboot-process-svg</artifactId>
diff --git
a/springboot/integration-tests/integration-tests-springboot-processes-it/src/main/resources/cinema.bpmn
b/springboot/integration-tests/integration-tests-springboot-processes-it/src/main/resources/org/kie/kogito/examples/cinema.bpmn
similarity index 100%
rename from
springboot/integration-tests/integration-tests-springboot-processes-it/src/main/resources/cinema.bpmn
rename to
springboot/integration-tests/integration-tests-springboot-processes-it/src/main/resources/org/kie/kogito/examples/cinema.bpmn
diff --git
a/springboot/integration-tests/integration-tests-springboot-processes-it/src/main/resources/timers.bpmn
b/springboot/integration-tests/integration-tests-springboot-processes-it/src/main/resources/org/kie/kogito/examples/timers.bpmn
similarity index 100%
rename from
springboot/integration-tests/integration-tests-springboot-processes-it/src/main/resources/timers.bpmn
rename to
springboot/integration-tests/integration-tests-springboot-processes-it/src/main/resources/org/kie/kogito/examples/timers.bpmn
diff --git
a/springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/SourceFilesAddOnIT.java
b/springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/SourceFilesAddOnIT.java
new file mode 100644
index 0000000000..db9a199ab1
--- /dev/null
+++
b/springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/SourceFilesAddOnIT.java
@@ -0,0 +1,109 @@
+/*
+ * 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.integrationtests.springboot;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.web.server.LocalServerPort;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import io.restassured.RestAssured;
+import io.restassured.http.ContentType;
+
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.Matchers.hasEntry;
+
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = KogitoSpringbootApplication.class)
+public class SourceFilesAddOnIT extends BaseRestTest {
+
+ private static final String GET_SOURCES_PATH =
"/management/processes/sources";
+ private static final String GET_PROCESS_SOURCES_PATH =
"/management/processes/{processId}/sources";
+ private static final String GET_PROCESS_SOURCE_PATH =
"/management/processes/{processId}/source";
+
+ @LocalServerPort
+ int randomServerPort;
+
+ static {
+ RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
+ }
+
+ @BeforeEach
+ void setPort() {
+ RestAssured.port = randomServerPort;
+ }
+
+ public static String readFileContent(String file) throws
URISyntaxException, IOException {
+ Path path =
Paths.get(Thread.currentThread().getContextClassLoader().getResource(file).toURI());
+ return Files.readString(path);
+ }
+
+ @Test
+ void testGetSourceFilesByProcessId() {
+ given()
+ .contentType(ContentType.JSON)
+ .when()
+ .get(GET_PROCESS_SOURCES_PATH, "cinema")
+ .then()
+ .statusCode(200)
+ .body("size()", is(1))
+ .body("", hasItems(hasEntry("uri",
"org/kie/kogito/examples/cinema.bpmn")));
+ }
+
+ @Test
+ void testGetSourceFileByProcessId() throws Exception {
+ given().when()
+ .get(GET_PROCESS_SOURCE_PATH, "approvals")
+ .then()
+ .statusCode(200)
+ .body(equalTo(readFileContent("approval.bpmn")));
+ }
+
+ @Test
+ void testGetSourceFileFromResourcesRoot() {
+ given()
+ .when()
+ .queryParam("uri", "approval.bpmn")
+ .get(GET_SOURCES_PATH)
+ .then()
+ .statusCode(200)
+ .header("Content-Length", "24215");
+ }
+
+ @Test
+ void testGetSourceFileFromInternalDirectory() {
+ given()
+ .when()
+ .queryParam("uri", "org/kie/kogito/examples/timers.bpmn")
+ .get(GET_SOURCES_PATH)
+ .then()
+ .statusCode(200)
+ .header("Content-Length", "11583");
+ }
+}
diff --git
a/springboot/integration-tests/integration-tests-springboot-processes-it/src/test/resources/approval.bpmn
b/springboot/integration-tests/integration-tests-springboot-processes-it/src/test/resources/approval.bpmn
new file mode 100644
index 0000000000..da70dcb93b
--- /dev/null
+++
b/springboot/integration-tests/integration-tests-springboot-processes-it/src/test/resources/approval.bpmn
@@ -0,0 +1,323 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+
+<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.omg.org/bpmn20"
xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:bpsim="http://www.bpsim.org/schemas/1.0"
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
xmlns:drools="http://www.jboss.org/drools" id="_F0jB8En5EeqlfsIhq1UCRQ"
xsi:schemaLocation="http://www.omg.org/spec/BPMN/201 [...]
+ <bpmn2:itemDefinition id="_approverItem" structureRef="String"/>
+ <bpmn2:itemDefinition id="_travellerItem"
structureRef="org.acme.travels.Traveller"/>
+ <bpmn2:itemDefinition id="_firstLineApprovalItem" structureRef="Boolean"/>
+ <bpmn2:itemDefinition id="_secondLineApprovalItem" structureRef="Boolean"/>
+ <bpmn2:itemDefinition
id="__0DBFABE8-92B0-46E6-B52E-A9593AFA4371_SkippableInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__0DBFABE8-92B0-46E6-B52E-A9593AFA4371_PriorityInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__0DBFABE8-92B0-46E6-B52E-A9593AFA4371_CommentInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__0DBFABE8-92B0-46E6-B52E-A9593AFA4371_DescriptionInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__0DBFABE8-92B0-46E6-B52E-A9593AFA4371_CreatedByInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__0DBFABE8-92B0-46E6-B52E-A9593AFA4371_TaskNameInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__0DBFABE8-92B0-46E6-B52E-A9593AFA4371_GroupIdInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__0DBFABE8-92B0-46E6-B52E-A9593AFA4371_ContentInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__0DBFABE8-92B0-46E6-B52E-A9593AFA4371_NotStartedReassignInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__0DBFABE8-92B0-46E6-B52E-A9593AFA4371_NotCompletedReassignInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__0DBFABE8-92B0-46E6-B52E-A9593AFA4371_NotStartedNotifyInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__0DBFABE8-92B0-46E6-B52E-A9593AFA4371_NotCompletedNotifyInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__0DBFABE8-92B0-46E6-B52E-A9593AFA4371_ExcludedOwnerIdInputXItem"
structureRef="String"/>
+ <bpmn2:itemDefinition
id="__0DBFABE8-92B0-46E6-B52E-A9593AFA4371_travellerInputXItem"
structureRef="org.acme.travels.Traveller"/>
+ <bpmn2:itemDefinition
id="__0DBFABE8-92B0-46E6-B52E-A9593AFA4371_approvedOutputXItem"
structureRef="Boolean"/>
+ <bpmn2:itemDefinition
id="__8B62D3CA-5D03-4B2B-832B-126469288BB4_SkippableInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__8B62D3CA-5D03-4B2B-832B-126469288BB4_PriorityInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__8B62D3CA-5D03-4B2B-832B-126469288BB4_CommentInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__8B62D3CA-5D03-4B2B-832B-126469288BB4_DescriptionInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__8B62D3CA-5D03-4B2B-832B-126469288BB4_CreatedByInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__8B62D3CA-5D03-4B2B-832B-126469288BB4_TaskNameInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__8B62D3CA-5D03-4B2B-832B-126469288BB4_GroupIdInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__8B62D3CA-5D03-4B2B-832B-126469288BB4_ContentInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__8B62D3CA-5D03-4B2B-832B-126469288BB4_NotStartedReassignInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__8B62D3CA-5D03-4B2B-832B-126469288BB4_NotCompletedReassignInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__8B62D3CA-5D03-4B2B-832B-126469288BB4_NotStartedNotifyInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__8B62D3CA-5D03-4B2B-832B-126469288BB4_NotCompletedNotifyInputXItem"
structureRef="Object"/>
+ <bpmn2:itemDefinition
id="__8B62D3CA-5D03-4B2B-832B-126469288BB4_travellerInputXItem"
structureRef="org.acme.travels.Traveller"/>
+ <bpmn2:itemDefinition
id="__8B62D3CA-5D03-4B2B-832B-126469288BB4_ActorIdOutputXItem"
structureRef="String"/>
+ <bpmn2:itemDefinition
id="__8B62D3CA-5D03-4B2B-832B-126469288BB4_approvedOutputXItem"
structureRef="Boolean"/>
+ <bpmn2:process id="approvals" drools:packageName="org.acme.travels"
drools:version="1.0" drools:adHoc="false" name="approvals" isExecutable="true">
+ <bpmn2:extensionElements>
+ <drools:import name="org.acme.travels.Traveller"/>
+ </bpmn2:extensionElements>
+ <bpmn2:property id="approver" itemSubjectRef="_approverItem"
name="approver"/>
+ <bpmn2:property id="traveller" itemSubjectRef="_travellerItem"
name="traveller"/>
+ <bpmn2:property id="firstLineApproval"
itemSubjectRef="_firstLineApprovalItem" name="firstLineApproval"/>
+ <bpmn2:property id="secondLineApproval"
itemSubjectRef="_secondLineApprovalItem" name="secondLineApproval"/>
+ <bpmn2:sequenceFlow id="_C13522F1-230A-4C26-B5A9-533A5D9FEE9D"
sourceRef="_8B62D3CA-5D03-4B2B-832B-126469288BB4"
targetRef="_0DBFABE8-92B0-46E6-B52E-A9593AFA4371">
+ <bpmn2:extensionElements>
+ <drools:metaData name="isAutoConnection.source">
+ <drools:metaValue><![CDATA[true]]></drools:metaValue>
+ </drools:metaData>
+ <drools:metaData name="isAutoConnection.target">
+ <drools:metaValue><![CDATA[true]]></drools:metaValue>
+ </drools:metaData>
+ </bpmn2:extensionElements>
+ </bpmn2:sequenceFlow>
+ <bpmn2:sequenceFlow id="_9EAFE6C1-69B4-4908-B764-EF3C4A55BEE3"
sourceRef="_9861B686-DF6B-4B1C-B370-F9898EEB47FD"
targetRef="_8B62D3CA-5D03-4B2B-832B-126469288BB4">
+ <bpmn2:extensionElements>
+ <drools:metaData name="isAutoConnection.source">
+ <drools:metaValue><![CDATA[true]]></drools:metaValue>
+ </drools:metaData>
+ <drools:metaData name="isAutoConnection.target">
+ <drools:metaValue><![CDATA[true]]></drools:metaValue>
+ </drools:metaData>
+ </bpmn2:extensionElements>
+ </bpmn2:sequenceFlow>
+ <bpmn2:sequenceFlow id="_078F46FB-B7A1-4DBB-BE9A-75C7CB0CCD03"
sourceRef="_0DBFABE8-92B0-46E6-B52E-A9593AFA4371"
targetRef="_125D9683-9218-4BBC-94C2-59DDD449ADC6">
+ <bpmn2:extensionElements>
+ <drools:metaData name="isAutoConnection.source">
+ <drools:metaValue><![CDATA[true]]></drools:metaValue>
+ </drools:metaData>
+ <drools:metaData name="isAutoConnection.target">
+ <drools:metaValue><![CDATA[true]]></drools:metaValue>
+ </drools:metaData>
+ </bpmn2:extensionElements>
+ </bpmn2:sequenceFlow>
+ <bpmn2:userTask id="_8B62D3CA-5D03-4B2B-832B-126469288BB4" name="First
Line Approval">
+ <bpmn2:extensionElements>
+ <drools:metaData name="elementname">
+ <drools:metaValue><![CDATA[First Line Approval]]></drools:metaValue>
+ </drools:metaData>
+ </bpmn2:extensionElements>
+ <bpmn2:incoming>_9EAFE6C1-69B4-4908-B764-EF3C4A55BEE3</bpmn2:incoming>
+ <bpmn2:outgoing>_C13522F1-230A-4C26-B5A9-533A5D9FEE9D</bpmn2:outgoing>
+ <bpmn2:ioSpecification id="_F0jB8Un5EeqlfsIhq1UCRQ">
+ <bpmn2:dataInput
id="_8B62D3CA-5D03-4B2B-832B-126469288BB4_TaskNameInputX" drools:dtype="Object"
itemSubjectRef="__8B62D3CA-5D03-4B2B-832B-126469288BB4_TaskNameInputXItem"
name="TaskName"/>
+ <bpmn2:dataInput
id="_8B62D3CA-5D03-4B2B-832B-126469288BB4_travellerInputX"
drools:dtype="org.acme.travels.Traveller"
itemSubjectRef="__8B62D3CA-5D03-4B2B-832B-126469288BB4_travellerInputXItem"
name="traveller"/>
+ <bpmn2:dataInput
id="_8B62D3CA-5D03-4B2B-832B-126469288BB4_SkippableInputX"
drools:dtype="Object"
itemSubjectRef="__8B62D3CA-5D03-4B2B-832B-126469288BB4_SkippableInputXItem"
name="Skippable"/>
+ <bpmn2:dataInput
id="_8B62D3CA-5D03-4B2B-832B-126469288BB4_GroupIdInputX" drools:dtype="Object"
itemSubjectRef="__8B62D3CA-5D03-4B2B-832B-126469288BB4_GroupIdInputXItem"
name="GroupId"/>
+ <bpmn2:dataOutput
id="_8B62D3CA-5D03-4B2B-832B-126469288BB4_ActorIdOutputX" drools:dtype="String"
itemSubjectRef="__8B62D3CA-5D03-4B2B-832B-126469288BB4_ActorIdOutputXItem"
name="ActorId"/>
+ <bpmn2:dataOutput
id="_8B62D3CA-5D03-4B2B-832B-126469288BB4_approvedOutputX"
drools:dtype="Boolean"
itemSubjectRef="__8B62D3CA-5D03-4B2B-832B-126469288BB4_approvedOutputXItem"
name="approved"/>
+ <bpmn2:inputSet id="_F0jB8kn5EeqlfsIhq1UCRQ">
+
<bpmn2:dataInputRefs>_8B62D3CA-5D03-4B2B-832B-126469288BB4_TaskNameInputX</bpmn2:dataInputRefs>
+
<bpmn2:dataInputRefs>_8B62D3CA-5D03-4B2B-832B-126469288BB4_travellerInputX</bpmn2:dataInputRefs>
+
<bpmn2:dataInputRefs>_8B62D3CA-5D03-4B2B-832B-126469288BB4_SkippableInputX</bpmn2:dataInputRefs>
+
<bpmn2:dataInputRefs>_8B62D3CA-5D03-4B2B-832B-126469288BB4_GroupIdInputX</bpmn2:dataInputRefs>
+ </bpmn2:inputSet>
+ <bpmn2:outputSet id="_F0jB80n5EeqlfsIhq1UCRQ">
+
<bpmn2:dataOutputRefs>_8B62D3CA-5D03-4B2B-832B-126469288BB4_ActorIdOutputX</bpmn2:dataOutputRefs>
+
<bpmn2:dataOutputRefs>_8B62D3CA-5D03-4B2B-832B-126469288BB4_approvedOutputX</bpmn2:dataOutputRefs>
+ </bpmn2:outputSet>
+ </bpmn2:ioSpecification>
+ <bpmn2:dataInputAssociation id="_F0jB9En5EeqlfsIhq1UCRQ">
+
<bpmn2:targetRef>_8B62D3CA-5D03-4B2B-832B-126469288BB4_TaskNameInputX</bpmn2:targetRef>
+ <bpmn2:assignment id="_F0jB9Un5EeqlfsIhq1UCRQ">
+ <bpmn2:from xsi:type="bpmn2:tFormalExpression"
id="_F0jB9kn5EeqlfsIhq1UCRQ"><![CDATA[firstLineApproval]]></bpmn2:from>
+ <bpmn2:to xsi:type="bpmn2:tFormalExpression"
id="_F0jB90n5EeqlfsIhq1UCRQ">_8B62D3CA-5D03-4B2B-832B-126469288BB4_TaskNameInputX</bpmn2:to>
+ </bpmn2:assignment>
+ </bpmn2:dataInputAssociation>
+ <bpmn2:dataInputAssociation id="_F0jB-En5EeqlfsIhq1UCRQ">
+ <bpmn2:sourceRef>traveller</bpmn2:sourceRef>
+
<bpmn2:targetRef>_8B62D3CA-5D03-4B2B-832B-126469288BB4_travellerInputX</bpmn2:targetRef>
+ </bpmn2:dataInputAssociation>
+ <bpmn2:dataInputAssociation id="_F0jB-Un5EeqlfsIhq1UCRQ">
+
<bpmn2:targetRef>_8B62D3CA-5D03-4B2B-832B-126469288BB4_SkippableInputX</bpmn2:targetRef>
+ <bpmn2:assignment id="_F0jB-kn5EeqlfsIhq1UCRQ">
+ <bpmn2:from xsi:type="bpmn2:tFormalExpression"
id="_F0jB-0n5EeqlfsIhq1UCRQ"><![CDATA[true]]></bpmn2:from>
+ <bpmn2:to xsi:type="bpmn2:tFormalExpression"
id="_F0jB_En5EeqlfsIhq1UCRQ">_8B62D3CA-5D03-4B2B-832B-126469288BB4_SkippableInputX</bpmn2:to>
+ </bpmn2:assignment>
+ </bpmn2:dataInputAssociation>
+ <bpmn2:dataInputAssociation id="_F0jB_Un5EeqlfsIhq1UCRQ">
+
<bpmn2:targetRef>_8B62D3CA-5D03-4B2B-832B-126469288BB4_GroupIdInputX</bpmn2:targetRef>
+ <bpmn2:assignment id="_F0jB_kn5EeqlfsIhq1UCRQ">
+ <bpmn2:from xsi:type="bpmn2:tFormalExpression"
id="_F0jB_0n5EeqlfsIhq1UCRQ"><![CDATA[managers]]></bpmn2:from>
+ <bpmn2:to xsi:type="bpmn2:tFormalExpression"
id="_F0jCAEn5EeqlfsIhq1UCRQ">_8B62D3CA-5D03-4B2B-832B-126469288BB4_GroupIdInputX</bpmn2:to>
+ </bpmn2:assignment>
+ </bpmn2:dataInputAssociation>
+ <bpmn2:dataOutputAssociation id="_F0jCAUn5EeqlfsIhq1UCRQ">
+
<bpmn2:sourceRef>_8B62D3CA-5D03-4B2B-832B-126469288BB4_ActorIdOutputX</bpmn2:sourceRef>
+ <bpmn2:targetRef>approver</bpmn2:targetRef>
+ </bpmn2:dataOutputAssociation>
+ <bpmn2:dataOutputAssociation id="_F0jCAkn5EeqlfsIhq1UCRQ">
+
<bpmn2:sourceRef>_8B62D3CA-5D03-4B2B-832B-126469288BB4_approvedOutputX</bpmn2:sourceRef>
+ <bpmn2:targetRef>firstLineApproval</bpmn2:targetRef>
+ </bpmn2:dataOutputAssociation>
+ <bpmn2:potentialOwner id="_2f7befe6-4b21-43e9-a59c-71fb1fc296c8">
+ <bpmn2:resourceAssignmentExpression id="_F0jCA0n5EeqlfsIhq1UCRQ">
+ <bpmn2:formalExpression
id="_F0jCBEn5EeqlfsIhq1UCRQ">manager</bpmn2:formalExpression>
+ </bpmn2:resourceAssignmentExpression>
+ </bpmn2:potentialOwner>
+ </bpmn2:userTask>
+ <bpmn2:userTask id="_0DBFABE8-92B0-46E6-B52E-A9593AFA4371" name="Second
Line Approval">
+ <bpmn2:extensionElements>
+ <drools:metaData name="elementname">
+ <drools:metaValue><![CDATA[Second Line Approval]]></drools:metaValue>
+ </drools:metaData>
+ </bpmn2:extensionElements>
+ <bpmn2:incoming>_C13522F1-230A-4C26-B5A9-533A5D9FEE9D</bpmn2:incoming>
+ <bpmn2:outgoing>_078F46FB-B7A1-4DBB-BE9A-75C7CB0CCD03</bpmn2:outgoing>
+ <bpmn2:ioSpecification id="_F0jCBUn5EeqlfsIhq1UCRQ">
+ <bpmn2:dataInput
id="_0DBFABE8-92B0-46E6-B52E-A9593AFA4371_TaskNameInputX" drools:dtype="Object"
itemSubjectRef="__0DBFABE8-92B0-46E6-B52E-A9593AFA4371_TaskNameInputXItem"
name="TaskName"/>
+ <bpmn2:dataInput
id="_0DBFABE8-92B0-46E6-B52E-A9593AFA4371_ExcludedOwnerIdInputX"
drools:dtype="String"
itemSubjectRef="__0DBFABE8-92B0-46E6-B52E-A9593AFA4371_ExcludedOwnerIdInputXItem"
name="ExcludedOwnerId"/>
+ <bpmn2:dataInput
id="_0DBFABE8-92B0-46E6-B52E-A9593AFA4371_travellerInputX"
drools:dtype="org.acme.travels.Traveller"
itemSubjectRef="__0DBFABE8-92B0-46E6-B52E-A9593AFA4371_travellerInputXItem"
name="traveller"/>
+ <bpmn2:dataInput
id="_0DBFABE8-92B0-46E6-B52E-A9593AFA4371_SkippableInputX"
drools:dtype="Object"
itemSubjectRef="__0DBFABE8-92B0-46E6-B52E-A9593AFA4371_SkippableInputXItem"
name="Skippable"/>
+ <bpmn2:dataInput
id="_0DBFABE8-92B0-46E6-B52E-A9593AFA4371_GroupIdInputX" drools:dtype="Object"
itemSubjectRef="__0DBFABE8-92B0-46E6-B52E-A9593AFA4371_GroupIdInputXItem"
name="GroupId"/>
+ <bpmn2:dataOutput
id="_0DBFABE8-92B0-46E6-B52E-A9593AFA4371_approvedOutputX"
drools:dtype="Boolean"
itemSubjectRef="__0DBFABE8-92B0-46E6-B52E-A9593AFA4371_approvedOutputXItem"
name="approved"/>
+ <bpmn2:inputSet id="_F0jCBkn5EeqlfsIhq1UCRQ">
+
<bpmn2:dataInputRefs>_0DBFABE8-92B0-46E6-B52E-A9593AFA4371_TaskNameInputX</bpmn2:dataInputRefs>
+
<bpmn2:dataInputRefs>_0DBFABE8-92B0-46E6-B52E-A9593AFA4371_ExcludedOwnerIdInputX</bpmn2:dataInputRefs>
+
<bpmn2:dataInputRefs>_0DBFABE8-92B0-46E6-B52E-A9593AFA4371_travellerInputX</bpmn2:dataInputRefs>
+
<bpmn2:dataInputRefs>_0DBFABE8-92B0-46E6-B52E-A9593AFA4371_SkippableInputX</bpmn2:dataInputRefs>
+
<bpmn2:dataInputRefs>_0DBFABE8-92B0-46E6-B52E-A9593AFA4371_GroupIdInputX</bpmn2:dataInputRefs>
+ </bpmn2:inputSet>
+ <bpmn2:outputSet id="_F0jCB0n5EeqlfsIhq1UCRQ">
+
<bpmn2:dataOutputRefs>_0DBFABE8-92B0-46E6-B52E-A9593AFA4371_approvedOutputX</bpmn2:dataOutputRefs>
+ </bpmn2:outputSet>
+ </bpmn2:ioSpecification>
+ <bpmn2:dataInputAssociation id="_F0jCCEn5EeqlfsIhq1UCRQ">
+
<bpmn2:targetRef>_0DBFABE8-92B0-46E6-B52E-A9593AFA4371_TaskNameInputX</bpmn2:targetRef>
+ <bpmn2:assignment id="_F0jCCUn5EeqlfsIhq1UCRQ">
+ <bpmn2:from xsi:type="bpmn2:tFormalExpression"
id="_F0jCCkn5EeqlfsIhq1UCRQ"><![CDATA[secondLineApproval]]></bpmn2:from>
+ <bpmn2:to xsi:type="bpmn2:tFormalExpression"
id="_F0jCC0n5EeqlfsIhq1UCRQ">_0DBFABE8-92B0-46E6-B52E-A9593AFA4371_TaskNameInputX</bpmn2:to>
+ </bpmn2:assignment>
+ </bpmn2:dataInputAssociation>
+ <bpmn2:dataInputAssociation id="_F0jCDEn5EeqlfsIhq1UCRQ">
+ <bpmn2:sourceRef>approver</bpmn2:sourceRef>
+
<bpmn2:targetRef>_0DBFABE8-92B0-46E6-B52E-A9593AFA4371_ExcludedOwnerIdInputX</bpmn2:targetRef>
+ </bpmn2:dataInputAssociation>
+ <bpmn2:dataInputAssociation id="_F0jCDUn5EeqlfsIhq1UCRQ">
+ <bpmn2:sourceRef>traveller</bpmn2:sourceRef>
+
<bpmn2:targetRef>_0DBFABE8-92B0-46E6-B52E-A9593AFA4371_travellerInputX</bpmn2:targetRef>
+ </bpmn2:dataInputAssociation>
+ <bpmn2:dataInputAssociation id="_F0jCDkn5EeqlfsIhq1UCRQ">
+
<bpmn2:targetRef>_0DBFABE8-92B0-46E6-B52E-A9593AFA4371_SkippableInputX</bpmn2:targetRef>
+ <bpmn2:assignment id="_F0jCD0n5EeqlfsIhq1UCRQ">
+ <bpmn2:from xsi:type="bpmn2:tFormalExpression"
id="_F0jCEEn5EeqlfsIhq1UCRQ"><![CDATA[true]]></bpmn2:from>
+ <bpmn2:to xsi:type="bpmn2:tFormalExpression"
id="_F0jCEUn5EeqlfsIhq1UCRQ">_0DBFABE8-92B0-46E6-B52E-A9593AFA4371_SkippableInputX</bpmn2:to>
+ </bpmn2:assignment>
+ </bpmn2:dataInputAssociation>
+ <bpmn2:dataInputAssociation id="_F0jCEkn5EeqlfsIhq1UCRQ">
+
<bpmn2:targetRef>_0DBFABE8-92B0-46E6-B52E-A9593AFA4371_GroupIdInputX</bpmn2:targetRef>
+ <bpmn2:assignment id="_F0jCE0n5EeqlfsIhq1UCRQ">
+ <bpmn2:from xsi:type="bpmn2:tFormalExpression"
id="_F0jCFEn5EeqlfsIhq1UCRQ"><![CDATA[managers]]></bpmn2:from>
+ <bpmn2:to xsi:type="bpmn2:tFormalExpression"
id="_F0jCFUn5EeqlfsIhq1UCRQ">_0DBFABE8-92B0-46E6-B52E-A9593AFA4371_GroupIdInputX</bpmn2:to>
+ </bpmn2:assignment>
+ </bpmn2:dataInputAssociation>
+ <bpmn2:dataOutputAssociation id="_F0jCFkn5EeqlfsIhq1UCRQ">
+
<bpmn2:sourceRef>_0DBFABE8-92B0-46E6-B52E-A9593AFA4371_approvedOutputX</bpmn2:sourceRef>
+ <bpmn2:targetRef>secondLineApproval</bpmn2:targetRef>
+ </bpmn2:dataOutputAssociation>
+ </bpmn2:userTask>
+ <bpmn2:startEvent id="_9861B686-DF6B-4B1C-B370-F9898EEB47FD"
name="StartProcess">
+ <bpmn2:extensionElements>
+ <drools:metaData name="elementname">
+ <drools:metaValue><![CDATA[StartProcess
+]]></drools:metaValue>
+ </drools:metaData>
+ </bpmn2:extensionElements>
+ <bpmn2:outgoing>_9EAFE6C1-69B4-4908-B764-EF3C4A55BEE3</bpmn2:outgoing>
+ </bpmn2:startEvent>
+ <bpmn2:endEvent id="_125D9683-9218-4BBC-94C2-59DDD449ADC6" name="End">
+ <bpmn2:extensionElements>
+ <drools:metaData name="elementname">
+ <drools:metaValue><![CDATA[End]]></drools:metaValue>
+ </drools:metaData>
+ </bpmn2:extensionElements>
+ <bpmn2:incoming>_078F46FB-B7A1-4DBB-BE9A-75C7CB0CCD03</bpmn2:incoming>
+ </bpmn2:endEvent>
+ </bpmn2:process>
+ <bpmndi:BPMNDiagram id="_F0jCF0n5EeqlfsIhq1UCRQ">
+ <bpmndi:BPMNPlane id="_F0jCGEn5EeqlfsIhq1UCRQ" bpmnElement="approvals">
+ <bpmndi:BPMNShape id="shape__125D9683-9218-4BBC-94C2-59DDD449ADC6"
bpmnElement="_125D9683-9218-4BBC-94C2-59DDD449ADC6">
+ <dc:Bounds height="56.0" width="56.0" x="923.0" y="280.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="shape__9861B686-DF6B-4B1C-B370-F9898EEB47FD"
bpmnElement="_9861B686-DF6B-4B1C-B370-F9898EEB47FD">
+ <dc:Bounds height="56.0" width="56.0" x="319.0" y="280.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="shape__0DBFABE8-92B0-46E6-B52E-A9593AFA4371"
bpmnElement="_0DBFABE8-92B0-46E6-B52E-A9593AFA4371">
+ <dc:Bounds height="102.0" width="154.0" x="689.0" y="257.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="shape__8B62D3CA-5D03-4B2B-832B-126469288BB4"
bpmnElement="_8B62D3CA-5D03-4B2B-832B-126469288BB4">
+ <dc:Bounds height="102.0" width="154.0" x="455.0" y="257.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge
id="edge_shape__0DBFABE8-92B0-46E6-B52E-A9593AFA4371_to_shape__125D9683-9218-4BBC-94C2-59DDD449ADC6"
bpmnElement="_078F46FB-B7A1-4DBB-BE9A-75C7CB0CCD03">
+ <di:waypoint xsi:type="dc:Point" x="843.0" y="308.0"/>
+ <di:waypoint xsi:type="dc:Point" x="923.0" y="308.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge
id="edge_shape__9861B686-DF6B-4B1C-B370-F9898EEB47FD_to_shape__8B62D3CA-5D03-4B2B-832B-126469288BB4"
bpmnElement="_9EAFE6C1-69B4-4908-B764-EF3C4A55BEE3">
+ <di:waypoint xsi:type="dc:Point" x="375.0" y="308.0"/>
+ <di:waypoint xsi:type="dc:Point" x="455.0" y="308.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge
id="edge_shape__8B62D3CA-5D03-4B2B-832B-126469288BB4_to_shape__0DBFABE8-92B0-46E6-B52E-A9593AFA4371"
bpmnElement="_C13522F1-230A-4C26-B5A9-533A5D9FEE9D">
+ <di:waypoint xsi:type="dc:Point" x="609.0" y="308.0"/>
+ <di:waypoint xsi:type="dc:Point" x="689.0" y="308.0"/>
+ </bpmndi:BPMNEdge>
+ </bpmndi:BPMNPlane>
+ </bpmndi:BPMNDiagram>
+ <bpmn2:relationship id="_F0jCGUn5EeqlfsIhq1UCRQ" type="BPSimData">
+ <bpmn2:extensionElements>
+ <bpsim:BPSimData>
+ <bpsim:Scenario xsi:type="bpsim:Scenario" id="default"
name="Simulationscenario">
+ <bpsim:ScenarioParameters xsi:type="bpsim:ScenarioParameters"/>
+ <bpsim:ElementParameters xsi:type="bpsim:ElementParameters"
elementRef="_9861B686-DF6B-4B1C-B370-F9898EEB47FD" id="_F0jpAEn5EeqlfsIhq1UCRQ">
+ <bpsim:TimeParameters xsi:type="bpsim:TimeParameters">
+ <bpsim:ProcessingTime xsi:type="bpsim:Parameter">
+ <bpsim:NormalDistribution mean="0.0" standardDeviation="0.0"/>
+ </bpsim:ProcessingTime>
+ </bpsim:TimeParameters>
+ </bpsim:ElementParameters>
+ <bpsim:ElementParameters xsi:type="bpsim:ElementParameters"
elementRef="_0DBFABE8-92B0-46E6-B52E-A9593AFA4371" id="_F0jpAUn5EeqlfsIhq1UCRQ">
+ <bpsim:TimeParameters xsi:type="bpsim:TimeParameters">
+ <bpsim:ProcessingTime xsi:type="bpsim:Parameter">
+ <bpsim:NormalDistribution mean="0.0" standardDeviation="0.0"/>
+ </bpsim:ProcessingTime>
+ </bpsim:TimeParameters>
+ <bpsim:ResourceParameters xsi:type="bpsim:ResourceParameters">
+ <bpsim:Availability xsi:type="bpsim:Parameter">
+ <bpsim:FloatingParameter value="0.0"/>
+ </bpsim:Availability>
+ <bpsim:Quantity xsi:type="bpsim:Parameter">
+ <bpsim:FloatingParameter value="0.0"/>
+ </bpsim:Quantity>
+ </bpsim:ResourceParameters>
+ <bpsim:CostParameters xsi:type="bpsim:CostParameters">
+ <bpsim:UnitCost xsi:type="bpsim:Parameter">
+ <bpsim:FloatingParameter value="0.0"/>
+ </bpsim:UnitCost>
+ </bpsim:CostParameters>
+ </bpsim:ElementParameters>
+ <bpsim:ElementParameters xsi:type="bpsim:ElementParameters"
elementRef="_8B62D3CA-5D03-4B2B-832B-126469288BB4" id="_F0jpAkn5EeqlfsIhq1UCRQ">
+ <bpsim:TimeParameters xsi:type="bpsim:TimeParameters">
+ <bpsim:ProcessingTime xsi:type="bpsim:Parameter">
+ <bpsim:NormalDistribution mean="0.0" standardDeviation="0.0"/>
+ </bpsim:ProcessingTime>
+ </bpsim:TimeParameters>
+ <bpsim:ResourceParameters xsi:type="bpsim:ResourceParameters">
+ <bpsim:Availability xsi:type="bpsim:Parameter">
+ <bpsim:FloatingParameter value="0.0"/>
+ </bpsim:Availability>
+ <bpsim:Quantity xsi:type="bpsim:Parameter">
+ <bpsim:FloatingParameter value="0.0"/>
+ </bpsim:Quantity>
+ </bpsim:ResourceParameters>
+ <bpsim:CostParameters xsi:type="bpsim:CostParameters">
+ <bpsim:UnitCost xsi:type="bpsim:Parameter">
+ <bpsim:FloatingParameter value="0.0"/>
+ </bpsim:UnitCost>
+ </bpsim:CostParameters>
+ </bpsim:ElementParameters>
+ </bpsim:Scenario>
+ </bpsim:BPSimData>
+ </bpmn2:extensionElements>
+ <bpmn2:source>_F0jB8En5EeqlfsIhq1UCRQ</bpmn2:source>
+ <bpmn2:target>_F0jB8En5EeqlfsIhq1UCRQ</bpmn2:target>
+ </bpmn2:relationship>
+</bpmn2:definitions>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]