12.6. Task Permissions

12.6.1. Task Service and Process Engine

Human tasks are similar to any other external service that are invoked and implemented as a domain-specific service. As a human task is an example of such a domain-specific service, the process itself only contains a high-level, abstract description of the human task to be executed and a work item handler that is responsible for binding this (abstract) task to a specific implementation.
You can plug in any human task service implementation, such as the one that is provided by JBoss BPM Suite, or may register your own implementation. The JBoss BPM Suite provides a default implementation of a human task service based on the WS-HumanTask specification. If you do not need to integrate JBoss BPM Suite with another existing implementation of a human task service, you can use this service. The JBoss BPM Suite implementation manages the life cycle of the tasks (such as creation, claiming, completion) and stores the state of all the tasks, task lists, and other associated information. It also supports features like internationalization, calendar integration, different types of assignments, delegation, escalation and deadlines. You can find the code for the implementation in the jbpm-human-task module. The JBoss BPM Suite task service implementation is based on the WS-HumanTask (WS-HT) specification. This specification defines (in detail) the model of the tasks, the life cycle, and many other features.

12.6.2. Task Service API

The human task service exposes a Java API for managing the life cycle of tasks. This allows clients to integrate (at a low level) with the human task service. Note that, the end users should probably not interact with this low-level API directly, but use one of the more user-friendly task clients instead. These clients offer a graphical user interface to request task lists, claim and complete tasks, and manage tasks in general. The task clients listed below use the Java API to internally interact with the human task service. Of course, the low-level API is also available so that developers can use it in their code to interact with the human task service directly.
A task service (interface org.kie.api.task.TaskService) offers the following methods for managing the life cycle of human tasks:
              ...
              
              void start( long taskId, String userId );

              void stop( long taskId, String userId );

              void release( long taskId, String userId );

              void suspend( long taskId, String userId );

              void resume( long taskId, String userId );

              void skip( long taskId, String userId );

              void delegate(long taskId, String userId, String targetUserId);

              void complete( long taskId, String userId, Map<String, Object> results );
              
              ...
The common arguments passed to these methods are:
  • taskId: The ID of the task that we are working with. This is usually extracted from the currently selected task in the user task list in the user interface.
  • userId: The ID of the user that is executing the action. This is usually the id of the user that is logged in into the application.
To make use of the methods provided by the internal interface InternalTaskService, you need to manually cast to InternalTaskService. One method that can be useful from this interface is getTaskContent():
 Map<String, Object> getTaskContent( long taskId );
This method saves you from the complexity of getting the ContentMarshallerContext to unmarshall the serialized version of the task content. If you only want to use the stable or public API's, you can use the following method:
              Task taskById = taskQueryService.getTaskInstanceById(taskId);
              Content contentById = taskContentService.getContentById(taskById.getTaskData().getDocumentContentId());
              ContentMarshallerContext context = getMarshallerContext(taskById);
              Object unmarshalledObject = ContentMarshallerHelper.unmarshall(contentById.getContent(), context.getEnvironment(), context.getClassloader());
              if (!(unmarshalledObject instanceof Map)) {
                  throw new IllegalStateException(" The Task Content Needs to be a Map in order to use this method and it was: "+unmarshalledObject.getClass());
      
              }
              Map<String, Object> content = (Map<String, Object>) unmarshalledObject;
              return content;

12.6.3. Interacting with the Task Service

In order to get access to the Task Service API, it is recommended to let the Runtime Manager ensure that everything is setup correctly. From the API perspective, if you use the following approach, there is no need to register the Task Service with the Process Engine:
              ...
              RuntimeEngine engine = runtimeManager.getRuntimeEngine(EmptyContext.get());
              KieSession kieSession = engine.getKieSession();
              // Start a process
              kieSession.startProcess("CustomersRelationship.customers", params);
              // Do Task Operations
              TaskService taskService = engine.getTaskService();
              List<TaskSummary> tasksAssignedAsPotentialOwner = taskService.getTasksAssignedAsPotentialOwner("mary", "en-UK");
              
              // Claim Task
              taskService.claim(taskSummary.getId(), "mary");
              // Start Task
              taskService.start(taskSummary.getId(), "mary");

              ...

The Runtime Manager registers the Task Service with the Process Engine automatically. If you do not use the Runtime Manager, you have to set the LocalHTWorkItemHandler in the session to get the Task Service notify the Process Engine once the task completes. In JBoss BPM Suite, the Task Service runs locally to the Process and Rule Engine. This enables you to create multiple light clients for different Process and Rule Engine's instances. All the clients can share the same database.