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 3e79d5ddae [incubator-kie-issues#1975] Provide mechanism to fetch the 
list of timers associated to a Process Instance. (#3933)
3e79d5ddae is described below

commit 3e79d5ddae315719ac675623b0b4b3996b195356
Author: Pere Fernández <[email protected]>
AuthorDate: Tue May 27 09:27:35 2025 +0200

    [incubator-kie-issues#1975] Provide mechanism to fetch the list of timers 
associated to a Process Instance. (#3933)
    
    * [incubator-kie-issues#1975] Provide mechanism to fetch the list of timers 
associated to a Process Instance.
    
    * - fixes
    
    * - fixes
    
    * - IT test fix
    
    * - Fixed validations & improved testing
    
    * - moving timers to default implementation
---
 .../BaseProcessInstanceManagementResource.java     |  22 ++-
 .../management/ProcessInstanceManagement.java      |   4 +
 .../BaseProcessInstanceManagementResourceTest.java |  17 ++
 .../process/runtime/KogitoNodeInstance.java        |  14 +-
 .../runtime/KogitoWorkflowProcessInstance.java     |   8 +
 .../main/java/org/kie/kogito/jobs/JobsService.java |   3 +-
 .../java/org/kie/kogito/jobs/TimerDescription.java | 103 ++++++++++++
 .../org/kie/kogito/process/ProcessInstance.java    |   3 +
 .../java/org/jbpm/bpmn2/xml/ProcessHandler.java    |  11 ++
 .../java/org/jbpm/process/core/timer/Timer.java    |  14 +-
 .../jbpm/ruleflow/core/RuleFlowProcessFactory.java |  11 ++
 .../workflow/core/node/AsyncEventNodeInstance.java |  21 +++
 .../workflow/instance/impl/NodeInstanceImpl.java   |   7 +-
 .../instance/impl/WorkflowProcessInstanceImpl.java |  26 +++
 .../workflow/instance/node/EventNodeInstance.java  |  27 +++-
 .../instance/node/StateBasedNodeInstance.java      |  51 ++++--
 .../workflow/instance/node/TimerNodeInstance.java  |  24 ++-
 .../process/impl/AbstractProcessInstance.java      |  12 +-
 .../src/main/resources/timers.bpmn                 | 178 +++++++++++++++++++++
 .../quarkus/workflows/ProcessManagementIT.java     | 109 +++++++++++++
 .../ProcessInstanceManagementResource.java         |  16 ++
 .../ProcessInstanceManagementRestController.java   |  13 ++
 .../src/main/resources/timers.bpmn                 | 178 +++++++++++++++++++++
 .../springboot/ManagementAddOnTest.java            |  76 ++++++++-
 .../integrationtests/springboot/TaskTest.java      |   2 +-
 25 files changed, 902 insertions(+), 48 deletions(-)

diff --git 
a/addons/common/process-management/src/main/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResource.java
 
b/addons/common/process-management/src/main/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResource.java
index 727ccebfb9..5501fc494f 100644
--- 
a/addons/common/process-management/src/main/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResource.java
+++ 
b/addons/common/process-management/src/main/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResource.java
@@ -18,10 +18,7 @@
  */
 package org.kie.kogito.process.management;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
+import java.util.*;
 import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
@@ -31,6 +28,7 @@ import org.jbpm.workflow.core.Node;
 import org.jbpm.workflow.core.WorkflowProcess;
 import org.kie.kogito.Application;
 import org.kie.kogito.Model;
+import org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
 import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcess;
 import org.kie.kogito.process.Process;
 import org.kie.kogito.process.ProcessError;
@@ -227,6 +225,22 @@ public abstract class 
BaseProcessInstanceManagementResource<T> implements Proces
         });
     }
 
+    public T doGetProcessInstanceTimers(String processId, String 
processInstanceId) {
+        return executeOnProcessInstance(processId, processInstanceId, 
processInstance -> buildOkResponse(processInstance.timers()));
+    }
+
+    public T doGetNodeInstanceTimers(String processId, String 
processInstanceId, String nodeInstanceId) {
+        return executeOnProcessInstance(processId, processInstanceId, 
processInstance -> {
+            Collection<KogitoNodeInstance> nodeInstances = 
processInstance.findNodes(nodeInstance -> 
nodeInstance.getId().equals(nodeInstanceId));
+
+            if (nodeInstances.isEmpty()) {
+                return badRequestResponse(String.format("Failure getting 
timers for node instance '%s' from proces instance '%s', node instance couldn't 
be found", nodeInstanceId, processInstanceId));
+            }
+
+            return buildOkResponse(nodeInstances.iterator().next().timers());
+        });
+    }
+
     public T doCancelProcessInstanceId(String processId, String 
processInstanceId) {
 
         return executeOnProcessInstance(processId, processInstanceId, 
processInstance -> {
diff --git 
a/addons/common/process-management/src/main/java/org/kie/kogito/process/management/ProcessInstanceManagement.java
 
b/addons/common/process-management/src/main/java/org/kie/kogito/process/management/ProcessInstanceManagement.java
index 7aa1a5210b..77ae708789 100644
--- 
a/addons/common/process-management/src/main/java/org/kie/kogito/process/management/ProcessInstanceManagement.java
+++ 
b/addons/common/process-management/src/main/java/org/kie/kogito/process/management/ProcessInstanceManagement.java
@@ -30,6 +30,8 @@ public interface ProcessInstanceManagement<T> {
 
     T getWorkItemsInProcessInstance(String processId, String 
processInstanceId);
 
+    T getProcessInstanceTimers(String processId, String processInstanceId);
+
     T retriggerInstanceInError(String processId, String processInstanceId);
 
     T skipInstanceInError(String processId, String processInstanceId);
@@ -40,6 +42,8 @@ public interface ProcessInstanceManagement<T> {
 
     T cancelNodeInstanceId(String processId, String processInstanceId, String 
nodeInstanceId);
 
+    T getNodeInstanceTimers(String processId, String processInstanceId, String 
nodeInstanceId);
+
     T cancelProcessInstanceId(String processId, String processInstanceId);
 
     T migrateAllInstances(String processId, ProcessMigrationSpec 
migrationSpec);
diff --git 
a/addons/common/process-management/src/test/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResourceTest.java
 
b/addons/common/process-management/src/test/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResourceTest.java
index 154bb46308..199d33bd27 100644
--- 
a/addons/common/process-management/src/test/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResourceTest.java
+++ 
b/addons/common/process-management/src/test/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResourceTest.java
@@ -125,6 +125,7 @@ class BaseProcessInstanceManagementResourceTest {
         lenient().when(processInstance.variables()).thenReturn(variables);
         lenient().when(processInstance.id()).thenReturn(PROCESS_INSTANCE_ID);
         
lenient().when(processInstance.status()).thenReturn(ProcessInstance.STATE_ERROR);
+        lenient().when(processInstance.timers()).thenReturn(List.of());
         lenient().when(error.failedNodeId()).thenReturn(NODE_ID_ERROR);
         lenient().when(error.errorMessage()).thenReturn("Test error message");
         lenient().when(application.unitOfWorkManager()).thenReturn(new 
DefaultUnitOfWorkManager(new CollectingUnitOfWorkFactory()));
@@ -161,6 +162,11 @@ class BaseProcessInstanceManagementResourceTest {
                 return null;
             }
 
+            @Override
+            public Object getProcessInstanceTimers(String processId, String 
processInstanceId) {
+                return null;
+            }
+
             @Override
             public Object retriggerInstanceInError(String processId, String 
processInstanceId) {
                 return null;
@@ -181,6 +187,11 @@ class BaseProcessInstanceManagementResourceTest {
                 return null;
             }
 
+            @Override
+            public Object getNodeInstanceTimers(String processId, String 
processInstanceId, String nodeInstanceId) {
+                return null;
+            }
+
             @Override
             public Object cancelNodeInstanceId(String processId, String 
processInstanceId, String nodeInstanceId) {
                 return null;
@@ -339,4 +350,10 @@ class BaseProcessInstanceManagementResourceTest {
         verify(processInstance, times(1)).abort();
         assertResultOk(response);
     }
+
+    @Test
+    void testGetProcessInstanceTimers() {
+        Object response = tested.doGetProcessInstanceTimers(PROCESS_ID, 
PROCESS_INSTANCE_ID);
+        verify(processInstance, times(1)).timers();
+    }
 }
diff --git 
a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoNodeInstance.java
 
b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoNodeInstance.java
index fc6e46a190..3af349fef7 100644
--- 
a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoNodeInstance.java
+++ 
b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoNodeInstance.java
@@ -18,11 +18,10 @@
  */
 package org.kie.kogito.internal.process.runtime;
 
-import java.util.Collections;
-import java.util.Date;
-import java.util.Map;
+import java.util.*;
 
 import org.kie.api.runtime.process.NodeInstance;
+import org.kie.kogito.jobs.TimerDescription;
 
 public interface KogitoNodeInstance extends NodeInstance {
 
@@ -82,4 +81,13 @@ public interface KogitoNodeInstance extends NodeInstance {
      * @return true if this a retrigger node (see above), false otherwise
      */
     boolean isRetrigger();
+
+    /**
+     * Returns the timers associated with this node instance.
+     * 
+     * @return a collection of {@link TimerDescription} instances, never null.
+     */
+    default Collection<TimerDescription> timers() {
+        return new ArrayList<>();
+    }
 }
diff --git 
a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoWorkflowProcessInstance.java
 
b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoWorkflowProcessInstance.java
index 7023cb2890..c4676f2a1c 100644
--- 
a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoWorkflowProcessInstance.java
+++ 
b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoWorkflowProcessInstance.java
@@ -23,6 +23,7 @@ import java.util.Date;
 import java.util.Optional;
 
 import org.kie.api.runtime.process.WorkflowProcessInstance;
+import org.kie.kogito.jobs.TimerDescription;
 import org.kie.kogito.process.flexible.AdHocFragment;
 import org.kie.kogito.process.flexible.Milestone;
 
@@ -85,6 +86,13 @@ public interface KogitoWorkflowProcessInstance extends 
WorkflowProcessInstance,
      */
     Collection<Milestone> milestones();
 
+    /**
+     * Returns the timers associated with the process instance.
+     *
+     * @return a collection of {@link TimerDescription} instances representing 
the timers for the process instance, never null.
+     */
+    Collection<TimerDescription> timers();
+
     /**
      * @return AdHocFragments from the process instances
      */
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/jobs/JobsService.java 
b/api/kogito-api/src/main/java/org/kie/kogito/jobs/JobsService.java
index f953c9a79b..1271afcc54 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/jobs/JobsService.java
+++ b/api/kogito-api/src/main/java/org/kie/kogito/jobs/JobsService.java
@@ -28,8 +28,7 @@ public interface JobsService {
     /**
      * Schedules process job that is responsible for starting new process 
instances
      * based on the given description.
-     * 
-     * @param context of the job
+     *
      * @param description defines what kind of process should be started upon 
expiration time
      * @return returns unique id of the job
      */
diff --git 
a/api/kogito-api/src/main/java/org/kie/kogito/jobs/TimerDescription.java 
b/api/kogito-api/src/main/java/org/kie/kogito/jobs/TimerDescription.java
new file mode 100644
index 0000000000..ee26484c26
--- /dev/null
+++ b/api/kogito-api/src/main/java/org/kie/kogito/jobs/TimerDescription.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.kie.kogito.jobs;
+
+import org.kie.api.runtime.process.NodeInstance;
+import org.kie.api.runtime.process.ProcessInstance;
+
+/**
+ * A description of a timer scheduled either by a ProcessInstance or a 
NodeInstance.
+ */
+public class TimerDescription {
+
+    private final String processId;
+    private final String processInstanceId;
+    private final String nodeInstanceId;
+    private final String timerId;
+    private final String description;
+
+    private TimerDescription(String processId, String processInstanceId, 
String nodeInstanceId, String timerId, String description) {
+        this.processId = processId;
+        this.processInstanceId = processInstanceId;
+        this.nodeInstanceId = nodeInstanceId;
+        this.timerId = timerId;
+        this.description = description;
+    }
+
+    public String getProcessId() {
+        return processId;
+    }
+
+    public String getProcessInstanceId() {
+        return processInstanceId;
+    }
+
+    public String getNodeInstanceId() {
+        return nodeInstanceId;
+    }
+
+    public String getTimerId() {
+        return timerId;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public static class Builder {
+        private final String processId;
+        private final String processInstanceId;
+        private String nodeInstanceId;
+        private String timerId;
+        private String timerDescription;
+
+        private Builder(String processId, String processInstanceId) {
+            this.processId = processId;
+            this.processInstanceId = processInstanceId;
+        }
+
+        private Builder(String processId, String processInstanceId, String 
nodeInstanceId) {
+            this(processId, processInstanceId);
+            this.nodeInstanceId = nodeInstanceId;
+        }
+
+        public static Builder ofProcessInstance(ProcessInstance 
processInstance) {
+            return new Builder(processInstance.getProcessId(), 
processInstance.getId());
+        }
+
+        public static Builder ofNodeInstance(NodeInstance nodeInstance) {
+            return new 
Builder(nodeInstance.getProcessInstance().getProcessId(), 
nodeInstance.getProcessInstance().getId(), nodeInstance.getId());
+        }
+
+        public Builder timerId(String timerId) {
+            this.timerId = timerId;
+            return this;
+        }
+
+        public Builder timerDescription(String timerDescription) {
+            this.timerDescription = timerDescription;
+            return this;
+        }
+
+        public TimerDescription build() {
+            return new TimerDescription(processId, processInstanceId, 
nodeInstanceId, timerId, timerDescription);
+        }
+
+    }
+}
diff --git 
a/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessInstance.java 
b/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessInstance.java
index 384efbb98e..9c5cad75ed 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessInstance.java
+++ b/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessInstance.java
@@ -32,6 +32,7 @@ import 
org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
 import org.kie.kogito.internal.process.workitem.KogitoWorkItem;
 import org.kie.kogito.internal.process.workitem.Policy;
 import org.kie.kogito.internal.process.workitem.WorkItemTransition;
+import org.kie.kogito.jobs.TimerDescription;
 import org.kie.kogito.process.flexible.AdHocFragment;
 import org.kie.kogito.process.flexible.Milestone;
 
@@ -276,6 +277,8 @@ public interface ProcessInstance<T> {
      */
     Collection<Milestone> milestones();
 
+    Collection<TimerDescription> timers();
+
     /**
      * Returns the process adHocFragments
      *
diff --git 
a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/ProcessHandler.java 
b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/ProcessHandler.java
index 72180a45c1..9bd9b04357 100755
--- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/ProcessHandler.java
+++ b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/ProcessHandler.java
@@ -542,6 +542,7 @@ public class ProcessHandler extends BaseAbstractHandler 
implements Handler {
         String timeCycle = (String) node.getMetaData().get("TimeCycle");
         String timeDate = (String) node.getMetaData().get("TimeDate");
         Timer timer = new Timer();
+        timer.setName(concatName(compositeNode.getName(), node.getName()));
         if (timeDuration != null) {
             timer.setDelay(timeDuration);
             timer.setTimeType(Timer.TIME_DURATION);
@@ -584,6 +585,16 @@ public class ProcessHandler extends BaseAbstractHandler 
implements Handler {
         }
     }
 
+    public static String concatName(String prefix, String suffix) {
+        if (prefix == null) {
+            return suffix;
+        } else if (suffix == null) {
+            return prefix;
+        } else {
+            return prefix.concat('-' + suffix);
+        }
+    }
+
     private static void linkBoundaryCompensationEvent(Node node) {
         /**
          * BPMN2 Spec, p. 264:
diff --git 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/timer/Timer.java 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/timer/Timer.java
index a39c59c6c1..e2c0f21fa4 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/timer/Timer.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/timer/Timer.java
@@ -35,6 +35,7 @@ public class Timer implements Serializable {
     private String period;
     private String date;
     private int timeType;
+    private String name;
 
     public long getId() {
         return id;
@@ -68,6 +69,14 @@ public class Timer implements Serializable {
         this.date = date;
     }
 
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
     @Override
     public String toString() {
         return "Timer{" +
@@ -76,6 +85,7 @@ public class Timer implements Serializable {
                 ", period='" + period + '\'' +
                 ", date='" + date + '\'' +
                 ", timeType=" + timeType +
+                ", name='" + name + '\'' +
                 '}';
     }
 
@@ -108,11 +118,11 @@ public class Timer implements Serializable {
         }
         Timer timer = (Timer) o;
         return timeType == timer.timeType && id == timer.id && 
Objects.equals(delay, timer.delay) && Objects.equals(period,
-                timer.period) && Objects.equals(date, timer.date);
+                timer.period) && Objects.equals(date, timer.date) && 
Objects.equals(name, timer.name);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(id, delay, period, date, timeType);
+        return Objects.hash(id, delay, period, date, timeType, name);
     }
 }
diff --git 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/RuleFlowProcessFactory.java
 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/RuleFlowProcessFactory.java
index 2234646210..d9d614e9ca 100755
--- 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/RuleFlowProcessFactory.java
+++ 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/RuleFlowProcessFactory.java
@@ -322,6 +322,7 @@ public class RuleFlowProcessFactory extends 
RuleFlowNodeContainerFactory<RuleFlo
         String timeCycle = (String) node.getMetaData().get(TIME_CYCLE);
         String timeDate = (String) node.getMetaData().get(TIME_DATE);
         Timer timer = new Timer();
+        timer.setName(concatName(compositeNode.getName(), node.getName()));
         if (timeDuration != null) {
             timer.setDelay(timeDuration);
             timer.setTimeType(Timer.TIME_DURATION);
@@ -355,6 +356,16 @@ public class RuleFlowProcessFactory extends 
RuleFlowNodeContainerFactory<RuleFlo
         }
     }
 
+    public static String concatName(String prefix, String suffix) {
+        if (prefix == null) {
+            return suffix;
+        } else if (suffix == null) {
+            return prefix;
+        } else {
+            return prefix.concat('-' + suffix);
+        }
+    }
+
     protected void linkBoundarySignalEvent(Node node, String attachedTo) {
         boolean cancelActivity = (Boolean) 
node.getMetaData().get(CANCEL_ACTIVITY);
         if (cancelActivity) {
diff --git 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/AsyncEventNodeInstance.java
 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/AsyncEventNodeInstance.java
index 59cc4263c8..c21b4f91fd 100644
--- 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/AsyncEventNodeInstance.java
+++ 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/AsyncEventNodeInstance.java
@@ -20,6 +20,7 @@ package org.jbpm.workflow.core.node;
 
 import java.time.ZonedDateTime;
 import java.time.temporal.ChronoUnit;
+import java.util.Collection;
 import java.util.Objects;
 import java.util.Optional;
 
@@ -33,6 +34,7 @@ import 
org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
 import org.kie.kogito.jobs.ExactExpirationTime;
 import org.kie.kogito.jobs.ExpirationTime;
 import org.kie.kogito.jobs.JobsService;
+import org.kie.kogito.jobs.TimerDescription;
 import org.kie.kogito.jobs.descriptors.ProcessInstanceJobDescription;
 import org.kie.kogito.process.ProcessInstance;
 import org.kie.kogito.services.uow.BaseWorkUnit;
@@ -41,6 +43,7 @@ import org.kie.kogito.uow.WorkUnit;
 
 import static org.jbpm.ruleflow.core.Metadata.ASYNC_WAITING;
 import static 
org.jbpm.workflow.instance.node.TimerNodeInstance.TIMER_TRIGGERED_EVENT;
+import static org.kie.kogito.internal.utils.ConversionUtils.isEmpty;
 
 /**
  * Runtime counterpart of an event node.
@@ -162,6 +165,24 @@ public class AsyncEventNodeInstance extends 
EventNodeInstance {
         this.jobId = jobId;
     }
 
+    @Override
+    public Collection<TimerDescription> timers() {
+        if (isEmpty(jobId)) {
+            return super.timers();
+        }
+
+        Collection<TimerDescription> toReturn = super.timers();
+
+        TimerDescription timerDescription = 
TimerDescription.Builder.ofNodeInstance(this)
+                .timerId(this.jobId)
+                .timerDescription(resolveExpression(getNodeName()))
+                .build();
+
+        toReturn.add(timerDescription);
+
+        return toReturn;
+    }
+
     @Override
     public void triggerCompleted() {
         getProcessInstance().removeEventListener(getEventType(), 
getEventListener(), true);
diff --git 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceImpl.java
 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceImpl.java
index b9698aacc2..90083bf58c 100755
--- 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceImpl.java
+++ 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceImpl.java
@@ -19,12 +19,7 @@
 package org.jbpm.workflow.instance.impl;
 
 import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.Map.Entry;
 import java.util.function.Function;
 import java.util.regex.Matcher;
diff --git 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/WorkflowProcessInstanceImpl.java
 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/WorkflowProcessInstanceImpl.java
index 8dc6e80822..106cf6abae 100755
--- 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/WorkflowProcessInstanceImpl.java
+++ 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/WorkflowProcessInstanceImpl.java
@@ -95,6 +95,7 @@ import 
org.kie.kogito.internal.process.runtime.KogitoWorkflowProcess;
 import org.kie.kogito.internal.process.runtime.MessageException;
 import org.kie.kogito.jobs.DurationExpirationTime;
 import org.kie.kogito.jobs.JobsService;
+import org.kie.kogito.jobs.TimerDescription;
 import org.kie.kogito.jobs.descriptors.ProcessInstanceJobDescription;
 import org.kie.kogito.process.BaseEventDescription;
 import org.kie.kogito.process.EventDescription;
@@ -120,6 +121,7 @@ import static 
org.jbpm.ruleflow.core.Metadata.EVENT_TYPE_SIGNAL;
 import static org.jbpm.ruleflow.core.Metadata.IS_FOR_COMPENSATION;
 import static 
org.jbpm.workflow.instance.impl.DummyEventListener.EMPTY_EVENT_LISTENER;
 import static 
org.jbpm.workflow.instance.node.TimerNodeInstance.TIMER_TRIGGERED_EVENT;
+import static org.kie.kogito.internal.utils.ConversionUtils.isNotEmpty;
 import static org.kie.kogito.process.flexible.ItemDescription.Status.ACTIVE;
 import static org.kie.kogito.process.flexible.ItemDescription.Status.AVAILABLE;
 import static org.kie.kogito.process.flexible.ItemDescription.Status.COMPLETED;
@@ -1368,6 +1370,30 @@ public abstract class WorkflowProcessInstanceImpl 
extends ProcessInstanceImpl im
                 .collect(Collectors.toSet());
     }
 
+    @Override
+    public Collection<TimerDescription> timers() {
+
+        List<TimerDescription> toReturn = new ArrayList<>();
+
+        if (isNotEmpty(this.slaTimerId)) {
+            toReturn.add(TimerDescription.Builder.ofProcessInstance(this)
+                    .timerId(slaTimerId)
+                    .timerDescription("[SLA-Process] " + getProcessName())
+                    .build());
+        }
+        if (isNotEmpty(this.cancelTimerId)) {
+            toReturn.add(TimerDescription.Builder.ofProcessInstance(this)
+                    .timerId(cancelTimerId)
+                    .timerDescription("[CANCEL-Process] " + getProcessName())
+                    .build());
+        }
+        getNodeInstances().stream().map(nodeInstance -> (KogitoNodeInstance) 
nodeInstance)
+                .flatMap(nodeInstance -> nodeInstance.timers().stream())
+                .forEach(toReturn::add);
+
+        return toReturn;
+    }
+
     private <N extends org.kie.api.definition.process.Node> Stream<N> 
getNodesByType(Class<N> nodeClass) {
         return 
getWorkflowProcess().getNodesRecursively().stream().filter(nodeClass::isInstance).map(nodeClass::cast);
     }
diff --git 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/EventNodeInstance.java
 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/EventNodeInstance.java
index 8506251a30..72961609f1 100755
--- 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/EventNodeInstance.java
+++ 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/EventNodeInstance.java
@@ -19,11 +19,7 @@
 package org.jbpm.workflow.instance.node;
 
 import java.io.Serializable;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 import java.util.function.Function;
 import java.util.regex.Matcher;
 
@@ -40,6 +36,7 @@ import 
org.kie.kogito.internal.process.event.KogitoEventListener;
 import org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
 import org.kie.kogito.internal.process.runtime.KogitoProcessInstance;
 import org.kie.kogito.jobs.JobsService;
+import org.kie.kogito.jobs.TimerDescription;
 import org.kie.kogito.process.BaseEventDescription;
 import org.kie.kogito.process.EventDescription;
 import org.kie.kogito.process.NamedDataType;
@@ -47,6 +44,8 @@ import org.kie.kogito.timer.TimerInstance;
 
 import static 
org.jbpm.workflow.instance.impl.DummyEventListener.EMPTY_EVENT_LISTENER;
 import static 
org.jbpm.workflow.instance.node.TimerNodeInstance.TIMER_TRIGGERED_EVENT;
+import static org.kie.kogito.internal.utils.ConversionUtils.isEmpty;
+import static org.kie.kogito.internal.utils.ConversionUtils.isNotEmpty;
 
 /**
  * Runtime counterpart of an event node.
@@ -115,7 +114,7 @@ public class EventNodeInstance extends 
ExtendedNodeInstanceImpl implements Kogit
     }
 
     private void cancelSlaTimer() {
-        if (this.slaTimerId != null && !this.slaTimerId.trim().isEmpty()) {
+        if (isNotEmpty(this.slaTimerId)) {
             JobsService jobService = ((InternalProcessRuntime) 
getProcessInstance().getKnowledgeRuntime().getProcessRuntime()).getJobsService();
             jobService.cancelJob(this.slaTimerId);
             logger.debug("SLA Timer {} has been canceled", this.slaTimerId);
@@ -229,7 +228,7 @@ public class EventNodeInstance extends 
ExtendedNodeInstanceImpl implements Kogit
         } else {
             getProcessInstance().addEventListener(eventType, 
getEventListener(), true);
         }
-        if (this.slaTimerId != null && !this.slaTimerId.trim().isEmpty()) {
+        if (isNotEmpty(this.slaTimerId)) {
             addTimerListener();
         }
     }
@@ -279,4 +278,18 @@ public class EventNodeInstance extends 
ExtendedNodeInstanceImpl implements Kogit
         return Collections.singleton(new BaseEventDescription(getEventType(), 
getNodeDefinitionId(), getNodeName(), "signal", getStringId(), 
getProcessInstance().getStringId(), dataType));
     }
 
+    @Override
+    public Collection<TimerDescription> timers() {
+        if (isEmpty(slaTimerId)) {
+            return super.timers();
+        }
+
+        Collection<TimerDescription> toReturn = super.timers();
+        TimerDescription slaTimer = 
TimerDescription.Builder.ofNodeInstance(this)
+                .timerId(slaTimerId)
+                .timerDescription("[SLA] " + resolveExpression(getNodeName()))
+                .build();
+        toReturn.add(slaTimer);
+        return toReturn;
+    }
 }
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 1489004472..2aee1f690e 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
@@ -18,12 +18,7 @@
  */
 package org.jbpm.workflow.instance.node;
 
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
 
 import org.drools.core.common.InternalAgenda;
 import org.drools.core.common.ReteEvaluator;
@@ -48,10 +43,7 @@ import 
org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
 import org.kie.kogito.internal.process.runtime.KogitoProcessContext;
 import org.kie.kogito.internal.process.runtime.KogitoProcessInstance;
 import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime;
-import org.kie.kogito.jobs.DurationExpirationTime;
-import org.kie.kogito.jobs.ExactExpirationTime;
-import org.kie.kogito.jobs.ExpirationTime;
-import org.kie.kogito.jobs.JobsService;
+import org.kie.kogito.jobs.*;
 import org.kie.kogito.jobs.descriptors.ProcessInstanceJobDescription;
 import org.kie.kogito.process.expr.Expression;
 import org.kie.kogito.process.expr.ExpressionHandlerFactory;
@@ -62,6 +54,7 @@ import org.slf4j.LoggerFactory;
 import static 
org.jbpm.process.core.constants.CalendarConstants.BUSINESS_CALENDAR_ENVIRONMENT_KEY;
 import static org.jbpm.workflow.core.Node.CONNECTION_DEFAULT_TYPE;
 import static 
org.jbpm.workflow.instance.node.TimerNodeInstance.TIMER_TRIGGERED_EVENT;
+import static org.kie.kogito.internal.utils.ConversionUtils.isNotEmpty;
 
 public abstract class StateBasedNodeInstance extends ExtendedNodeInstanceImpl 
implements EventBasedNodeInstanceInterface, KogitoEventListener {
 
@@ -332,7 +325,7 @@ public abstract class StateBasedNodeInstance extends 
ExtendedNodeInstanceImpl im
 
     @Override
     public void addEventListeners() {
-        if (timerInstances != null && (!timerInstances.isEmpty()) || 
(this.slaTimerId != null && !this.slaTimerId.trim().isEmpty())) {
+        if (timerInstances != null && (!timerInstances.isEmpty()) || 
isNotEmpty(this.slaTimerId)) {
             addTimerListener();
         }
         if (slaCompliance == KogitoProcessInstance.SLA_PENDING) {
@@ -417,7 +410,7 @@ public abstract class StateBasedNodeInstance extends 
ExtendedNodeInstanceImpl im
     }
 
     private void cancelSlaTimer() {
-        if (this.slaTimerId != null && !this.slaTimerId.trim().isEmpty()) {
+        if (isNotEmpty(this.slaTimerId)) {
             JobsService jobService = ((InternalProcessRuntime) 
getProcessInstance().getKnowledgeRuntime().getProcessRuntime()).getJobsService();
             jobService.cancelJob(this.slaTimerId);
             logger.debug("SLA Timer {} has been canceled", this.slaTimerId);
@@ -467,4 +460,38 @@ public abstract class StateBasedNodeInstance extends 
ExtendedNodeInstanceImpl im
         context.getContextData().put("Exception", e);
         return context;
     }
+
+    @Override
+    public Collection<TimerDescription> timers() {
+        Collection<TimerDescription> toReturn = super.timers();
+
+        if (isNotEmpty(slaTimerId)) {
+            TimerDescription slaTimer = 
TimerDescription.Builder.ofNodeInstance(this)
+                    .timerId(slaTimerId)
+                    .timerDescription("[SLA] " + 
resolveExpression(getNodeName()))
+                    .build();
+            toReturn.add(slaTimer);
+        }
+
+        if (timerInstancesReference != null) {
+            Set<Timer> nodeTimers = getEventBasedNode().getTimers().keySet();
+            for (Timer timer : nodeTimers) {
+                Optional<String> jobIdOptional = 
timerInstancesReference.entrySet()
+                        .stream()
+                        .filter(entry -> 
String.valueOf(timer.getId()).equals(entry.getValue()))
+                        .findFirst()
+                        .map(Map.Entry::getKey);
+
+                jobIdOptional.ifPresent(jobId -> {
+                    TimerDescription timerDescription = 
TimerDescription.Builder.ofNodeInstance(this)
+                            .timerId(jobId)
+                            
.timerDescription(resolveExpression(timer.getName()))
+                            .build();
+                    toReturn.add(timerDescription);
+                });
+            }
+        }
+
+        return toReturn;
+    }
 }
diff --git 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/TimerNodeInstance.java
 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/TimerNodeInstance.java
index 5ca0c76a28..788aecc725 100755
--- 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/TimerNodeInstance.java
+++ 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/TimerNodeInstance.java
@@ -18,13 +18,7 @@
  */
 package org.jbpm.workflow.instance.node;
 
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.UUID;
+import java.util.*;
 
 import org.jbpm.process.core.context.exception.ExceptionScope;
 import org.jbpm.process.instance.InternalProcessRuntime;
@@ -36,6 +30,7 @@ import 
org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
 import org.kie.kogito.internal.process.workitem.WorkItemExecutionException;
 import org.kie.kogito.jobs.ExpirationTime;
 import org.kie.kogito.jobs.JobsService;
+import org.kie.kogito.jobs.TimerDescription;
 import org.kie.kogito.jobs.descriptors.ProcessInstanceJobDescription;
 import org.kie.kogito.process.BaseEventDescription;
 import org.kie.kogito.process.EventDescription;
@@ -157,4 +152,19 @@ public class TimerNodeInstance extends 
StateBasedNodeInstance implements EventLi
         return Collections
                 .singleton(new BaseEventDescription(TIMER_TRIGGERED_EVENT, 
getNodeDefinitionId(), getNodeName(), "timer", getStringId(), 
getProcessInstance().getStringId(), null, properties));
     }
+
+    @Override
+    public Collection<TimerDescription> timers() {
+        if (this.timerId == null) {
+            return super.timers();
+        }
+
+        Collection<TimerDescription> toReturn = super.timers();
+        TimerDescription timerDescription = 
TimerDescription.Builder.ofNodeInstance(this)
+                .timerId(timerId)
+                .timerDescription(resolveExpression(getNodeName()))
+                .build();
+        toReturn.add(timerDescription);
+        return toReturn;
+    }
 }
diff --git 
a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessInstance.java
 
b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessInstance.java
index 81c2275048..df5ccb715f 100644
--- 
a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessInstance.java
+++ 
b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessInstance.java
@@ -59,6 +59,7 @@ import 
org.kie.kogito.internal.process.workitem.KogitoWorkItem;
 import org.kie.kogito.internal.process.workitem.Policy;
 import org.kie.kogito.internal.process.workitem.WorkItemNotFoundException;
 import org.kie.kogito.internal.process.workitem.WorkItemTransition;
+import org.kie.kogito.jobs.TimerDescription;
 import org.kie.kogito.process.EventDescription;
 import org.kie.kogito.process.MutableProcessInstances;
 import org.kie.kogito.process.NodeInstanceNotFoundException;
@@ -652,14 +653,21 @@ public abstract class AbstractProcessInstance<T extends 
Model> implements Proces
     @Override
     public Collection<Milestone> milestones() {
         return processInstanceLockStrategy.executeOperation(id, () -> {
-            return processInstance.milestones();
+            return processInstance().milestones();
+        });
+    }
+
+    @Override
+    public Collection<TimerDescription> timers() {
+        return processInstanceLockStrategy.executeOperation(id, () -> {
+            return processInstance().timers();
         });
     }
 
     @Override
     public Collection<AdHocFragment> adHocFragments() {
         return processInstanceLockStrategy.executeOperation(id, () -> {
-            return processInstance.adHocFragments();
+            return processInstance().adHocFragments();
         });
     }
 
diff --git 
a/quarkus/addons/process-management/integration-tests/src/main/resources/timers.bpmn
 
b/quarkus/addons/process-management/integration-tests/src/main/resources/timers.bpmn
new file mode 100644
index 0000000000..63b3bac089
--- /dev/null
+++ 
b/quarkus/addons/process-management/integration-tests/src/main/resources/timers.bpmn
@@ -0,0 +1,178 @@
+<?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: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="_FbQn4Bn5ED6qPL2RHaehww" 
xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd 
http://www. [...]
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_SkippableInputXItem" 
structureRef="Object"/>
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_PriorityInputXItem" 
structureRef="Object"/>
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_CommentInputXItem" 
structureRef="Object"/>
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_DescriptionInputXItem" 
structureRef="Object"/>
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_CreatedByInputXItem" 
structureRef="Object"/>
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_TaskNameInputXItem" 
structureRef="Object"/>
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_GroupIdInputXItem" 
structureRef="Object"/>
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_ContentInputXItem" 
structureRef="Object"/>
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_NotStartedReassignInputXItem" 
structureRef="Object"/>
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_NotCompletedReassignInputXItem" 
structureRef="Object"/>
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_NotStartedNotifyInputXItem" 
structureRef="Object"/>
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_NotCompletedNotifyInputXItem" 
structureRef="Object"/>
+  <bpmn2:collaboration id="_11F36E9B-11DF-499D-896C-0D73277FBCB5" 
name="Default Collaboration">
+    <bpmn2:participant id="_3CC3D518-96F1-4246-B77A-BD69EA62333A" name="Pool 
Participant" processRef="timers"/>
+  </bpmn2:collaboration>
+  <bpmn2:process id="timers" drools:packageName="com.example" 
drools:version="1.0" drools:adHoc="false" name="timers" isExecutable="true" 
processType="Public">
+    <bpmn2:extensionElements>
+      <drools:metaData name="customSLADueDate">
+        <drools:metaValue><![CDATA[200m]]></drools:metaValue>
+      </drools:metaData>
+      <drools:metaData name="processDuration">
+        <drools:metaValue><![CDATA[PT1M]]></drools:metaValue>
+      </drools:metaData>
+    </bpmn2:extensionElements>
+    <bpmn2:sequenceFlow id="_2CCE6D96-07C9-4196-A3DA-2FA12675606B" 
sourceRef="_C64FDE83-9AE3-4BC8-94AC-14805BE0D3D3" 
targetRef="_A2B595B9-3809-487E-B354-677DE3EB9B83"/>
+    <bpmn2:sequenceFlow id="_217C7B88-D29D-479F-9DDA-49C505B55DB3" 
sourceRef="_CB75879B-EB0D-4F28-AC61-E6FAA0126490" 
targetRef="_66215F0B-D52C-4DEF-8BAE-3524FD59A246"/>
+    <bpmn2:sequenceFlow id="_BB186F29-4721-4C71-BFAA-D816C47ED670" 
sourceRef="_F35EC805-22D5-4833-B56D-9DE16B4B258B" 
targetRef="_CB75879B-EB0D-4F28-AC61-E6FAA0126490"/>
+    <bpmn2:endEvent id="_A2B595B9-3809-487E-B354-677DE3EB9B83">
+      <bpmn2:incoming>_2CCE6D96-07C9-4196-A3DA-2FA12675606B</bpmn2:incoming>
+    </bpmn2:endEvent>
+    <bpmn2:endEvent id="_66215F0B-D52C-4DEF-8BAE-3524FD59A246">
+      <bpmn2:incoming>_217C7B88-D29D-479F-9DDA-49C505B55DB3</bpmn2:incoming>
+    </bpmn2:endEvent>
+    <bpmn2:userTask id="_CB75879B-EB0D-4F28-AC61-E6FAA0126490" name="Task">
+      <bpmn2:extensionElements>
+        <drools:metaData name="elementname">
+          <drools:metaValue><![CDATA[Task]]></drools:metaValue>
+        </drools:metaData>
+        <drools:metaData name="customSLADueDate">
+          <drools:metaValue><![CDATA[150m]]></drools:metaValue>
+        </drools:metaData>
+      </bpmn2:extensionElements>
+      <bpmn2:incoming>_BB186F29-4721-4C71-BFAA-D816C47ED670</bpmn2:incoming>
+      <bpmn2:outgoing>_217C7B88-D29D-479F-9DDA-49C505B55DB3</bpmn2:outgoing>
+      <bpmn2:ioSpecification>
+        <bpmn2:dataInput 
id="_CB75879B-EB0D-4F28-AC61-E6FAA0126490_TaskNameInputX" drools:dtype="Object" 
itemSubjectRef="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_TaskNameInputXItem" 
name="TaskName"/>
+        <bpmn2:dataInput 
id="_CB75879B-EB0D-4F28-AC61-E6FAA0126490_SkippableInputX" 
drools:dtype="Object" 
itemSubjectRef="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_SkippableInputXItem" 
name="Skippable"/>
+        <bpmn2:inputSet>
+          
<bpmn2:dataInputRefs>_CB75879B-EB0D-4F28-AC61-E6FAA0126490_TaskNameInputX</bpmn2:dataInputRefs>
+          
<bpmn2:dataInputRefs>_CB75879B-EB0D-4F28-AC61-E6FAA0126490_SkippableInputX</bpmn2:dataInputRefs>
+        </bpmn2:inputSet>
+      </bpmn2:ioSpecification>
+      <bpmn2:dataInputAssociation>
+        
<bpmn2:targetRef>_CB75879B-EB0D-4F28-AC61-E6FAA0126490_TaskNameInputX</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[Task]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_CB75879B-EB0D-4F28-AC61-E6FAA0126490_TaskNameInputX]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        
<bpmn2:targetRef>_CB75879B-EB0D-4F28-AC61-E6FAA0126490_SkippableInputX</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[false]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_CB75879B-EB0D-4F28-AC61-E6FAA0126490_SkippableInputX]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:potentialOwner id="_FbR2ABn5ED6qPL2RHaehww">
+        <bpmn2:resourceAssignmentExpression id="_FbR2ARn5ED6qPL2RHaehww">
+          <bpmn2:formalExpression>jdoe</bpmn2:formalExpression>
+        </bpmn2:resourceAssignmentExpression>
+      </bpmn2:potentialOwner>
+    </bpmn2:userTask>
+    <bpmn2:startEvent id="_F35EC805-22D5-4833-B56D-9DE16B4B258B">
+      <bpmn2:outgoing>_BB186F29-4721-4C71-BFAA-D816C47ED670</bpmn2:outgoing>
+    </bpmn2:startEvent>
+    <bpmn2:boundaryEvent id="_C64FDE83-9AE3-4BC8-94AC-14805BE0D3D3" 
drools:dockerinfo="70.42^74|" drools:boundaryca="true" name="Boundary Timer" 
attachedToRef="_CB75879B-EB0D-4F28-AC61-E6FAA0126490">
+      <bpmn2:extensionElements>
+        <drools:metaData name="elementname">
+          <drools:metaValue><![CDATA[Boundary Timer]]></drools:metaValue>
+        </drools:metaData>
+      </bpmn2:extensionElements>
+      <bpmn2:outgoing>_2CCE6D96-07C9-4196-A3DA-2FA12675606B</bpmn2:outgoing>
+      <bpmn2:timerEventDefinition>
+        <bpmn2:timeDuration 
xsi:type="bpmn2:tFormalExpression">PT180S</bpmn2:timeDuration>
+      </bpmn2:timerEventDefinition>
+    </bpmn2:boundaryEvent>
+  </bpmn2:process>
+  <bpmndi:BPMNDiagram>
+    <bpmndi:BPMNPlane bpmnElement="timers">
+      <bpmndi:BPMNShape id="shape__F35EC805-22D5-4833-B56D-9DE16B4B258B" 
bpmnElement="_F35EC805-22D5-4833-B56D-9DE16B4B258B">
+        <dc:Bounds height="56" width="56" x="325" y="97"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__CB75879B-EB0D-4F28-AC61-E6FAA0126490" 
bpmnElement="_CB75879B-EB0D-4F28-AC61-E6FAA0126490">
+        <dc:Bounds height="102" width="154" x="448" y="74"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__66215F0B-D52C-4DEF-8BAE-3524FD59A246" 
bpmnElement="_66215F0B-D52C-4DEF-8BAE-3524FD59A246">
+        <dc:Bounds height="56" width="56" x="682" y="97"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__C64FDE83-9AE3-4BC8-94AC-14805BE0D3D3" 
bpmnElement="_C64FDE83-9AE3-4BC8-94AC-14805BE0D3D3">
+        <dc:Bounds height="56" width="56" x="518.42" y="148"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__A2B595B9-3809-487E-B354-677DE3EB9B83" 
bpmnElement="_A2B595B9-3809-487E-B354-677DE3EB9B83">
+        <dc:Bounds height="56" width="56" x="682" y="246"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge 
id="edge_shape__F35EC805-22D5-4833-B56D-9DE16B4B258B_to_shape__CB75879B-EB0D-4F28-AC61-E6FAA0126490"
 bpmnElement="_BB186F29-4721-4C71-BFAA-D816C47ED670">
+        <di:waypoint x="353" y="125"/>
+        <di:waypoint x="525" y="125"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge 
id="edge_shape__CB75879B-EB0D-4F28-AC61-E6FAA0126490_to_shape__66215F0B-D52C-4DEF-8BAE-3524FD59A246"
 bpmnElement="_217C7B88-D29D-479F-9DDA-49C505B55DB3">
+        <di:waypoint x="525" y="125"/>
+        <di:waypoint x="710" y="125"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge 
id="edge_shape__C64FDE83-9AE3-4BC8-94AC-14805BE0D3D3_to_shape__A2B595B9-3809-487E-B354-677DE3EB9B83"
 bpmnElement="_2CCE6D96-07C9-4196-A3DA-2FA12675606B">
+        <di:waypoint x="546.42" y="176"/>
+        <di:waypoint x="546.42" y="274"/>
+        <di:waypoint x="682" y="274"/>
+      </bpmndi:BPMNEdge>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+  <bpmn2:relationship type="BPSimData">
+    <bpmn2:extensionElements>
+      <bpsim:BPSimData>
+        <bpsim:Scenario id="default" name="Simulationscenario">
+          <bpsim:ScenarioParameters/>
+          <bpsim:ElementParameters 
elementRef="_F35EC805-22D5-4833-B56D-9DE16B4B258B">
+            <bpsim:TimeParameters>
+              <bpsim:ProcessingTime>
+                <bpsim:NormalDistribution mean="0" standardDeviation="0"/>
+              </bpsim:ProcessingTime>
+            </bpsim:TimeParameters>
+          </bpsim:ElementParameters>
+          <bpsim:ElementParameters 
elementRef="_CB75879B-EB0D-4F28-AC61-E6FAA0126490">
+            <bpsim:TimeParameters>
+              <bpsim:ProcessingTime>
+                <bpsim:NormalDistribution mean="0" standardDeviation="0"/>
+              </bpsim:ProcessingTime>
+            </bpsim:TimeParameters>
+            <bpsim:ResourceParameters>
+              <bpsim:Availability>
+                <bpsim:FloatingParameter value="0"/>
+              </bpsim:Availability>
+              <bpsim:Quantity>
+                <bpsim:FloatingParameter value="0"/>
+              </bpsim:Quantity>
+            </bpsim:ResourceParameters>
+            <bpsim:CostParameters>
+              <bpsim:UnitCost>
+                <bpsim:FloatingParameter value="0"/>
+              </bpsim:UnitCost>
+            </bpsim:CostParameters>
+          </bpsim:ElementParameters>
+        </bpsim:Scenario>
+      </bpsim:BPSimData>
+    </bpmn2:extensionElements>
+    <bpmn2:source>_FbQn4Bn5ED6qPL2RHaehww</bpmn2:source>
+    <bpmn2:target>_FbQn4Bn5ED6qPL2RHaehww</bpmn2:target>
+  </bpmn2:relationship>
+</bpmn2:definitions>
\ No newline at end of file
diff --git 
a/quarkus/addons/process-management/integration-tests/src/test/java/org/kie/kogito/quarkus/workflows/ProcessManagementIT.java
 
b/quarkus/addons/process-management/integration-tests/src/test/java/org/kie/kogito/quarkus/workflows/ProcessManagementIT.java
new file mode 100644
index 0000000000..9d83bbc17e
--- /dev/null
+++ 
b/quarkus/addons/process-management/integration-tests/src/test/java/org/kie/kogito/quarkus/workflows/ProcessManagementIT.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.quarkus.workflows;
+
+import java.util.Map;
+
+import org.junit.jupiter.api.Test;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+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;
+import static org.hamcrest.Matchers.hasKey;
+
+@QuarkusIntegrationTest
+public class ProcessManagementIT {
+
+    static {
+        RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
+    }
+
+    @Test
+    void testManagementTimersEndpoint() {
+        String processInstanceId = given()
+                .body(Map.of())
+                .contentType(ContentType.JSON)
+                .when()
+                .post("/timers")
+                .then()
+                .statusCode(201)
+                .body("id", notNullValue())
+                .extract().path("id");
+
+        String nodeInstanceId = given()
+                .when()
+                
.get("/management/processes/timers/instances/{processInstanceId}/nodeInstances",
 processInstanceId)
+                .then()
+                .statusCode(200)
+                .body("$.size()", equalTo(1))
+                .extract().path("[0].nodeInstanceId");
+
+        given()
+                .when()
+                
.get("/management/processes/timers/instances/{processInstanceId}/timers", 
processInstanceId)
+                .then()
+                .statusCode(200)
+                .body("$.size()", equalTo(4))
+                .body("", hasItem(allOf(
+                        hasEntry("processId", "timers"),
+                        hasEntry("processInstanceId", processInstanceId),
+                        hasKey("timerId"),
+                        hasEntry("description", "[SLA-Process] timers"))))
+                .body("", hasItem(allOf(
+                        hasEntry("processId", "timers"),
+                        hasEntry("processInstanceId", processInstanceId),
+                        hasKey("timerId"),
+                        hasEntry("description", "[CANCEL-Process] timers"))))
+                .body("", hasItem(allOf(
+                        hasEntry("processId", "timers"),
+                        hasEntry("processInstanceId", processInstanceId),
+                        hasEntry("nodeInstanceId", nodeInstanceId),
+                        hasKey("timerId"),
+                        hasEntry("description", "[SLA] Task"))))
+                .body("", hasItem(allOf(
+                        hasEntry("processId", "timers"),
+                        hasEntry("processInstanceId", processInstanceId),
+                        hasEntry("nodeInstanceId", nodeInstanceId),
+                        hasKey("timerId"),
+                        hasEntry("description", "Task-Boundary Timer"))));
+
+        given()
+                .when()
+                
.get("/management/processes/timers/instances/{processInstanceId}/nodeInstances/{nodeInstanceId}/timers",
 processInstanceId, nodeInstanceId)
+                .then()
+                .statusCode(200)
+                .body("$.size()", equalTo(2))
+                .body("", hasItem(allOf(
+                        hasEntry("processId", "timers"),
+                        hasEntry("processInstanceId", processInstanceId),
+                        hasEntry("nodeInstanceId", nodeInstanceId),
+                        hasKey("timerId"),
+                        hasEntry("description", "[SLA] Task"))))
+                .body("", hasItem(allOf(
+                        hasEntry("processId", "timers"),
+                        hasEntry("processInstanceId", processInstanceId),
+                        hasEntry("nodeInstanceId", nodeInstanceId),
+                        hasKey("timerId"),
+                        hasEntry("description", "Task-Boundary Timer"))));
+    }
+}
diff --git 
a/quarkus/addons/process-management/runtime/src/main/java/org/kie/kogito/process/management/ProcessInstanceManagementResource.java
 
b/quarkus/addons/process-management/runtime/src/main/java/org/kie/kogito/process/management/ProcessInstanceManagementResource.java
index c2b9bf1cc5..6bf8433f63 100644
--- 
a/quarkus/addons/process-management/runtime/src/main/java/org/kie/kogito/process/management/ProcessInstanceManagementResource.java
+++ 
b/quarkus/addons/process-management/runtime/src/main/java/org/kie/kogito/process/management/ProcessInstanceManagementResource.java
@@ -126,6 +126,14 @@ public class ProcessInstanceManagementResource extends 
BaseProcessInstanceManage
         return doGetWorkItemsInProcessInstance(processId, processInstanceId);
     }
 
+    @Override
+    @GET
+    @Path("{processId}/instances/{processInstanceId}/timers")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getProcessInstanceTimers(@PathParam("processId") String 
processId, @PathParam("processInstanceId") String processInstanceId) {
+        return doGetProcessInstanceTimers(processId, processInstanceId);
+    }
+
     @Override
     @POST
     @Path("{processId}/instances/{processInstanceId}/retrigger")
@@ -166,6 +174,14 @@ public class ProcessInstanceManagementResource extends 
BaseProcessInstanceManage
         return doCancelNodeInstanceId(processId, processInstanceId, 
nodeInstanceId);
     }
 
+    @Override
+    @GET
+    
@Path("{processId}/instances/{processInstanceId}/nodeInstances/{nodeInstanceId}/timers")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getNodeInstanceTimers(@PathParam("processId") String 
processId, @PathParam("processInstanceId") String processInstanceId, 
@PathParam("nodeInstanceId") String nodeInstanceId) {
+        return doGetNodeInstanceTimers(processId, processInstanceId, 
nodeInstanceId);
+    }
+
     @Override
     @DELETE
     @Path("{processId}/instances/{processInstanceId}")
diff --git 
a/springboot/addons/process-management/src/main/java/org/kie/kogito/process/management/ProcessInstanceManagementRestController.java
 
b/springboot/addons/process-management/src/main/java/org/kie/kogito/process/management/ProcessInstanceManagementRestController.java
index 5f143aac29..eec6482af3 100644
--- 
a/springboot/addons/process-management/src/main/java/org/kie/kogito/process/management/ProcessInstanceManagementRestController.java
+++ 
b/springboot/addons/process-management/src/main/java/org/kie/kogito/process/management/ProcessInstanceManagementRestController.java
@@ -101,6 +101,12 @@ public class ProcessInstanceManagementRestController 
extends BaseProcessInstance
         return doGetWorkItemsInProcessInstance(processId, processInstanceId);
     }
 
+    @Override
+    @GetMapping(value = "{processId}/instances/{processInstanceId}/timers", 
produces = APPLICATION_JSON_VALUE)
+    public ResponseEntity getProcessInstanceTimers(@PathVariable("processId") 
String processId, @PathVariable("processInstanceId") String processInstanceId) {
+        return doGetProcessInstanceTimers(processId, processInstanceId);
+    }
+
     @Override
     @PostMapping(value = 
"{processId}/instances/{processInstanceId}/retrigger", produces = 
APPLICATION_JSON_VALUE)
     public ResponseEntity retriggerInstanceInError(@PathVariable("processId") 
String processId, @PathVariable("processInstanceId") String processInstanceId) {
@@ -133,6 +139,13 @@ public class ProcessInstanceManagementRestController 
extends BaseProcessInstance
         return doCancelNodeInstanceId(processId, processInstanceId, 
nodeInstanceId);
     }
 
+    @Override
+    @GetMapping(value = 
"{processId}/instances/{processInstanceId}/nodeInstances/{nodeInstanceId}/timers",
 produces = APPLICATION_JSON_VALUE)
+    public ResponseEntity getNodeInstanceTimers(@PathVariable("processId") 
String processId, @PathVariable("processInstanceId") String processInstanceId,
+            @PathVariable("nodeInstanceId") String nodeInstanceId) {
+        return doGetNodeInstanceTimers(processId, processInstanceId, 
nodeInstanceId);
+    }
+
     @Override
     @DeleteMapping(value = "{processId}/instances/{processInstanceId}", 
produces = APPLICATION_JSON_VALUE)
     public ResponseEntity cancelProcessInstanceId(@PathVariable("processId") 
String processId, @PathVariable("processInstanceId") String processInstanceId) {
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/timers.bpmn
new file mode 100644
index 0000000000..63b3bac089
--- /dev/null
+++ 
b/springboot/integration-tests/integration-tests-springboot-processes-it/src/main/resources/timers.bpmn
@@ -0,0 +1,178 @@
+<?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: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="_FbQn4Bn5ED6qPL2RHaehww" 
xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd 
http://www. [...]
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_SkippableInputXItem" 
structureRef="Object"/>
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_PriorityInputXItem" 
structureRef="Object"/>
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_CommentInputXItem" 
structureRef="Object"/>
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_DescriptionInputXItem" 
structureRef="Object"/>
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_CreatedByInputXItem" 
structureRef="Object"/>
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_TaskNameInputXItem" 
structureRef="Object"/>
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_GroupIdInputXItem" 
structureRef="Object"/>
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_ContentInputXItem" 
structureRef="Object"/>
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_NotStartedReassignInputXItem" 
structureRef="Object"/>
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_NotCompletedReassignInputXItem" 
structureRef="Object"/>
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_NotStartedNotifyInputXItem" 
structureRef="Object"/>
+  <bpmn2:itemDefinition 
id="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_NotCompletedNotifyInputXItem" 
structureRef="Object"/>
+  <bpmn2:collaboration id="_11F36E9B-11DF-499D-896C-0D73277FBCB5" 
name="Default Collaboration">
+    <bpmn2:participant id="_3CC3D518-96F1-4246-B77A-BD69EA62333A" name="Pool 
Participant" processRef="timers"/>
+  </bpmn2:collaboration>
+  <bpmn2:process id="timers" drools:packageName="com.example" 
drools:version="1.0" drools:adHoc="false" name="timers" isExecutable="true" 
processType="Public">
+    <bpmn2:extensionElements>
+      <drools:metaData name="customSLADueDate">
+        <drools:metaValue><![CDATA[200m]]></drools:metaValue>
+      </drools:metaData>
+      <drools:metaData name="processDuration">
+        <drools:metaValue><![CDATA[PT1M]]></drools:metaValue>
+      </drools:metaData>
+    </bpmn2:extensionElements>
+    <bpmn2:sequenceFlow id="_2CCE6D96-07C9-4196-A3DA-2FA12675606B" 
sourceRef="_C64FDE83-9AE3-4BC8-94AC-14805BE0D3D3" 
targetRef="_A2B595B9-3809-487E-B354-677DE3EB9B83"/>
+    <bpmn2:sequenceFlow id="_217C7B88-D29D-479F-9DDA-49C505B55DB3" 
sourceRef="_CB75879B-EB0D-4F28-AC61-E6FAA0126490" 
targetRef="_66215F0B-D52C-4DEF-8BAE-3524FD59A246"/>
+    <bpmn2:sequenceFlow id="_BB186F29-4721-4C71-BFAA-D816C47ED670" 
sourceRef="_F35EC805-22D5-4833-B56D-9DE16B4B258B" 
targetRef="_CB75879B-EB0D-4F28-AC61-E6FAA0126490"/>
+    <bpmn2:endEvent id="_A2B595B9-3809-487E-B354-677DE3EB9B83">
+      <bpmn2:incoming>_2CCE6D96-07C9-4196-A3DA-2FA12675606B</bpmn2:incoming>
+    </bpmn2:endEvent>
+    <bpmn2:endEvent id="_66215F0B-D52C-4DEF-8BAE-3524FD59A246">
+      <bpmn2:incoming>_217C7B88-D29D-479F-9DDA-49C505B55DB3</bpmn2:incoming>
+    </bpmn2:endEvent>
+    <bpmn2:userTask id="_CB75879B-EB0D-4F28-AC61-E6FAA0126490" name="Task">
+      <bpmn2:extensionElements>
+        <drools:metaData name="elementname">
+          <drools:metaValue><![CDATA[Task]]></drools:metaValue>
+        </drools:metaData>
+        <drools:metaData name="customSLADueDate">
+          <drools:metaValue><![CDATA[150m]]></drools:metaValue>
+        </drools:metaData>
+      </bpmn2:extensionElements>
+      <bpmn2:incoming>_BB186F29-4721-4C71-BFAA-D816C47ED670</bpmn2:incoming>
+      <bpmn2:outgoing>_217C7B88-D29D-479F-9DDA-49C505B55DB3</bpmn2:outgoing>
+      <bpmn2:ioSpecification>
+        <bpmn2:dataInput 
id="_CB75879B-EB0D-4F28-AC61-E6FAA0126490_TaskNameInputX" drools:dtype="Object" 
itemSubjectRef="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_TaskNameInputXItem" 
name="TaskName"/>
+        <bpmn2:dataInput 
id="_CB75879B-EB0D-4F28-AC61-E6FAA0126490_SkippableInputX" 
drools:dtype="Object" 
itemSubjectRef="__CB75879B-EB0D-4F28-AC61-E6FAA0126490_SkippableInputXItem" 
name="Skippable"/>
+        <bpmn2:inputSet>
+          
<bpmn2:dataInputRefs>_CB75879B-EB0D-4F28-AC61-E6FAA0126490_TaskNameInputX</bpmn2:dataInputRefs>
+          
<bpmn2:dataInputRefs>_CB75879B-EB0D-4F28-AC61-E6FAA0126490_SkippableInputX</bpmn2:dataInputRefs>
+        </bpmn2:inputSet>
+      </bpmn2:ioSpecification>
+      <bpmn2:dataInputAssociation>
+        
<bpmn2:targetRef>_CB75879B-EB0D-4F28-AC61-E6FAA0126490_TaskNameInputX</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[Task]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_CB75879B-EB0D-4F28-AC61-E6FAA0126490_TaskNameInputX]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:dataInputAssociation>
+        
<bpmn2:targetRef>_CB75879B-EB0D-4F28-AC61-E6FAA0126490_SkippableInputX</bpmn2:targetRef>
+        <bpmn2:assignment>
+          <bpmn2:from 
xsi:type="bpmn2:tFormalExpression"><![CDATA[false]]></bpmn2:from>
+          <bpmn2:to 
xsi:type="bpmn2:tFormalExpression"><![CDATA[_CB75879B-EB0D-4F28-AC61-E6FAA0126490_SkippableInputX]]></bpmn2:to>
+        </bpmn2:assignment>
+      </bpmn2:dataInputAssociation>
+      <bpmn2:potentialOwner id="_FbR2ABn5ED6qPL2RHaehww">
+        <bpmn2:resourceAssignmentExpression id="_FbR2ARn5ED6qPL2RHaehww">
+          <bpmn2:formalExpression>jdoe</bpmn2:formalExpression>
+        </bpmn2:resourceAssignmentExpression>
+      </bpmn2:potentialOwner>
+    </bpmn2:userTask>
+    <bpmn2:startEvent id="_F35EC805-22D5-4833-B56D-9DE16B4B258B">
+      <bpmn2:outgoing>_BB186F29-4721-4C71-BFAA-D816C47ED670</bpmn2:outgoing>
+    </bpmn2:startEvent>
+    <bpmn2:boundaryEvent id="_C64FDE83-9AE3-4BC8-94AC-14805BE0D3D3" 
drools:dockerinfo="70.42^74|" drools:boundaryca="true" name="Boundary Timer" 
attachedToRef="_CB75879B-EB0D-4F28-AC61-E6FAA0126490">
+      <bpmn2:extensionElements>
+        <drools:metaData name="elementname">
+          <drools:metaValue><![CDATA[Boundary Timer]]></drools:metaValue>
+        </drools:metaData>
+      </bpmn2:extensionElements>
+      <bpmn2:outgoing>_2CCE6D96-07C9-4196-A3DA-2FA12675606B</bpmn2:outgoing>
+      <bpmn2:timerEventDefinition>
+        <bpmn2:timeDuration 
xsi:type="bpmn2:tFormalExpression">PT180S</bpmn2:timeDuration>
+      </bpmn2:timerEventDefinition>
+    </bpmn2:boundaryEvent>
+  </bpmn2:process>
+  <bpmndi:BPMNDiagram>
+    <bpmndi:BPMNPlane bpmnElement="timers">
+      <bpmndi:BPMNShape id="shape__F35EC805-22D5-4833-B56D-9DE16B4B258B" 
bpmnElement="_F35EC805-22D5-4833-B56D-9DE16B4B258B">
+        <dc:Bounds height="56" width="56" x="325" y="97"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__CB75879B-EB0D-4F28-AC61-E6FAA0126490" 
bpmnElement="_CB75879B-EB0D-4F28-AC61-E6FAA0126490">
+        <dc:Bounds height="102" width="154" x="448" y="74"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__66215F0B-D52C-4DEF-8BAE-3524FD59A246" 
bpmnElement="_66215F0B-D52C-4DEF-8BAE-3524FD59A246">
+        <dc:Bounds height="56" width="56" x="682" y="97"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__C64FDE83-9AE3-4BC8-94AC-14805BE0D3D3" 
bpmnElement="_C64FDE83-9AE3-4BC8-94AC-14805BE0D3D3">
+        <dc:Bounds height="56" width="56" x="518.42" y="148"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape id="shape__A2B595B9-3809-487E-B354-677DE3EB9B83" 
bpmnElement="_A2B595B9-3809-487E-B354-677DE3EB9B83">
+        <dc:Bounds height="56" width="56" x="682" y="246"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNEdge 
id="edge_shape__F35EC805-22D5-4833-B56D-9DE16B4B258B_to_shape__CB75879B-EB0D-4F28-AC61-E6FAA0126490"
 bpmnElement="_BB186F29-4721-4C71-BFAA-D816C47ED670">
+        <di:waypoint x="353" y="125"/>
+        <di:waypoint x="525" y="125"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge 
id="edge_shape__CB75879B-EB0D-4F28-AC61-E6FAA0126490_to_shape__66215F0B-D52C-4DEF-8BAE-3524FD59A246"
 bpmnElement="_217C7B88-D29D-479F-9DDA-49C505B55DB3">
+        <di:waypoint x="525" y="125"/>
+        <di:waypoint x="710" y="125"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge 
id="edge_shape__C64FDE83-9AE3-4BC8-94AC-14805BE0D3D3_to_shape__A2B595B9-3809-487E-B354-677DE3EB9B83"
 bpmnElement="_2CCE6D96-07C9-4196-A3DA-2FA12675606B">
+        <di:waypoint x="546.42" y="176"/>
+        <di:waypoint x="546.42" y="274"/>
+        <di:waypoint x="682" y="274"/>
+      </bpmndi:BPMNEdge>
+    </bpmndi:BPMNPlane>
+  </bpmndi:BPMNDiagram>
+  <bpmn2:relationship type="BPSimData">
+    <bpmn2:extensionElements>
+      <bpsim:BPSimData>
+        <bpsim:Scenario id="default" name="Simulationscenario">
+          <bpsim:ScenarioParameters/>
+          <bpsim:ElementParameters 
elementRef="_F35EC805-22D5-4833-B56D-9DE16B4B258B">
+            <bpsim:TimeParameters>
+              <bpsim:ProcessingTime>
+                <bpsim:NormalDistribution mean="0" standardDeviation="0"/>
+              </bpsim:ProcessingTime>
+            </bpsim:TimeParameters>
+          </bpsim:ElementParameters>
+          <bpsim:ElementParameters 
elementRef="_CB75879B-EB0D-4F28-AC61-E6FAA0126490">
+            <bpsim:TimeParameters>
+              <bpsim:ProcessingTime>
+                <bpsim:NormalDistribution mean="0" standardDeviation="0"/>
+              </bpsim:ProcessingTime>
+            </bpsim:TimeParameters>
+            <bpsim:ResourceParameters>
+              <bpsim:Availability>
+                <bpsim:FloatingParameter value="0"/>
+              </bpsim:Availability>
+              <bpsim:Quantity>
+                <bpsim:FloatingParameter value="0"/>
+              </bpsim:Quantity>
+            </bpsim:ResourceParameters>
+            <bpsim:CostParameters>
+              <bpsim:UnitCost>
+                <bpsim:FloatingParameter value="0"/>
+              </bpsim:UnitCost>
+            </bpsim:CostParameters>
+          </bpsim:ElementParameters>
+        </bpsim:Scenario>
+      </bpsim:BPSimData>
+    </bpmn2:extensionElements>
+    <bpmn2:source>_FbQn4Bn5ED6qPL2RHaehww</bpmn2:source>
+    <bpmn2:target>_FbQn4Bn5ED6qPL2RHaehww</bpmn2:target>
+  </bpmn2:relationship>
+</bpmn2:definitions>
\ No newline at end of file
diff --git 
a/springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/ManagementAddOnTest.java
 
b/springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/ManagementAddOnTest.java
index ac7b72f40d..d15ee2104c 100644
--- 
a/springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/ManagementAddOnTest.java
+++ 
b/springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/ManagementAddOnTest.java
@@ -20,6 +20,7 @@ package org.kie.kogito.integrationtests.springboot;
 
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -31,12 +32,13 @@ import io.restassured.http.ContentType;
 
 import static io.restassured.RestAssured.given;
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.hamcrest.CoreMatchers.allOf;
 import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.hasItem;
 import static org.hamcrest.CoreMatchers.hasItems;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.Matchers.emptyOrNullString;
-import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.*;
 
 @ExtendWith(SpringExtension.class)
 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, 
classes = KogitoSpringbootApplication.class)
@@ -44,6 +46,7 @@ class ManagementAddOnTest extends BaseRestTest {
 
     private static final String HELLO1_NODE = 
"_3CDC6E61-DCC5-4831-8BBB-417CFF517CB0";
     private static final String GREETINGS = "greetings";
+    private static final String TIMERS = "timers";
 
     static {
         RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
@@ -128,6 +131,75 @@ class ManagementAddOnTest extends BaseRestTest {
         
assertThat(newNodeInstanceIds).doesNotContainAnyElementsOf(nodeInstanceIds);
     }
 
+    @Test
+    void testManagementTimersEndpoint() {
+        String processInstanceId = given()
+                .body(Map.of())
+                .contentType(ContentType.JSON)
+                .when()
+                .post("/timers")
+                .then()
+                .statusCode(201)
+                .body("id", notNullValue())
+                .extract().path("id");
+
+        String nodeInstanceId = given()
+                .when()
+                
.get("/management/processes/{processId}/instances/{processInstanceId}/nodeInstances",
 TIMERS, processInstanceId)
+                .then()
+                .statusCode(200)
+                .body("$.size()", equalTo(1))
+                .extract().path("[0].nodeInstanceId");
+
+        given()
+                .when()
+                
.get("/management/processes/{processId}/instances/{processInstanceId}/timers", 
TIMERS, processInstanceId)
+                .then()
+                .statusCode(200)
+                .body("$.size()", equalTo(4))
+                .body("", hasItem(allOf(
+                        hasEntry("processId", "timers"),
+                        hasEntry("processInstanceId", processInstanceId),
+                        hasKey("timerId"),
+                        hasEntry("description", "[SLA-Process] timers"))))
+                .body("", hasItem(allOf(
+                        hasEntry("processId", "timers"),
+                        hasEntry("processInstanceId", processInstanceId),
+                        hasKey("timerId"),
+                        hasEntry("description", "[CANCEL-Process] timers"))))
+                .body("", hasItem(allOf(
+                        hasEntry("processId", "timers"),
+                        hasEntry("processInstanceId", processInstanceId),
+                        hasEntry("nodeInstanceId", nodeInstanceId),
+                        hasKey("timerId"),
+                        hasEntry("description", "[SLA] Task"))))
+                .body("", hasItem(allOf(
+                        hasEntry("processId", "timers"),
+                        hasEntry("processInstanceId", processInstanceId),
+                        hasEntry("nodeInstanceId", nodeInstanceId),
+                        hasKey("timerId"),
+                        hasEntry("description", "Task-Boundary Timer"))));
+
+        given()
+                .when()
+                
.get("/management/processes/{processId}/instances/{processInstanceId}/nodeInstances/{nodeInstanceId}/timers",
 TIMERS, processInstanceId, nodeInstanceId)
+                .then()
+                .statusCode(200)
+                .body("$.size()", equalTo(2))
+                .body("", hasItem(allOf(
+                        hasEntry("processId", "timers"),
+                        hasEntry("processInstanceId", processInstanceId),
+                        hasEntry("nodeInstanceId", nodeInstanceId),
+                        hasKey("timerId"),
+                        hasEntry("description", "[SLA] Task"))))
+                .body("", hasItem(allOf(
+                        hasEntry("processId", "timers"),
+                        hasEntry("processInstanceId", processInstanceId),
+                        hasEntry("nodeInstanceId", nodeInstanceId),
+                        hasKey("timerId"),
+                        hasEntry("description", "Task-Boundary Timer"))));
+    }
+
     private String givenGreetingsProcess() {
         return given().contentType(ContentType.JSON)
                 .when()
diff --git 
a/springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/TaskTest.java
 
b/springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/TaskTest.java
index 66821bd1c0..c11f1f9831 100644
--- 
a/springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/TaskTest.java
+++ 
b/springboot/integration-tests/integration-tests-springboot-processes-it/src/test/java/org/kie/kogito/integrationtests/springboot/TaskTest.java
@@ -104,7 +104,7 @@ public class TaskTest extends BaseRestTest {
 
     @Test
     void testJsonSchemaFiles() {
-        long expectedJsonSchemas = 25;
+        long expectedJsonSchemas = 27;
         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