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.git
The following commit(s) were added to refs/heads/main by this push:
new c009e0a5a35 [incubator-kie-issue-2418] Workflow Engine: Support
dynamic signals based on variables (#7204)
c009e0a5a35 is described below
commit c009e0a5a3591835bf187d5099c225fe0cbbd091
Author: abhijithumbe <[email protected]>
AuthorDate: Mon Oct 26 22:04:34 2026 +0530
[incubator-kie-issue-2418] Workflow Engine: Support dynamic signals based
on variables (#7204)
* Workflow Engine: Support dynamic signals based on variables
* License details
* junit test fix
---------
Co-authored-by: abhijithumbe <[email protected]>
---
.../codegen/process/ProcessResourceGenerator.java | 15 +++
.../RestResourceSignalQuarkusTemplate.java | 24 ++++-
.../RestResourceSignalSpringTemplate.java | 13 ++-
.../process/ProcessResourceGeneratorTest.java | 70 ++++++++++++
.../IntermediateCatchEventSignalWithVariable.bpmn2 | 120 +++++++++++++++++++++
.../src/main/resources/dynamicsignals.bpmn | 62 +++++++++++
.../integrationtests/quarkus/SignalProcessIT.java | 53 +++++++++
.../src/main/resources/dynamicsignals.bpmn | 62 +++++++++++
.../springboot/SignalProcessTest.java | 52 +++++++++
.../integrationtests/springboot/TaskTest.java | 2 +-
10 files changed, 470 insertions(+), 3 deletions(-)
diff --git
a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessResourceGenerator.java
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessResourceGenerator.java
index 6657046147d..3a15a4a0c4c 100644
---
a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessResourceGenerator.java
+++
b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessResourceGenerator.java
@@ -295,8 +295,17 @@ public class ProcessResourceGenerator {
.findFirst(MethodDeclaration.class, md ->
md.getNameAsString().equals("signalInstance"))
.orElseThrow(() -> new
NoSuchElementException("signalInstance method not found in
SignalResourceTemplate"));
+ MethodDeclaration dynamicSignalInstanceDeclaration =
signalTemplate
+ .findFirst(MethodDeclaration.class, md ->
md.getNameAsString().equals("dynamicSignalInstance"))
+ .orElseThrow(() -> new
NoSuchElementException("dynamicSignalInstance method not found in
SignalResourceTemplate"));
+
Collection<TriggerMetaData> startSignalTriggers =
getStartSignalTriggers();
+ boolean hasDynamicSignals = signalsMap.keySet()
+ .stream()
+ .filter(Objects::nonNull)
+ .anyMatch(this::isDynamicSignalName);
+
signalsMap.entrySet()
.stream()
.filter(e -> Objects.nonNull(e.getKey()))
@@ -371,7 +380,13 @@ public class ProcessResourceGenerator {
interpolated =
interpolated.replace("$signalPath$", sanitizeName(signalName));
vv.setString(interpolated);
});
+
});
+ if (hasDynamicSignals) {
+ MethodDeclaration dynamicSignal =
dynamicSignalInstanceDeclaration.clone();
+ dynamicSignal.setName(SIGNAL_METHOD_PREFFIX +
"dynamic");
+ template.addMember(dynamicSignal);
+ }
});
}
diff --git
a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSignalQuarkusTemplate.java
b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSignalQuarkusTemplate.java
index 70e7a3c6f3f..8b2a527ad99 100644
---
a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSignalQuarkusTemplate.java
+++
b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSignalQuarkusTemplate.java
@@ -57,4 +57,26 @@ public class $Type$Resource {
return processService.signalProcessInstance(process, id, data,
"$signalName$")
.orElseThrow(() -> new
ClientErrorException(String.format("Process instance %s is not currently
accepting signal '%s'", id, "$signalName$"),
Response.Status.PRECONDITION_FAILED));
}
-}
\ No newline at end of file
+
+ @POST
+ @Path("/{id}/signal/{signalName}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @org.eclipse.microprofile.openapi.annotations.parameters.RequestBody(
+ content =
@org.eclipse.microprofile.openapi.annotations.media.Content(
+ schema =
@org.eclipse.microprofile.openapi.annotations.media.Schema(type =
org.eclipse.microprofile.openapi.annotations.enums.SchemaType.OBJECT)))
+ public $Type$Output dynamicSignalInstance(
+ @PathParam("id") final String id,
+ @PathParam("signalName") final String signalName,
+ final com.fasterxml.jackson.databind.JsonNode data) {
+
+ return processService.signalProcessInstance(
+ process, id, data != null ?
org.kie.kogito.jackson.utils.JsonObjectUtils.toJavaValue(data) : null,
signalName)
+ .orElseThrow(() -> new ClientErrorException(
+ String.format(
+ "Process instance %s is not currently
accepting signal '%s'",
+ id, signalName),
+ Response.Status.PRECONDITION_FAILED));
+ }
+
+}
diff --git
a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSignalSpringTemplate.java
b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSignalSpringTemplate.java
index fb697365da4..09adf804261 100644
---
a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSignalSpringTemplate.java
+++
b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSignalSpringTemplate.java
@@ -59,4 +59,15 @@ public class $Type$Resource {
return processService.signalProcessInstance(process, id, data,
"$signalName$")
.orElseThrow(() -> new
ResponseStatusException(HttpStatus.PRECONDITION_FAILED, String.format("Process
instance %s is not currently accepting signal '%s'", id, "$signalName$")));
}
-}
\ No newline at end of file
+
+ @PostMapping(value = "/{id}/signal/{signalName}", produces =
MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
+ @io.swagger.v3.oas.annotations.parameters.RequestBody(content =
@io.swagger.v3.oas.annotations.media.Content(schema =
@io.swagger.v3.oas.annotations.media.Schema(type = "object")))
+ public $Type$Output dynamicSignalInstance(@PathVariable("id") final String
id,
+ @PathVariable("signalName") final String signalName,
+ final @RequestBody(required = false)
com.fasterxml.jackson.databind.JsonNode data) {
+ return processService.signalProcessInstance(process, id,
+ data != null ?
org.kie.kogito.jackson.utils.JsonObjectUtils.toJavaValue(data) : null,
signalName)
+ .orElseThrow(() -> new
ResponseStatusException(HttpStatus.PRECONDITION_FAILED,
+ String.format("Process instance %s is not currently
accepting signal '%s'", id, signalName)));
+ }
+}
diff --git
a/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/ProcessResourceGeneratorTest.java
b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/ProcessResourceGeneratorTest.java
index 38b17e2daa4..f5f110aa681 100644
---
a/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/ProcessResourceGeneratorTest.java
+++
b/kogito-codegen-modules/kogito-codegen-processes/src/test/java/org/kie/kogito/codegen/process/ProcessResourceGeneratorTest.java
@@ -45,8 +45,10 @@ import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.expr.AnnotationExpr;
import com.github.javaparser.ast.expr.MemberValuePair;
+import com.github.javaparser.ast.expr.NameExpr;
import com.github.javaparser.ast.expr.NormalAnnotationExpr;
import com.github.javaparser.ast.expr.StringLiteralExpr;
@@ -91,6 +93,74 @@ public class ProcessResourceGeneratorTest {
testOpenApiDocumentation(contextBuilder, fileName, expectedSummary,
expectedDescription);
}
+ @ParameterizedTest
+
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
+ void testDynamicSignalEndpointGeneration(KogitoBuildContext.Builder
contextBuilder) {
+ String fileName =
"src/test/resources/signalevent/IntermediateCatchEventSignalWithVariable.bpmn2";
+
+ ClassOrInterfaceDeclaration classDeclaration =
getResourceClassDeclaration(contextBuilder, fileName);
+
+ // 1. No static endpoint for the raw "#{signalName}" literal must be
present.
+ boolean hasRawDynamicEndpoint = classDeclaration.getMethods().stream()
+ .filter(m -> isRestMethod(m) &&
m.getNameAsString().startsWith(SIGNAL_METHOD))
+ .anyMatch(m -> m.toString().contains("#{signalName}"));
+ assertThat(hasRawDynamicEndpoint)
+ .as("No static REST endpoint should be generated for a dynamic
signal name #{signalName}")
+ .isFalse();
+
+ // 2. Exactly one dynamic endpoint (signal_dynamic) must be present.
+ List<MethodDeclaration> dynamicMethods =
classDeclaration.getMethods().stream()
+ .filter(m -> isRestMethod(m) &&
m.getNameAsString().equals(SIGNAL_METHOD + "dynamic"))
+ .toList();
+ assertThat(dynamicMethods)
+ .as("Exactly one dynamic signal endpoint must be generated")
+ .hasSize(1);
+
+ MethodDeclaration dynamicMethod = dynamicMethods.get(0);
+
+ // 3. The method must accept a 'signalName' path parameter.
+ Optional<Parameter> signalNameParam =
dynamicMethod.getParameters().stream()
+ .filter(p -> p.getNameAsString().equals("signalName"))
+ .findFirst();
+ assertThat(signalNameParam)
+ .as("Dynamic signal endpoint must declare a 'signalName' path
parameter")
+ .isPresent();
+
+ // 4. The 'signalName' parameter must carry a path-binding annotation
(e.g. @PathParam or @PathVariable) pointing to "signalName".
+ boolean hasPathAnnotation =
signalNameParam.get().getAnnotations().stream()
+ .anyMatch(a -> {
+ String s = a.toString();
+ return s.contains("signalName");
+ });
+ assertThat(hasPathAnnotation)
+ .as("The 'signalName' path parameter must be annotated with
its path binding (e.g. @PathParam(\"signalName\"))")
+ .isTrue();
+
+ // 5. The endpoint URL path must contain "signal/{signalName}".
+ boolean hasCorrectPath = dynamicMethod.getAnnotations().stream()
+ .anyMatch(a -> a.toString().contains("signal/{signalName}"));
+ assertThat(hasCorrectPath)
+ .as("The dynamic signal endpoint path must contain
'signal/{signalName}'")
+ .isTrue();
+
+ // 6. The method body must pass the 'signalName' variable (not a
string literal) as the signal name argument.
+ boolean hasVariableSignalName = dynamicMethod.getBody()
+ .map(body -> body.findAll(NameExpr.class).stream()
+ .anyMatch(n ->
"signalName".equals(n.getNameAsString())))
+ .orElse(false);
+ assertThat(hasVariableSignalName)
+ .as("The dynamic signal endpoint body must reference the
'signalName' variable, not a literal")
+ .isTrue();
+
+ boolean hasLiteralDynamicSignal = dynamicMethod.getBody()
+ .map(body -> body.findAll(StringLiteralExpr.class).stream()
+ .anyMatch(s -> s.getValue().contains("#{signalName}")))
+ .orElse(false);
+ assertThat(hasLiteralDynamicSignal)
+ .as("The dynamic signal endpoint body must NOT contain a
literal '#{signalName}'")
+ .isFalse();
+ }
+
@ParameterizedTest
@MethodSource("org.kie.kogito.codegen.api.utils.KogitoContextTestUtils#restContextBuilders")
void testGenerateBoundarySignalEventOnTask(KogitoBuildContext.Builder
contextBuilder) {
diff --git
a/kogito-codegen-modules/kogito-codegen-processes/src/test/resources/signalevent/IntermediateCatchEventSignalWithVariable.bpmn2
b/kogito-codegen-modules/kogito-codegen-processes/src/test/resources/signalevent/IntermediateCatchEventSignalWithVariable.bpmn2
new file mode 100644
index 00000000000..c9fa636e0c8
--- /dev/null
+++
b/kogito-codegen-modules/kogito-codegen-processes/src/test/resources/signalevent/IntermediateCatchEventSignalWithVariable.bpmn2
@@ -0,0 +1,120 @@
+<?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.
+ -->
+
+<definitions id="Definition"
+ targetNamespace="http://www.example.org/MinimalExample"
+ typeLanguage="http://www.java.com/javaTypes"
+ expressionLanguage="http://www.mvel.org/2.0"
+ xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL
BPMN20.xsd"
+ xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
+ xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
+ xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
+ xmlns:tns="http://www.jboss.org/drools">
+
+ <signal id="Signal_1" name="#{signalName}"/>
+ <itemDefinition id="_xItem" structureRef="String"/>
+
+ <process processType="Public" isExecutable="true"
+ id="IntermediateCatchEventSignalWithVariable"
+ tns:packageName="org.kie.kogito.codegen.process"
+ name="IntermediateCatchEvent Process">
+
+ <property id="x" itemSubjectRef="_xItem"/>
+ <property id="signalName" itemSubjectRef="_xItem"/>
+
+ <startEvent id="_1" name="StartProcess" isInterrupting="true"/>
+ <userTask id="_2" name="UserTask">
+ <ioSpecification>
+ <dataInput id="_2_NodeNameInput" name="NodeName"/>
+ <inputSet>
+ <dataInputRefs>_2_NodeNameInput</dataInputRefs>
+ </inputSet>
+ <outputSet/>
+ </ioSpecification>
+ <dataInputAssociation>
+ <targetRef>_2_NodeNameInput</targetRef>
+ <assignment>
+ <from xsi:type="tFormalExpression">UserTask</from>
+ <to xsi:type="tFormalExpression">_2_NodeNameInput</to>
+ </assignment>
+ </dataInputAssociation>
+ </userTask>
+ <intermediateCatchEvent id="_4" name="event">
+ <dataOutput id="_4_Output" name="event" dtype="String"/>
+ <dataOutputAssociation>
+ <sourceRef>_4_Output</sourceRef>
+ <targetRef>x</targetRef>
+ </dataOutputAssociation>
+ <outputSet>
+ <dataOutputRefs>_4_Output</dataOutputRefs>
+ </outputSet>
+ <signalEventDefinition signalRef="Signal_1"/>
+ </intermediateCatchEvent>
+ <scriptTask id="_5" name="Event">
+ <script>System.out.println(x);</script>
+ </scriptTask>
+ <endEvent id="_6" name="EndProcess">
+ <terminateEventDefinition/>
+ </endEvent>
+
+ <sequenceFlow id="_1-_2" sourceRef="_1" targetRef="_2"/>
+ <sequenceFlow id="_2-_4" sourceRef="_2" targetRef="_4"/>
+ <sequenceFlow id="_4-_5" sourceRef="_4" targetRef="_5"/>
+ <sequenceFlow id="_5-_6" sourceRef="_5" targetRef="_6"/>
+ </process>
+
+ <bpmndi:BPMNDiagram>
+ <bpmndi:BPMNPlane bpmnElement="IntermediateCatchEventSignalWithVariable">
+ <bpmndi:BPMNShape bpmnElement="_1">
+ <dc:Bounds x="16" y="16" width="48" height="48"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="_2">
+ <dc:Bounds x="96" y="16" width="100" height="48"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="_4">
+ <dc:Bounds x="228" y="16" width="48" height="48"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="_5">
+ <dc:Bounds x="308" y="16" width="100" height="48"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="_6">
+ <dc:Bounds x="440" y="16" width="48" height="48"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge bpmnElement="_1-_2">
+ <di:waypoint x="40" y="40"/>
+ <di:waypoint x="146" y="40"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="_2-_4">
+ <di:waypoint x="146" y="40"/>
+ <di:waypoint x="252" y="40"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="_4-_5">
+ <di:waypoint x="252" y="40"/>
+ <di:waypoint x="358" y="40"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="_5-_6">
+ <di:waypoint x="358" y="40"/>
+ <di:waypoint x="464" y="40"/>
+ </bpmndi:BPMNEdge>
+ </bpmndi:BPMNPlane>
+ </bpmndi:BPMNDiagram>
+</definitions>
diff --git
a/kogito-quarkus/integration-tests/integration-tests-quarkus-processes/src/main/resources/dynamicsignals.bpmn
b/kogito-quarkus/integration-tests/integration-tests-quarkus-processes/src/main/resources/dynamicsignals.bpmn
new file mode 100644
index 00000000000..a38b07c01d8
--- /dev/null
+++
b/kogito-quarkus/integration-tests/integration-tests-quarkus-processes/src/main/resources/dynamicsignals.bpmn
@@ -0,0 +1,62 @@
+<?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.
+ -->
+
+<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
namespace="https://kie.org/bpmn/_A1FD5170-EA8F-47F8-B4FA-1A97B71B6CE7"
id="_80139D11-2182-4568-AF43-680DFF2979E8"
name="BPMN_CE038D3D-C342-44C5-BD86-B0D8D4C55FC2"
targetNamespace="https://kie.apache.org/bpmn/_F6B98217-442F-49C1-A644-A9437E914FA7"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:drools="http://www [...]
+ <itemDefinition id="_29E24C02-87B8-440E-A3AF-BCAEF9817D43"
structureRef="String" />
+ <signal id="_6C15940C-1FAD-4FC4-8E3C-77D2B095A85C"
structureRef="Signal__7475CADType" name="Signal__7475CAD" />
+ <signal id="_9FA27321-CCE3-4AEA-A52C-05936C76E174"
structureRef="#{signalName}Type" name="#{signalName}" />
+ <process id="dynamicsignals" isExecutable="true" drools:adHoc="false">
+ <property id="_5BCF3659-529E-4252-80A1-F85D3ADA8892" name="signalName"
itemSubjectRef="_29E24C02-87B8-440E-A3AF-BCAEF9817D43" />
+ <startEvent id="_F2564FE8-DC72-4EF0-BA6A-4893B440142D">
+ <outgoing>_5C398F21-FE3A-461D-91E4-12C176D1A943</outgoing>
+ </startEvent>
+ <endEvent id="_03B9E669-316C-4C7F-9C01-70F7B3E6CC30">
+ <incoming>_1AF4860E-3543-4150-9F3C-0A733C462DBF</incoming>
+ </endEvent>
+ <intermediateCatchEvent id="_B6C99B5C-BBEA-4EB6-AF20-05D96459A3DF">
+ <incoming>_5C398F21-FE3A-461D-91E4-12C176D1A943</incoming>
+ <outgoing>_1AF4860E-3543-4150-9F3C-0A733C462DBF</outgoing>
+ <signalEventDefinition id="_1918C241-250A-433F-961A-1EC367A6E57B"
signalRef="_9FA27321-CCE3-4AEA-A52C-05936C76E174" />
+ </intermediateCatchEvent>
+ <sequenceFlow id="_5C398F21-FE3A-461D-91E4-12C176D1A943"
sourceRef="_F2564FE8-DC72-4EF0-BA6A-4893B440142D"
targetRef="_B6C99B5C-BBEA-4EB6-AF20-05D96459A3DF" />
+ <sequenceFlow id="_1AF4860E-3543-4150-9F3C-0A733C462DBF"
sourceRef="_B6C99B5C-BBEA-4EB6-AF20-05D96459A3DF"
targetRef="_03B9E669-316C-4C7F-9C01-70F7B3E6CC30" />
+ </process>
+ <bpmndi:BPMNDiagram id="_51A77CDD-394B-469E-8B58-59274F2D1C82">
+ <bpmndi:BPMNPlane id="_C2409FC5-458B-48DA-9E77-E967871E613E">
+ <bpmndi:BPMNShape id="_8899893D-C39B-4466-BA82-6AA44A1DDCC2"
bpmnElement="_F2564FE8-DC72-4EF0-BA6A-4893B440142D">
+ <dc:Bounds x="20" y="120" width="60" height="60" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="_962E7A08-674D-40A5-A8C8-FAF1D30FB26A"
bpmnElement="_B6C99B5C-BBEA-4EB6-AF20-05D96459A3DF">
+ <dc:Bounds x="180" y="120" width="60" height="60" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="_1E1484E7-92B6-4AF8-89A7-37908044B8AA"
bpmnElement="_03B9E669-316C-4C7F-9C01-70F7B3E6CC30">
+ <dc:Bounds x="340" y="120" width="60" height="60" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge
id="_4C31AAE7-31E4-4CE0-ABBE-040A4B2D2A0B-AUTO-SOURCE-AUTO-TARGET"
bpmnElement="_5C398F21-FE3A-461D-91E4-12C176D1A943"
sourceElement="_8899893D-C39B-4466-BA82-6AA44A1DDCC2"
targetElement="_962E7A08-674D-40A5-A8C8-FAF1D30FB26A">
+ <di:waypoint x="50" y="150" />
+ <di:waypoint x="210" y="150" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge
id="_E9926657-64A9-4D00-A407-FD1BD5CAFEFD-AUTO-SOURCE-AUTO-TARGET"
bpmnElement="_1AF4860E-3543-4150-9F3C-0A733C462DBF"
sourceElement="_962E7A08-674D-40A5-A8C8-FAF1D30FB26A"
targetElement="_1E1484E7-92B6-4AF8-89A7-37908044B8AA">
+ <di:waypoint x="210" y="150" />
+ <di:waypoint x="370" y="150" />
+ </bpmndi:BPMNEdge>
+ </bpmndi:BPMNPlane>
+ </bpmndi:BPMNDiagram>
+</definitions>
diff --git
a/kogito-quarkus/integration-tests/integration-tests-quarkus-processes/src/test/java/org/kie/kogito/integrationtests/quarkus/SignalProcessIT.java
b/kogito-quarkus/integration-tests/integration-tests-quarkus-processes/src/test/java/org/kie/kogito/integrationtests/quarkus/SignalProcessIT.java
index 2dfe5aa0ab0..10cdd6e2528 100644
---
a/kogito-quarkus/integration-tests/integration-tests-quarkus-processes/src/test/java/org/kie/kogito/integrationtests/quarkus/SignalProcessIT.java
+++
b/kogito-quarkus/integration-tests/integration-tests-quarkus-processes/src/test/java/org/kie/kogito/integrationtests/quarkus/SignalProcessIT.java
@@ -311,4 +311,57 @@ class SignalProcessIT {
.statusCode(200)
.body("var1", not(nullValue()));
}
+
+ @Test
+ void testDynamicSignalEndpoint() {
+ // Given: Process instance waiting for dynamic signal "Approved"
+ String pid = given()
+ .contentType(ContentType.JSON)
+ .body("{\"signalName\":\"Approved\"}")
+ .when()
+ .post("/dynamicsignals")
+ .then()
+ .statusCode(201)
+ .body("id", not(emptyOrNullString()))
+ .extract()
+ .path("id");
+
+ // When: Send an incorrect dynamic signal
+ // Then: Should return 412 as the process is not accepting this signal
+ given()
+ .contentType(ContentType.JSON)
+ .body("{}")
+ .when()
+ .post("/dynamicsignals/{pid}/signal/{signalName}", pid,
"Rejected")
+ .then()
+ .statusCode(412);
+
+ // Then: Process instance should still be active and waiting for
"Approved"
+ given()
+ .contentType(ContentType.JSON)
+ .when()
+ .get("/dynamicsignals/{pid}", pid)
+ .then()
+ .statusCode(200)
+ .body("signalName", is("Approved"));
+
+ // When: Send the correct dynamic signal "Approved"
+ // Then: Signal should be accepted and process should complete
+ given()
+ .contentType(ContentType.JSON)
+ .body("{}")
+ .when()
+ .post("/dynamicsignals/{pid}/signal/{signalName}", pid,
"Approved")
+ .then()
+ .statusCode(200);
+
+ // Then: Completed process instance should no longer be available
+ given()
+ .contentType(ContentType.JSON)
+ .when()
+ .get("/dynamicsignals/{pid}", pid)
+ .then()
+ .statusCode(404);
+ }
+
}
diff --git
a/kogito-springboot/integration-tests/integration-tests-springboot-processes-it/src/main/resources/dynamicsignals.bpmn
b/kogito-springboot/integration-tests/integration-tests-springboot-processes-it/src/main/resources/dynamicsignals.bpmn
new file mode 100644
index 00000000000..be7368328bb
--- /dev/null
+++
b/kogito-springboot/integration-tests/integration-tests-springboot-processes-it/src/main/resources/dynamicsignals.bpmn
@@ -0,0 +1,62 @@
+<?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.
+ -->
+
+<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
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"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
namespace="https://kie.org/bpmn/_A1FD5170-EA8F-47F8-B4FA-1A97B71B6CE7"
id="_80139D11-2182-4568-AF43-680DFF2979E8"
name="BPMN_CE038D3D-C342-44C5-BD86-B0D8D4C55FC2" targetNames [...]
+ <itemDefinition id="_29E24C02-87B8-440E-A3AF-BCAEF9817D43"
structureRef="String" />
+ <signal id="_6C15940C-1FAD-4FC4-8E3C-77D2B095A85C"
structureRef="Signal__7475CADType" name="Signal__7475CAD" />
+ <signal id="_9FA27321-CCE3-4AEA-A52C-05936C76E174"
structureRef="#{signalName}Type" name="#{signalName}" />
+ <process id="dynamicsignals" isExecutable="true" drools:adHoc="false"
drools:packageName="org.acme.travels">
+ <property id="_5BCF3659-529E-4252-80A1-F85D3ADA8892" name="signalName"
itemSubjectRef="_29E24C02-87B8-440E-A3AF-BCAEF9817D43" />
+ <startEvent id="_F2564FE8-DC72-4EF0-BA6A-4893B440142D">
+ <outgoing>_5C398F21-FE3A-461D-91E4-12C176D1A943</outgoing>
+ </startEvent>
+ <endEvent id="_03B9E669-316C-4C7F-9C01-70F7B3E6CC30">
+ <incoming>_1AF4860E-3543-4150-9F3C-0A733C462DBF</incoming>
+ </endEvent>
+ <intermediateCatchEvent id="_B6C99B5C-BBEA-4EB6-AF20-05D96459A3DF">
+ <incoming>_5C398F21-FE3A-461D-91E4-12C176D1A943</incoming>
+ <outgoing>_1AF4860E-3543-4150-9F3C-0A733C462DBF</outgoing>
+ <signalEventDefinition id="_1918C241-250A-433F-961A-1EC367A6E57B"
signalRef="_9FA27321-CCE3-4AEA-A52C-05936C76E174" />
+ </intermediateCatchEvent>
+ <sequenceFlow id="_5C398F21-FE3A-461D-91E4-12C176D1A943"
sourceRef="_F2564FE8-DC72-4EF0-BA6A-4893B440142D"
targetRef="_B6C99B5C-BBEA-4EB6-AF20-05D96459A3DF" />
+ <sequenceFlow id="_1AF4860E-3543-4150-9F3C-0A733C462DBF"
sourceRef="_B6C99B5C-BBEA-4EB6-AF20-05D96459A3DF"
targetRef="_03B9E669-316C-4C7F-9C01-70F7B3E6CC30" />
+ </process>
+ <bpmndi:BPMNDiagram id="_51A77CDD-394B-469E-8B58-59274F2D1C82">
+ <bpmndi:BPMNPlane id="_C2409FC5-458B-48DA-9E77-E967871E613E">
+ <bpmndi:BPMNShape id="_8899893D-C39B-4466-BA82-6AA44A1DDCC2"
bpmnElement="_F2564FE8-DC72-4EF0-BA6A-4893B440142D">
+ <dc:Bounds x="20" y="120" width="60" height="60" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="_962E7A08-674D-40A5-A8C8-FAF1D30FB26A"
bpmnElement="_B6C99B5C-BBEA-4EB6-AF20-05D96459A3DF">
+ <dc:Bounds x="180" y="120" width="60" height="60" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape id="_1E1484E7-92B6-4AF8-89A7-37908044B8AA"
bpmnElement="_03B9E669-316C-4C7F-9C01-70F7B3E6CC30">
+ <dc:Bounds x="340" y="120" width="60" height="60" />
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNEdge
id="_4C31AAE7-31E4-4CE0-ABBE-040A4B2D2A0B-AUTO-SOURCE-AUTO-TARGET"
bpmnElement="_5C398F21-FE3A-461D-91E4-12C176D1A943"
sourceElement="_8899893D-C39B-4466-BA82-6AA44A1DDCC2"
targetElement="_962E7A08-674D-40A5-A8C8-FAF1D30FB26A">
+ <di:waypoint x="50" y="150" />
+ <di:waypoint x="210" y="150" />
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge
id="_E9926657-64A9-4D00-A407-FD1BD5CAFEFD-AUTO-SOURCE-AUTO-TARGET"
bpmnElement="_1AF4860E-3543-4150-9F3C-0A733C462DBF"
sourceElement="_962E7A08-674D-40A5-A8C8-FAF1D30FB26A"
targetElement="_1E1484E7-92B6-4AF8-89A7-37908044B8AA">
+ <di:waypoint x="210" y="150" />
+ <di:waypoint x="370" y="150" />
+ </bpmndi:BPMNEdge>
+ </bpmndi:BPMNPlane>
+ </bpmndi:BPMNDiagram>
+</definitions>
diff --git
a/kogito-springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/SignalProcessTest.java
b/kogito-springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/SignalProcessTest.java
index 4f91ec85330..6285eb82b9f 100644
---
a/kogito-springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/SignalProcessTest.java
+++
b/kogito-springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/SignalProcessTest.java
@@ -314,4 +314,56 @@ class SignalProcessTest extends BaseRestTest {
.statusCode(200)
.body("var1", not(nullValue()));
}
+
+ @Test
+ void testDynamicSignalEndpoint() {
+ // Given: Process instance waiting for dynamic signal "Approved"
+ String pid = given()
+ .contentType(ContentType.JSON)
+ .body("{\"signalName\":\"Approved\"}")
+ .when()
+ .post("/dynamicsignals")
+ .then()
+ .statusCode(201)
+ .body("id", not(emptyOrNullString()))
+ .extract()
+ .path("id");
+
+ // When: Send an incorrect dynamic signal
+ // Then: Should return 412 as the process is not accepting this signal
+ given()
+ .contentType(ContentType.JSON)
+ .body("{}")
+ .when()
+ .post("/dynamicsignals/{pid}/signal/{signalName}", pid,
"Rejected")
+ .then()
+ .statusCode(412);
+
+ // Then: Process instance should still be active and waiting for
"Approved"
+ given()
+ .contentType(ContentType.JSON)
+ .when()
+ .get("/dynamicsignals/{pid}", pid)
+ .then()
+ .statusCode(200)
+ .body("signalName", is("Approved"));
+
+ // When: Send the correct dynamic signal "Approved"
+ // Then: Signal should be accepted and process should complete
+ given()
+ .contentType(ContentType.JSON)
+ .body("{}")
+ .when()
+ .post("/dynamicsignals/{pid}/signal/{signalName}", pid,
"Approved")
+ .then()
+ .statusCode(200);
+
+ // Then: Completed process instance should no longer be available
+ given()
+ .contentType(ContentType.JSON)
+ .when()
+ .get("/dynamicsignals/{pid}", pid)
+ .then()
+ .statusCode(404);
+ }
}
\ No newline at end of file
diff --git
a/kogito-springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/TaskTest.java
b/kogito-springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/TaskTest.java
index 3d6f87a3970..51129c4bfb9 100644
---
a/kogito-springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/TaskTest.java
+++
b/kogito-springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/TaskTest.java
@@ -108,7 +108,7 @@ public class TaskTest extends BaseRestTest {
@Test
void testJsonSchemaFiles() {
- long expectedJsonSchemas = 34;
+ long expectedJsonSchemas = 35;
Path jsonDir = Paths.get("target",
"classes").resolve(JsonSchemaUtil.getJsonDir());
try (Stream<Path> paths = Files.walk(jsonDir)) {
long generatedJsonSchemas = paths
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]