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]

Reply via email to