cancel
Showing results for 
Search instead for 
Did you mean: 

Retrieving active timer duedates, and their Event names

richardmward
Champ in-the-making
Champ in-the-making
Hi,

I am looking for a way to retrieve the due dates for all currently active timer events, along with the names of the associated timer event. This is so that when my process is waiting on a timer, I am able to show the user the absolute time that that timer will fire.

I have found I can get jobs via the management service jobquery and that has the duedate, but I can't find any way to associate that back to the actual event (be it an intermediateCatchEvent or a boundaryEvent) so that I can get the name attribute.

And pointers in the right direction would be much appreciated!
4 REPLIES 4

vasile_dirla
Star Contributor
Star Contributor
I've implemented a test where I display all the current pending jobs and some details about the related event.
Hope you'll find it useful.
<code lang="java" linenumbers="normal">
  private void listCurrentPendingEvents(ProcessInstance processInstance) {
    List<Job> jobs = managementService.createJobQuery().list();
    if (jobs.size() > 0) {
      for (Job job : jobs) {
        JobEntity jobEntity = (JobEntity) job;

        String configuration = jobEntity.getJobHandlerConfiguration();
        String jobHandlerType = jobEntity.getJobHandlerType();
        // based on the jobHandlerType you can find the type of the Event
        // In the configuration you will find the nestedActivityId
        // check the implementation of the JobHandler for a better understanding
        // in case of IntermediateTimerEvent and BoundaryTimerEvent
        // the config is a json with the activityId as a property in it.
        if (jobHandlerType.equalsIgnoreCase(TimerExecuteNestedActivityJobHandler.TYPE) ||
                jobHandlerType.equalsIgnoreCase(TimerCatchIntermediateEventJobHandler.TYPE)
                ) {
          JSONObject cfgJson = new JSONObject(configuration);
          String nestedActivityId = (String) cfgJson.get("activityId");

          ActivityImpl eventActivity = ((ProcessDefinitionEntity) processEngine.getRepositoryService()
                  .getProcessDefinition(processInstance.getProcessDefinitionId())).findActivity(nestedActivityId);

          //since now you have the EventActivityId you can find more information via queries. (name.. definition ..etc)
          System.out.println(
                  "DueTime:" + jobEntity.getDuedate() + " EventActivityID = " + eventActivity.getId() + " of type " + eventActivity.getActivityBehavior()
                          .getClass().getSimpleName());
        } else {
          System.out.println("this is not Boundary Event or Intermediate event");
        }
      }
    } else {
      System.out.println("There are no pending jobs.");
    }
  }
</code>

richardmward
Champ in-the-making
Champ in-the-making
Thanks for the reply.

Having done some digging around this approach I am a little uncomfortable about using the value in jobHandlerConfiguration due to:

https://groups.google.com/d/msg/camunda-bpm-dev/HugUZxqwJF8/WHXvMNlK49kJ
<blockquote>
For the timers we do not need to join the JobDefinition, the HANDLER_CFG_ is the timerId. However, I would understand if you do not want to rely on that.
</blockquote>

<blockquote>
Secondly, the fact that the job configuration matches the activity id is an implementation detail that might change in future releases if there is need. So far, this database field is not exposed anywhere in the public API and I think we should keep it that way.
</blockquote>

I have managed to find an approach that will give me access to intermediate timers, but the boundary timer gives me the user task flow element it is associated to, rather than the boundary event itself. I wonder if there is a link there somewhere I could use to get the timer it is using?

<code>
BpmnModel model = activitiRule.getRepositoryService().getBpmnModel(processInstance.getProcessDefinitionId());
Map<String, NamedDate> namedDates = new HashMap<>();

for (Job job : jobs) {
    Execution execution = activitiRule.getRuntimeService().createExecutionQuery().executionId(job.getExecutionId()).singleResult();
    FlowElement element = model.getFlowElement(execution.getActivityId());
    namedDates.put(element.getId(), new NamedDate(element.getName(), job.getDuedate()));
}
</code>

jbarrez
Star Contributor
Star Contributor
What is being said on other forums, is their business. We always strive for maximum backwards compatibility. Changing that json would be break many installation and we have no intention of doing that.

But you are correct: you can use the bpmn model for this.

> I wonder if there is a link there somewhere I could use to get the timer it is using?

Hmm not one that generically works. A boundary event has an 'attachedToRef' to indicate to what it is attached to, but you can have multiple ones. So you can't really rely on that attribute….

richardmward
Champ in-the-making
Champ in-the-making
Many thanks for info. It is good to know that JSON is unlikely to change. We can put a unit test into our project to flag up if it did anyway, mitigating risk.