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 aafb1339d3 [incubator-kie-issues#2239] Process compilation fails if
process has event subprocess with TimerStartEvent (#4184)
aafb1339d3 is described below
commit aafb1339d3c7fd885a0ad4ab034344bd74588e50
Author: Abhiram Gundala <[email protected]>
AuthorDate: Mon Feb 9 09:08:40 2026 -0500
[incubator-kie-issues#2239] Process compilation fails if process has event
subprocess with TimerStartEvent (#4184)
* Added trigger and migrated testEventSubprocessTimer
* Added null check
* Migrated testEventSubprocessTimerCycle
---
.../canonical/EventSubProcessNodeVisitor.java | 15 +++++
.../jbpm/compiler/canonical/StartNodeVisitor.java | 8 +++
.../core/factory/EventSubProcessNodeFactory.java | 13 ++++
.../instance/node/StateBasedNodeInstance.java | 5 +-
.../java/org/jbpm/bpmn2/IntermediateEventTest.java | 76 ++++++++++++----------
5 files changed, 82 insertions(+), 35 deletions(-)
diff --git
a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/EventSubProcessNodeVisitor.java
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/EventSubProcessNodeVisitor.java
index 5c468afc3c..4be279cb82 100644
---
a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/EventSubProcessNodeVisitor.java
+++
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/EventSubProcessNodeVisitor.java
@@ -23,15 +23,19 @@ import java.util.Collection;
import java.util.stream.Stream;
import org.jbpm.process.core.context.variable.VariableScope;
+import org.jbpm.process.core.timer.Timer;
import org.jbpm.ruleflow.core.factory.EventSubProcessNodeFactory;
import org.jbpm.workflow.core.node.EventSubProcessNode;
+import org.jbpm.workflow.core.node.StartNode;
import com.github.javaparser.ast.expr.BooleanLiteralExpr;
+import com.github.javaparser.ast.expr.IntegerLiteralExpr;
import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.ast.expr.StringLiteralExpr;
import static
org.jbpm.ruleflow.core.factory.EventSubProcessNodeFactory.METHOD_EVENT;
import static
org.jbpm.ruleflow.core.factory.EventSubProcessNodeFactory.METHOD_KEEP_ACTIVE;
+import static
org.jbpm.ruleflow.core.factory.EventSubProcessNodeFactory.METHOD_TIMER;
public class EventSubProcessNodeVisitor extends
CompositeContextNodeVisitor<EventSubProcessNode> {
@@ -60,6 +64,17 @@ public class EventSubProcessNodeVisitor extends
CompositeContextNodeVisitor<Even
methods.add(getFactoryMethod(getNodeId(node), METHOD_KEEP_ACTIVE, new
BooleanLiteralExpr(node.isKeepActive())));
node.getEvents()
.forEach(e -> methods.add(getFactoryMethod(getNodeId(node),
METHOD_EVENT, new StringLiteralExpr(e))));
+
+ StartNode startNode = node.findStartNode();
+ if (startNode != null && startNode.getTimer() != null) {
+ Timer timer = startNode.getTimer();
+ methods.add(getFactoryMethod(getNodeId(node), METHOD_TIMER,
+ getOrNullExpr(timer.getDelay()),
+ getOrNullExpr(timer.getPeriod()),
+ getOrNullExpr(timer.getDate()),
+ new
IntegerLiteralExpr(String.valueOf(timer.getTimeType())).asIntegerLiteralExpr()));
+ }
+
return methods.stream();
}
}
diff --git
a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/StartNodeVisitor.java
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/StartNodeVisitor.java
index 42c0ceb3c8..1fb76d74e1 100644
---
a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/StartNodeVisitor.java
+++
b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/StartNodeVisitor.java
@@ -18,6 +18,7 @@
*/
package org.jbpm.compiler.canonical;
+import java.util.Collections;
import java.util.Map;
import java.util.Optional;
@@ -27,6 +28,7 @@ import org.jbpm.process.core.context.variable.VariableScope;
import org.jbpm.process.core.timer.Timer;
import org.jbpm.ruleflow.core.Metadata;
import org.jbpm.ruleflow.core.factory.StartNodeFactory;
+import org.jbpm.workflow.core.node.EventSubProcessNode;
import org.jbpm.workflow.core.node.StartNode;
import com.github.javaparser.ast.NodeList;
@@ -74,6 +76,12 @@ public class StartNodeVisitor extends
AbstractNodeVisitor<StartNode> {
getOrNullExpr(timer.getPeriod()),
getOrNullExpr(timer.getDate()),
new
IntegerLiteralExpr(startNode.getTimer().getTimeType())));
+ if (startNode.getParentContainer() instanceof
EventSubProcessNode eventSubProcess) {
+ String triggerEventType = "Timer-" +
eventSubProcess.getId().toExternalFormat();
+ body.addStatement(getFactoryMethod(getNodeId(startNode),
METHOD_TRIGGER,
+ new StringLiteralExpr(triggerEventType),
+ buildDataAssociationsExpression(startNode,
Collections.emptyList())));
+ }
break;
}
case Metadata.EVENT_TYPE_SIGNAL:
diff --git
a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/EventSubProcessNodeFactory.java
b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/EventSubProcessNodeFactory.java
index 46aad92e26..8ce12af6c2 100644
---
a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/EventSubProcessNodeFactory.java
+++
b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/EventSubProcessNodeFactory.java
@@ -19,9 +19,11 @@
package org.jbpm.ruleflow.core.factory;
import org.jbpm.process.core.event.EventTypeFilter;
+import org.jbpm.process.core.timer.Timer;
import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
import org.jbpm.ruleflow.core.RuleFlowProcess;
import org.jbpm.workflow.core.NodeContainer;
+import org.jbpm.workflow.core.impl.DroolsConsequenceAction;
import org.jbpm.workflow.core.node.EventSubProcessNode;
import org.kie.api.definition.process.WorkflowElementIdentifier;
@@ -31,6 +33,7 @@ public class EventSubProcessNodeFactory<T extends
RuleFlowNodeContainerFactory<T
public static final String METHOD_KEEP_ACTIVE = "keepActive";
public static final String METHOD_EVENT = "event";
+ public static final String METHOD_TIMER = "timer";
public EventSubProcessNodeFactory(T nodeContainerFactory, NodeContainer
nodeContainer, WorkflowElementIdentifier id) {
super(nodeContainerFactory, nodeContainer, new EventSubProcessNode(),
id);
@@ -49,4 +52,14 @@ public class EventSubProcessNodeFactory<T extends
RuleFlowNodeContainerFactory<T
((EventSubProcessNode) getCompositeNode()).addEvent(filter);
return this;
}
+
+ public EventSubProcessNodeFactory<T> timer(String delay, String period,
String date, int timeType) {
+ Timer timer = new Timer();
+ timer.setDate(date);
+ timer.setDelay(delay);
+ timer.setPeriod(period);
+ timer.setTimeType(timeType);
+ ((EventSubProcessNode) getCompositeNode()).addTimer(timer, new
DroolsConsequenceAction("java", ""));
+ return this;
+ }
}
diff --git
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/StateBasedNodeInstance.java
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/StateBasedNodeInstance.java
index fab2a6bf67..b6a4c21197 100755
---
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/StateBasedNodeInstance.java
+++
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/StateBasedNodeInstance.java
@@ -311,7 +311,10 @@ public abstract class StateBasedNodeInstance extends
ExtendedNodeInstanceImpl im
timerInstancesReference.remove(timerInstance.getId());
}
}
- executeAction((Action) entry.getValue().getMetaData("Action"));
+ Action action = (Action)
entry.getValue().getMetaData("Action");
+ if (action != null) {
+ executeAction(action);
+ }
return;
}
}
diff --git
a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/IntermediateEventTest.java
b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/IntermediateEventTest.java
index c175c0c388..e37982d5aa 100755
--- a/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/IntermediateEventTest.java
+++ b/jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/IntermediateEventTest.java
@@ -110,10 +110,7 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
-import org.kie.api.event.process.ProcessCompletedEvent;
-import org.kie.api.event.process.ProcessNodeLeftEvent;
-import org.kie.api.event.process.ProcessNodeTriggeredEvent;
-import org.kie.api.event.process.ProcessStartedEvent;
+import org.kie.api.event.process.*;
import org.kie.api.runtime.rule.FactHandle;
import org.kie.kogito.Application;
import org.kie.kogito.event.impl.MessageProducer;
@@ -136,7 +133,7 @@ import
org.kie.kogito.process.workitems.impl.DefaultKogitoWorkItemHandler;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIterable;
import static
org.jbpm.workflow.instance.node.TimerNodeInstance.TIMER_TRIGGERED_EVENT;
-import static org.junit.jupiter.api.Assertions.fail;
+import static org.junit.jupiter.api.Assertions.*;
public class IntermediateEventTest extends JbpmBpmn2TestCase {
@@ -873,60 +870,69 @@ public class IntermediateEventTest extends
JbpmBpmn2TestCase {
}
@Test
+ @Timeout(10)
public void testEventSubprocessTimer() throws Exception {
+ Application app = ProcessTestHelper.newApplication();
NodeLeftCountDownProcessEventListener countDownListener = new
NodeLeftCountDownProcessEventListener(
"Script Task 1", 1);
- kruntime =
createKogitoProcessRuntime("org/jbpm/bpmn2/intermediate/BPMN2-EventSubprocessTimer.bpmn2");
-
- kruntime.getProcessEventManager().addEventListener(countDownListener);
-
+ EventTrackerProcessListener nodeTriggeredProcessEventListener = new
EventTrackerProcessListener();
TestWorkItemHandler workItemHandler = new TestWorkItemHandler();
- kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human
Task", workItemHandler);
- KogitoProcessInstance processInstance =
kruntime.startProcess("EventSubprocessTimer");
- assertProcessInstanceActive(processInstance);
+ ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler);
+ ProcessTestHelper.registerProcessEventListener(app, countDownListener);
+ ProcessTestHelper.registerProcessEventListener(app,
nodeTriggeredProcessEventListener);
- Set<EventDescription<?>> eventDescriptions =
processInstance.getEventDescriptions();
+ org.kie.kogito.process.Process<EventSubprocessTimerModel> definition =
EventSubprocessTimerProcess.newProcess(app);
+ org.kie.kogito.process.ProcessInstance<EventSubprocessTimerModel>
instance = definition.createInstance(definition.createModel());
+ instance.start();
+
+
assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ACTIVE);
+ Set<EventDescription<?>> eventDescriptions = instance.events();
assertThat(eventDescriptions).hasSize(2).extracting("event").contains("workItemCompleted",
TIMER_TRIGGERED_EVENT);
assertThat(eventDescriptions).extracting("eventType").contains("workItem",
"timer");
-
assertThat(eventDescriptions).extracting("processInstanceId").contains(processInstance.getStringId());
+
assertThat(eventDescriptions).extracting("processInstanceId").contains(instance.id());
assertThat(eventDescriptions).filteredOn("eventType",
"timer").hasSize(1).extracting("properties", Map.class)
.anyMatch(m -> m.containsKey("TimerID") &&
m.containsKey("Delay"));
+
countDownListener.waitTillCompleted();
- eventDescriptions = processInstance.getEventDescriptions();
+ eventDescriptions = instance.events();
assertThat(eventDescriptions).hasSize(1).extracting("event").contains("workItemCompleted");
assertThat(eventDescriptions).extracting("eventType").contains("workItem");
-
assertThat(eventDescriptions).extracting("processInstanceId").contains(processInstance.getStringId());
+
assertThat(eventDescriptions).extracting("processInstanceId").contains(instance.id());
KogitoWorkItem workItem = workItemHandler.getWorkItem();
assertThat(workItem).isNotNull();
-
kruntime.getKogitoWorkItemManager().completeWorkItem(workItem.getStringId(),
null);
- assertProcessInstanceFinished(processInstance, kruntime);
- assertNodeTriggered(processInstance.getStringId(), "start", "User Task
1", "end", "Sub Process 1", "start-sub",
- "Script Task 1", "end-sub");
+ ProcessTestHelper.completeWorkItem(instance, Collections.emptyMap(),
"john");
+
assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED);
+ List<String> trackedNodes =
nodeTriggeredProcessEventListener.tracked().stream()
+ .map(node -> node.getNodeInstance().getNodeName()).toList();
+ assertTrue(trackedNodes.containsAll(List.of("start", "User Task 1",
"end", "Sub Process 1", "start-sub",
+ "Script Task 1", "end-sub")));
}
@Test
- @RequirePersistence
public void testEventSubprocessTimerCycle() throws Exception {
+ Application app = ProcessTestHelper.newApplication();
NodeLeftCountDownProcessEventListener countDownListener = new
NodeLeftCountDownProcessEventListener(
"Script Task 1", 4);
-
- kruntime =
createKogitoProcessRuntime("org/jbpm/bpmn2/intermediate/BPMN2-EventSubprocessTimerCycle.bpmn2");
- kruntime.getProcessEventManager().addEventListener(countDownListener);
-
+ EventTrackerProcessListener nodeTriggeredProcessEventListener = new
EventTrackerProcessListener();
TestWorkItemHandler workItemHandler = new TestWorkItemHandler();
- kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Human
Task", workItemHandler);
- KogitoProcessInstance processInstance =
kruntime.startProcess("EventSubprocessTimerCycle");
- assertProcessInstanceActive(processInstance);
+ ProcessTestHelper.registerHandler(app, "Human Task", workItemHandler);
+ ProcessTestHelper.registerProcessEventListener(app, countDownListener);
+ ProcessTestHelper.registerProcessEventListener(app,
nodeTriggeredProcessEventListener);
- Set<EventDescription<?>> eventDescriptions =
processInstance.getEventDescriptions();
+ org.kie.kogito.process.Process<EventSubprocessTimerCycleModel>
definition = EventSubprocessTimerCycleProcess.newProcess(app);
+ org.kie.kogito.process.ProcessInstance<EventSubprocessTimerCycleModel>
instance = definition.createInstance(definition.createModel());
+ instance.start();
+
+
assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_ACTIVE);
+ Set<EventDescription<?>> eventDescriptions = instance.events();
assertThat(eventDescriptions).hasSize(2).extracting("event").contains("workItemCompleted",
TIMER_TRIGGERED_EVENT);
assertThat(eventDescriptions).extracting("eventType").contains("workItem",
"timer");
-
assertThat(eventDescriptions).extracting("processInstanceId").contains(processInstance.getStringId());
+
assertThat(eventDescriptions).extracting("processInstanceId").contains(instance.id());
assertThat(eventDescriptions).filteredOn("eventType",
"timer").hasSize(1).extracting("properties", Map.class)
.anyMatch(m -> m.containsKey("TimerID") &&
m.containsKey("Period"));
@@ -934,11 +940,13 @@ public class IntermediateEventTest extends
JbpmBpmn2TestCase {
KogitoWorkItem workItem = workItemHandler.getWorkItem();
assertThat(workItem).isNotNull();
-
kruntime.getKogitoWorkItemManager().completeWorkItem(workItem.getStringId(),
null);
- assertProcessInstanceFinished(processInstance, kruntime);
- assertNodeTriggered(processInstance.getStringId(), "start", "User Task
1", "end", "start-sub", "Script Task 1",
- "end-sub");
+ ProcessTestHelper.completeWorkItem(instance, Collections.emptyMap(),
"john");
+
assertThat(instance.status()).isEqualTo(org.kie.kogito.process.ProcessInstance.STATE_COMPLETED);
+ List<String> trackedNodes =
nodeTriggeredProcessEventListener.tracked().stream()
+ .map(node -> node.getNodeInstance().getNodeName()).toList();
+ assertTrue(trackedNodes.containsAll(List.of("start", "User Task 1",
"end", "Sub Process 1", "start-sub",
+ "Script Task 1", "end-sub")));
}
@Test
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]