Java API 7.2 - How to get all Usertasks of a process instance?

2,163 views
Skip to first unread message

kwma...@gmail.com

unread,
Jan 31, 2015, 6:44:06 AM1/31/15
to camunda-...@googlegroups.com
Hi Camunda Community,

I am wondering how to get all Usertasks for a process instance - independently of the tasks "runtime state".

E.g. if I have a process that has three Usertasks and I would like to get the name/id/input variables etc. of all three tasks and not only of those where the runtime "token" also passed by or is waiting.

What I tried is:

final HistoricProcessInstance historicProcessInstance = processEngine.getHistoryService().createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
final ProcessDefinitionQuery processDefinition = processEngine.getRepositoryService().createProcessDefinitionQuery().processDefinitionId(historicProcessInstance.getProcessDefinitionId());
final List<Task> tasks = getProcessEngine().getTaskService().createTaskQuery().processInstanceId(processInstanceId).list();
// final jhghj
final List<HistoricTaskInstance> unfinished = getProcessEngine().getHistoryService().createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).unfinished().list();
final List<HistoricTaskInstance> finished = getProcessEngine().getHistoryService().createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).finished().list();
final List<Task> tasks2 = getProcessEngine().getTaskService().createTaskQuery().processDefinitionId(historicProcessInstance.getProcessDefinitionId()).list();
final List<HistoricTaskInstance> historicTasks = getProcessEngine().getHistoryService().createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).list();

None of these queries provides me with the information I need?

Any idea how to get the definition info of really all (user) tasks of a process diagram via java API?

Thanks & Regards
Kristian

kwma...@gmail.com

unread,
Jan 31, 2015, 7:18:16 AM1/31/15
to camunda-...@googlegroups.com, kwma...@gmail.com
Possibly like so?:

final Collection<UserTask> userTasks = getProcessEngine().getRepositoryService().getBpmnModelInstance(historicProcessInstance.getProcessDefinitionId()).getModelElementsByType(org.camunda.bpm.model.bpmn.instance.UserTask.class);

Good idea (e.g. performance critical)?

Regards
Kristian



Sebastian Menski

unread,
Jan 31, 2015, 7:18:32 AM1/31/15
to camunda-...@googlegroups.com, kwma...@gmail.com
Hi Kristian,

you could use the repository service to get the bpmn model instance of the process [1]. And than get all user tasks of the process [2].

Cheers,
Sebastian

kwma...@gmail.com

unread,
Jan 31, 2015, 7:31:12 AM1/31/15
to camunda-...@googlegroups.com, kwma...@gmail.com
Thanks Sebastian, I will have a look at the Test next week in more detail. Seems I am on the right path :-)

Sebastian Menski

unread,
Jan 31, 2015, 7:36:21 AM1/31/15
to camunda-...@googlegroups.com, kwma...@gmail.com
Hi Kristian,

Good idea (e.g. performance critical)? 

The repository caches the model instances. But please be aware that the model API wasn't thread safe with the
7.2.0 release [1]. This was fixed with 7.3.0-alpha1.

Cheers,
Sebastian

kwma...@gmail.com

unread,
Feb 2, 2015, 3:19:54 AM2/2/15
to camunda-...@googlegroups.com, kwma...@gmail.com
OK thanks, good to know!

kwma...@gmail.com

unread,
Feb 2, 2015, 3:32:16 AM2/2/15
to camunda-...@googlegroups.com, kwma...@gmail.com
Hi Sebastian,

I can get all the UserTasks for a process (definition) as you mentioned which is very nice. My question now is how to get/order them in a kind of "logical" order. E.g. in a typical waterfall-like multilayered approval process, there would be given a sequential order.

Is there a way (for such simple cases) to get (identify) the 1rst userTask in the process definition and then get "following" user task?

Regards
Kristian

Sebastian Menski

unread,
Feb 2, 2015, 3:58:22 AM2/2/15
to camunda-...@googlegroups.com, kwma...@gmail.com
Hi Kristian,

I'm not aware of any general way to "order" the user task by there position in the process. You could traverse the process graph but
if there exist parallel sequence flows, cycles or boundary events the ordering isn't obvious. 

Maybe it is possible to add additional information to the user tasks during creation of the process?

Cheers,
Sebastian

kwma...@gmail.com

unread,
Feb 2, 2015, 6:39:17 AM2/2/15
to camunda-...@googlegroups.com, kwma...@gmail.com
Hi Sebastian,

traversing the graph is to much details at the moment :-)

I also thought about setting variables after process creation, however I would like to get a more "standardized" solution that is also visible at design time (maybe with validation checks at runtime (after deployment)?)

My currently favoured approach is to go via a "extension variable" (maybe wrong wording) like in this snippet: https://github.com/camunda/camunda-consulting/blob/master/snippets/extension-attributes-for-user-tasks/src/main/java/com/camunda/bpm/demo/extension_attributes_for_user_tasks/EscalationStartTaskListener.java

So every Usertask beeing a approval task has to have an extension variable like "ApprovalTask". However, after a task has been created, I don't see a quick way to get from a HistoricTaskInstance or a Task to the UserTask, like one can do with delegateTask:

UserTask userTask = delegateTask.getBpmnModelElementInstance();

Is there something like this or do I have to go via such engine queries:

final Task task = processEngine.getTaskService().createTaskQuery().taskId(taskInstance.getId()).singleResult();
final Collection<UserTask> userTasks = processEngine.getRepositoryService().getBpmnModelInstance(task.getProcessDefinitionId()).getModelElementsByType(org.camunda.bpm.model.bpmn.instance.UserTask.class);
for (final UserTask userTask : userTasks) {
final String userTaskId = userTask.getId();
final String taskInstanceId = task.getTaskDefinitionKey();
if (userTaskId.equals(taskInstanceId)) {
final ExtensionElements extensionElements = userTask.getExtensionElements();
final Collection<CamundaProperty> properties = extensionElements.getElementsQuery().filterByType(CamundaProperties.class).singleResult().getCamundaProperties();
for (final CamundaProperty camundaProperty : properties) {
camundaProperty.getCamundaName();
camundaProperty.getCamundaValue();
}
}
}

Regards
Kristian

Sebastian Menski

unread,
Feb 2, 2015, 7:03:33 AM2/2/15
to camunda-...@googlegroups.com, kwma...@gmail.com
Hi Kristian,

you can use the task id resp. the definition key during runtime to find a task without iterating:

final Task task = processEngine.getTaskService().createTaskQuery().taskId(taskInstance.getId()).singleResult();

final UserTask userTask = processEngine.getRepositoryService().getBpmnModelInstance(task.getProcessDefinitionId())
                           
.getModelElementById(task.getTaskDefinitionKey());

Cheers,
Sebastian
Reply all
Reply to author
Forward
0 new messages