Chapter 21. Remote API

Red Hat JBoss BPM Suite provides various ways how to access the execution server in Business Central remotely including REST, JMS, SOAP, and EJB interfaces. Moreover, it provides remote Java API which allows developers to work with the RuntimeEngine interface while remote calls are executed in the background, using either REST or JMS.

Note

It is not recommended to use Business Central remote APIs to any further extent, with the exception of the Knowledge Store REST API. Instead, Intelligent Process Server should be used. Both execution servers can be configured to use the same data source, thus processes and tasks started on one server are accessible from the other server. See section Unified Execution Servers of Red Hat JBoss BPM Suite Administration and Configuration Guide for more details.

21.1. REST API

Representational State Transfer (hereinafter referred to as REST) is a style of software architecture of distributed systems. It enables a highly abstract client-server communication: clients initiate requests to servers to a particular URL with parameters if needed and servers process the requests and return appropriate responses based on the requested URL. The requests and responses are built around the transfer of representations of resources. A resource can be any coherent and meaningful concept that may be addressed, such as a repository, a process, a rule, and so on.

Red Hat JBoss BPM Suite and Red Hat JBoss BRMS provide a REST API for individual application components. The REST API implementations differ slightly:

  • Knowledge Store REST API calls interact with the artifact repository and are mostly asynchronous, which means that they continue running after the call as a job. The calls return a job ID which can be used after the REST API call was performed to request the job status and verify whether the job finished successfully. Parameters of these calls are provided in the form of JSON entities. See Section 21.1.1, “Knowledge Store REST API”.

The following APIs are only available in Red Hat JBoss BPM Suite.

All REST API calls use the following URL with the request body: http://SERVER:PORT/business-central/rest/REQUEST_BODY.

Calls on Resources Are Not Supported

It is not possible to issue REST API calls on project resources, such as rule files, work item definitions, process definition files, and so on. Operations on such files should be performed using Git and its REST API directly.

21.1.1. Knowledge Store REST API

REST API calls to the Knowledge Store REST API allow you to manage the organization units, repositories, and projects.

All POST and DELETE calls return details about the request as well as a job ID that can be used to request the job status and verify whether the job finished successfully. The GET calls return information about repositories, projects, and organizational units.

Parameters and results of these calls are provided in the form of JSON entities. Java classes for different entities are available in the org.guvnor.rest.client package and are referenced in the following text.

21.1.1.1. Job Calls

Most Knowledge Store REST calls return a job ID after they are issued. This is necessary as the calls are asynchronous and it is required to be able to reference the job later to check its status as it goes through a job lifecycle.

During its lifecycle, a job can have the following statuses:

Table 21.1. Job Statuses

StatusDescription

ACCEPTED

The job was accepted and is being processed.

BAD_REQUEST

The request was not accepted as it contained incorrect content.

RESOURCE_NOT_EXIST

The requested resource (path) does not exist.

DUPLICATE_RESOURCE

The resource already exists.

SERVER_ERROR

An error on the server side occurred.

SUCCESS

The job finished successfully.

FAIL

The job failed.

APPROVED

The job was approved.

DENIED

The job was denied.

GONE

The job ID could not be found. A job can be GONE in the following cases:

  • The job was explicitly removed.
  • The job finished and has been deleted from a status cache. A job is removed from a status cache after the cache has reached its maximum capacity.
  • The job never existed.

The following job calls are provided:

[GET] /jobs/JOB_ID

Returns a status of the given JOB_ID.

Example 21.1. Formatted Response to GET Job Call on Repository Clone Request

{
  "status" : "SUCCESS",
  "jobId" : "1377770574783-27",
  "result" : "Alias: testInstallAndDeployProject, Scheme: git, Uri: git://testInstallAndDeployProject",
  "lastModified" : 1377770578194,
  "detailedResult" : null
}
[DELETE] /jobs/JOB_ID
Removes a job with the given JOB_ID. If the job is not being processed yet, the call will remove the job from the job queue. However, this call will not cancel or stop an ongoing job.

Both of these job calls return a JobResult instance.

21.1.1.2. Organizational Unit Calls

Organizational unit calls are calls to the Knowledge Store that allow you to manage its organizational units which are useful to model departments and divisions. An organization unit can hold multiple repositories.

The following organizational unit calls are provided:

[GET] /organizationalunits/

Returns a list of all organizational units.

Example 21.2. Organizational Unit List in JSON Format

[ {
  "name" : "EmployeeWage",
  "description" : null,
  "owner" : "Employee",
  "defaultGroupId" : "org.bpms",
  "repositories" : [ "EmployeeRepo", "OtherRepo" ]
}, {
  "name" : "OrgUnitName",
  "description" : null,
  "owner" : "OrgUnitOwner",
  "defaultGroupId" : "org.group.id",
  "repositories" : [ "repository-name-1", "repository-name-2" ]
} ]
[GET] /organizationalunits/ORGANIZATIONAL_UNIT_NAME
Returns information about a specific organizational unit.
[POST] /organizationalunits/

Creates an organizational unit in the Knowledge Store. The organizational unit is defined as a JSON entity. The call requires an OrganizationalUnit instance and returns a CreateOrganizationalUnitRequest instance.

Example 21.3. Organizational Unit in JSON Format

{
  "name" : "testgroup",
  "description" : "",
  "owner" : "tester",
  "repositories" : ["testGroupRepository"]
}
[POST] /organizationalunits/ORGANIZATIONAL_UNIT_NAME

Updates the details of an existing organizational unit.

Both the name and owner fields in the required UpdateOrganizationalUnit instance can be left empty. Neither the description field nor the repository association can be updated using this operation.

Example 21.4. Update Organizational Unit Input in JSON Format

{
  "owner" : "NewOwner",
  "defaultGroupId" : "org.new.default.group.id"
}
[DELETE] /organizationalunits/ORGANIZATIONAL_UNIT_NAME
Removes a specified organizational unit.
[POST] /organizationalunits/ORGANIZATIONAL_UNIT_NAME/repositories/REPOSITORY_NAME
Adds a repository to an organizational unit.
[DELETE] /organizationalunits/ORGANIZATIONAL_UNIT_NAME/repositories/REPOSITORY_NAME
Removes a repository from an organizational unit.

21.1.1.3. Repository Calls

Repository calls are calls to the Knowledge Store that allow you to manage its Git repositories and their projects.

The following repository calls are provided:

[GET] /repositories

Returns a list of repositories in the Knowledge Store.

Example 21.5. Response of Repository Call

[
  {
    "name": "bpms-assets",
    "description": "generic assets",
    "userName": null,
    "password": null,
    "requestType": null,
    "gitURL": "git://bpms-assets"
  },
  {
    "name": "loanProject",
    "description": "Loan processes and rules",
    "userName": null,
    "password": null,
    "requestType": null,
    "gitURL": "git://loansProject"
  }
]
[GET] /repositories/REPOSITORY_NAME
Returns information about a specific repository.
[DELETE] /repositories/REPOSITORY_NAME
Removes a repository.
[POST] /repositories/

Creates or clones a repository defined by a JSON entity.

Example 21.6. JSON Entity with Details about Repository to Be Cloned

{
  "name": "myClonedRepository",
  "organizationalUnitName": "example",
  "description": "",
  "userName": "",
  "password": "",
  "requestType": "clone",
  "gitURL": "git://localhost/example-repository"
}

Example 21.7. JSON Entity with Details about Repository to Be Created

{
  "name": "myCreatedRepository",
  "organizationalUnitName": "example",
  "description": "",
  "userName": "",
  "password": "",
  "requestType": "create",
  "gitURL": "git://localhost/example-repository"
}
Important

Make sure you always include the organizationalUnitName key-value pair in your query and that the specified organization unit exists before you create or clone the repository.

[GET] /repositories/REPOSITORY_NAME/projects/

Returns a list of projects in a specific repository as a JSON entity.

Example 21.8. JSON Entity with Details about Existing Projects

[ {
  "name" : "my-project-name",
  "description" : "A project to illustrate a REST output.",
  "groupId" : "com.acme",
  "version" : "1.0"
}, {
  "name" : "yet-another-project-name",
  "description" : "Yet another project to illustrate a REST output.",
  "groupId" : "com.acme",
  "version" : "2.2.1"
} ]
[POST] /repositories/REPOSITORY_NAME/projects/

Creates a project in a repository.

Example 21.9. Request Body That Defines Project to Be Created

{
  "name" : "NewProject",
  "description" : "Description of the new project.",
  "groupId" : "org.redhat.test",
  "version" : "1.0.0"
}
[DELETE] /repositories/REPOSITORY_NAME/projects/PROJECT_NAME
Removes a project in a repository.

21.1.1.4. Maven Calls

Maven calls are calls to a project in the Knowledge Store that allow you to compile and deploy the project resources.

The following Maven calls are provided:

[POST] /repositories/REPOSITORY_NAME/projects/PROJECT_NAME/maven/compile/
Compiles the project. Equivalent to mvn compile. Returns a CompileProjectRequest instance.
[POST] /repositories/REPOSITORY_NAME/projects/PROJECT_NAME/maven/install/
Installs the project. Equivalent to mvn install. Returns a InstallProjectRequest instance.
[POST] /repositories/REPOSITORY_NAME/projects/PROJECT_NAME/maven/test/
Compiles and runs the tests. Equivalent to mvn test. Returns a TestProjectRequest instance.
[POST] /repositories/REPOSITORY_NAME/projects/PROJECT_NAME/maven/deploy/
Deploys the project. Equivalent to mvn deploy. Returns a DeployProjectRequest instance.

21.1.2. Deployment REST API

The KIE module JAR files can be deployed or undeployed using the Business Central UI or the REST API calls.

Deployment units are represented by a unique deployment ID consisting of the following elements separated by colons:

  1. Group ID
  2. Artifact ID
  3. Version
  4. KIE base ID (optional)
  5. KIE session ID (optional)

21.1.2.1. Deployment Calls

The following deployment calls are provided:

[GET] /deployment/
Returns a list of all available deployed instances in a JaxbDeploymentUnitList instance.
[GET] /deployment/processes
Returns a list of all available deployed process definitions in a JaxbProcessDefinitionList instance.
[GET] /deployment/DEPLOYMENT_ID
Returns an instance of JaxbDeploymentUnit containing the information about a deployment unit, including its configuration.
[POST] /deployment/DEPLOYMENT_ID/deploy

Deploys a deployment unit referenced by DEPLOYMENT_ID. The call returns a JaxbDeploymentJobResult instance with a status of the request.

The deploy operation is asynchronous. Use the described GET calls to get a status of the deployment.

When a project is deployed, it is activated by default: new process instances can be started using the process definitions and other information in the deployment. However, at later point in time, users may want to make sure that the deployment is no longer used without necessarily aborting or stopping the existing (running) process instances. To do so, the deployment can first be deactivated before it will be removed at a later date.

Note

Configuration options such as the runtime strategy should be defined before deploying the JAR files and cannot be changed post deployment.

To override the session strategy specified in the deployment descriptor, use the strategy query parameter. The following not case-sensitive values are supported:

  • SINGLETON
  • PER_REQUEST
  • PER_PROCESS_INSTANCE

For example:

[POST] /deployment/DEPLOYMENT_ID/deploy?strategy=PER_REQUEST

To use a specific merge mode in the deployment request, specify the mergemode query parameter. The following not case-sensitive values are supported:

  • KEEP_ALL
  • OVERRIDE_ALL
  • OVERRIDE_EMPTY
  • MERGE_COLLECTIONS

It is possible to post a deployment descriptor or its fragment with the deployment request, which allows to override other deployment descriptors. To do so, set a content type of the request to application/xml and make sure the request body is a valid deployment descriptor content, for example:

<deployment-descriptor xsi:schemaLocation="http://www.jboss.org/jbpm deployment-descriptor.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <audit-mode>JMS</audit-mode>
</deployment-descriptor>
Warning

To avoid the Unsupported Media Type error on Oracle WebLogic Server, make sure the deployment-descriptor is always provided, even as an empty-element tag, and the header is specified as Content-Type. See the example call:

curl -v -H 'Content-Type: application/xml' -u bpmsAdmin --data "<deployment-descriptor/>" -X POST 'localhost:7001/business-central/rest/deployment/com.sample:bpm-processes:1.1/deploy'
[POST] /deployment/DEPLOYMENT_ID/undeploy

Undeploys a deployment unit with a specified DEPLOYMENT_ID and returns a JaxbDeploymentJobResult instance with a status of the request.

The undeploy operation is asynchronous. Use the described GET calls to get the status of the deployment.

Note

The deploy and undeploy operations can fail if one of the following is true:

  • An identical job has already been submitted to the queue and has not yet completed.
  • The amount of deploy and undeploy jobs submitted but not yet processed exceeds the job cache size.
[POST] /deployment/DEPLOYMENT_ID/activate

Activates a deployment. Returns a JaxbDeploymentJobResult instance with a status of the request.

The activate operation is asynchronous.

[POST] /deployment/DEPLOYMENT_ID/deactivate

Deactivates a deployment. Returns a JaxbDeploymentJobResult instance with a status of the request.

The deactivate operation is asynchronous.

Note
  • The deactivate operation ensures that no new process instances can be started with the existing deployment.
  • If it is decided that a deactivated deployment should be reactivated instead of deleted, the activate operation should be used to reactivate the deployment. A deployment is always activated by default when it is initially deployed.
Warning

In version 6.4 of the product, start timer events keep starting new process instances after a deployment is deactivated. This is a known issue.

[GET] /deployment/DEPLOYMENT_ID/processes
Lists all available process definitions in a given deployment unit. Returns an instance of JaxbProcessDefinitionList.

21.1.2.2. Asynchronous Calls

The following deployment calls described in the previous section are asynchronous REST operations:

  • /deployment/DEPLOYMENT_ID/deploy
  • /deployment/DEPLOYMENT_ID/undeploy
  • /deployment/DEPLOYMENT_ID/activate
  • /deployment/DEPLOYMENT_ID/deactivate

Asynchronous calls allow a user to issue a request and continue to the next task before the previous task in the queue is finished. Therefore, the information received after posting a call does not reflect the actual state or eventual status of the operation. It returns a status 202 upon the completion of the request: "The request has been accepted for processing, but the processing has not been completed."

This means that:

  • The POST request has been successfully queued, but the result of the actual operation (deploying or undeploying the deployment unit) cannot be determined from this code. Interrogate the JaxbDeploymentUnit object returned by the GET /deployment/DEPLOYMENT_ID call to obtain that state.
  • The JaxbDeploymentUnit object returned using the GET request is only valid for the point in time which it was checked. Its status may change after the GET request has completed.

21.1.3. Process Image REST API

Red Hat JBoss BPM Suite allows you to get a diagram of your process in Business Central through the remote REST API. To get the diagram, you need to generate the image based on the SVG source first, which is done automatically by the process designer when you save a process definition.

To ensure that the process is saved in the process designer as SVG and is added to the kJAR, set <storesvgonsave enabled="true"/> in the /org.kie.workbench.KIEWebapp/profiles/jbpm.xml file in business-central.war. SVGImageProcessor adds further annotations based on the audit log data. You can extend SVGImageProcessor further for more advanced visualizations.

Note

It is recommended to use Intelligent Process Server instead of Business Central. Chapter 18, Intelligent Process Server UI Extension provides a richer set of REST endpoints, including process diagram images as well as process and task forms.

The following process image REST operations are provided by Business Central:

[GET] /runtime/DEPLOYMENT_ID/process/PROCESS_DEFINITION_ID/image
Returns an SVG image of the process definition diagram.
[GET] /runtime/DEPLOYMENT_ID/process/PROCESS_DEFINITION_ID/image/PROCESS_INSTANCE_ID
Returns an SVG image of the process instance diagram, with highlighted currently active nodes.

21.1.4. Runtime REST API

Runtime REST API provided by Business Central allows you to work with its underlying execution server, including process engine, task service, and business rule engine, and manipulate runtime data.

Note

It is recommended to use Intelligent Process Server instead of Business Central for all remote calls. See Chapter 16, The REST API for Intelligent Process Server Execution for more information about equivalent REST endpoints.

With the exception of execute operations (see Section 21.1.6, “Execute Operations”), all the other REST calls can use JAXB or JSON. The calls are synchronous and return the requested data as JAXB objects by default. When using JSON, the JSON media type (application/json) should be added to the ACCEPT header of the REST call.

21.1.4.1. Query Parameters

The Runtime REST API calls can have various query parameters. To add a parameter to a call, add the ? symbol to the URL and a parameter name with its value. For example, http://localhost:8080/business-central/rest/task/query?workItemId=393 returns a list of all tasks (TaskSummary instances) based on the work item with ID 393. Note that parameters and their values are case sensitive.

21.1.4.1.1. Map Parameters

Some runtime REST API calls can use the Map parameter. That means it is possible to submit key-value pairs to the operation using a query parameter prefixed with the map_ keyword. For example,

map_age=5000

is translated as

{ "age" => Long.parseLong("5000") }

Example 21.10. GET Call That Returns All Tasks to Locally Running Application Using curl

curl -v -H 'Accept: application/json' -u eko 'localhost:8080/business-central/rest/tasks/'

To perform the runtime REST calls from your Java application, see Section 21.5, “Remote Java API”.

While interacting with the Remote API, some classes are to be included in the deployment. This enables users to pass instances of their own classes as parameters to certain operations. The REST calls that start with /task often do not contain any information about the associated deployment. In this case, an extra query parameter deploymentId is added to the REST call allowing the server to find the appropriate deployment class and deserialize the information passed with the call.

21.1.4.1.2. Pagination

The pagination parameters allow you to define pagination of REST call results. The following pagination parameters are available:

page or p
A number of the page to be returned. The default value is 1, which means that page number 1 is returned.
pageSize or s
A number of items per page. The default value is 10.

If both the long option and the short option are included in a URL, the longer version of the parameter takes precedence. When no pagination parameters are included, the returned results are not paginated.

Pagination parameters can be applied to the following REST requests:

  • /task/query
  • /history/instances
  • /history/instance/*
  • /task/query

Example 21.11. REST Request Body with Pagination Parameter

/history/instances?page=3&pageSize=20
/history/instances?p=3&s=20
21.1.4.1.3. Object Data Type Parameters

By default, any object parameters provided in a REST call are considered to be strings. If you need to explicitly define the data type of a parameter in a call, you can do so by adding one of the following values to the parameter:

  • \d+i: Integer
  • \d+l: Long

Example 21.12. REST Request Body with Integer Parameter

/rest/runtime/business-central/process/org.jbpm.test/start?map_var1=1234i

Note that the intended use of these object parameters is to define data types of send signal and process variable values. For example, consider the use in the startProcess command in the execute operation. See Section 21.1.6, “Execute Operations”.

21.1.4.2. Runtime Calls

Runtime REST calls allow you to work with runtime data such as process instances, signals, and work items.

Note

If you want to use other features of the execution engine that are not available as direct REST calls, look at generic execute operations. See Section 21.1.6, “Execute Operations”.

21.1.4.2.1. Process Calls

Process calls allow you to start new process instances, abort the existing ones, and get details about running process instances and their variables.

The following runtime process calls are provided:

[POST] /runtime/DEPLOYMENT_ID/process/PROCESS_DEFINITION_ID/start

Starts a new instance of PROCESS_DEFINITION_ID process and returns JaxbProcessInstanceResponse with information about the process instance.

This operation accepts map parameters. For more information, see Section 21.1.4.1.1, “Map Parameters”. If you want to pass custom classes, use Remove Java API. See Section 21.5, “Remote Java API”.

[POST] /runtime/DEPLOYMENT_ID/withvars/process/PROCESS_DEFINITION_ID/start
Starts a new instance of PROCESS_DEFINITION_ID process and returns JaxbProcessInstanceWithVariablesResponse with information about the process instance including process variables.
[GET] /runtime/DEPLOYMENT_ID/process/PROCESS_DEFINITION_ID/startform
If the PROCESS_DEFINITION_ID process exists, returns JaxbProcessInstanceFormResponse containing a URL where the process form can be found.
[POST] /runtime/DEPLOYMENT_ID/process/instance/PROCESS_INSTANCE_ID/abort
Aborts the process instance and returns JaxbGenericResponse indicating success or failure of the operation.
[GET] /runtime/DEPLOYMENT_ID/process/instance/PROCESS_INSTANCE_ID
Returns JaxbProcessInstanceResponse with details about the active process instance.
[GET] /runtime/DEPLOYMENT_ID/withvars/process/instance/PROCESS_INSTANCE_ID
Returns JaxbProcessInstanceWithVariablesResponse with details about the active process instance including process variables.
[GET] /runtime/DEPLOYMENT_ID/process/instance/PROCESS_INSTANCE_ID/variable/VARIABLE_NAME
Returns the VARIABLE_NAME variable in the PROCESS_INSTANCE_ID process instance. If the variable is primitive, the variable value is returned.
21.1.4.2.2. Signal Calls

Signal calls allow you to send a signal to a deployment or a particular process instance.

All signal calls accept the following query parameters:

  • signal: the name of the signal event (required).
  • event: the data associated with this event.

The following signal calls are provided:

[POST] /runtime/DEPLOYMENT_ID/signal

Sends a signal event to all active process instances as well as process definitions with a Signal start event (see Section 11.5.1, “Start Events”) in the given deployment unit. Returns JaxbGenericResponse with the status of the operation.

Example 21.13. Signal Call Example

/runtime/DEPLOYMENT_ID/signal?signal=SIGNAL_CODE
Warning

There is a known issue preventing this operation to work with deployment units using the Per Process Instance runtime strategy.

[POST] /runtime/DEPLOYMENT_ID/process/instance/PROCESS_INSTANCE_ID/signal

Sends a signal event to the given process instance and returns JaxbGenericResponse with a status of the operation.

Example 21.14. Local Signal Invocation and Its REST Version

ksession.signalEvent("MySignal", "value", 23l);
curl -v -u admin 'localhost:8080/business-central/rest/runtime/myDeployment/process/instance/23/signal?signal=MySignal&event=value'
[POST] /runtime/DEPLOYMENT_ID/withvars/process/instance/PROCESS_INSTANCE_ID/signal
Sends a signal event to the given process instance and returns JaxbProcessInstanceWithVariablesResponse.
21.1.4.2.3. Work Item Calls

Work item calls allow you to complete or abort a particular work item as well as get details about a work item instance.

The parameters of work item calls must match the following regular expressions:

  • DEPLOYMENT_ID: (:[\\w\\.-]){2,2}(:[\\w\\.-]*){0,2}}
  • WORK_ITEM_ID: [0-9]+

The following work item calls are provided:

[GET] /runtime/DEPLOYMENT_ID/workitem/WORK_ITEM_ID
Returns JaxbWorkItemResponse with details about a work item with the given WORK_ITEM_ID.
[POST] /runtime/DEPLOYMENT_ID/workitem/WORK_ITEM_ID/complete

Completes the given work item.

The call accepts map parameters containing information about the results. See Section 21.1.4.1.1, “Map Parameters”.

Example 21.15. Local Invocation and Its REST Version

Map<String, Object> results = new HashMap<String, Object>();

results.put("one", "done");
results.put("two", 2);

kieSession.getWorkItemManager().completeWorkItem(23l, results);
curl -v -u admin 'localhost:8080/business-central/rest/runtime/myDeployment/workitem/23/complete?map_one=done&map_two=2i'
[POST] /runtime/DEPLOYMENT_ID/workitem/WORK_ITEM_ID/abort
Aborts the given work item.
21.1.4.2.4. History Calls

The history calls allow you to access audit log information about process instances.

The following history calls are provided:

[GET] /history/instances
Returns logs of all process instances.
[GET] /history/instance/PROCESS_INSTANCE_ID
Returns all logs of the given process instance, including subprocesses.
[GET] /history/instance/PROCESS_INSTANCE_ID/child
Returns logs of subprocesses of the given process instance.
[GET] /history/instance/PROCESS_INSTANCE_ID/node
Returns logs of all nodes of the given process instance.
[GET] /history/instance/PROCESS_INSTANCE_ID/node/NODE_ID
Returns logs of the specified node of the given process instance.
[GET] /history/instance/PROCESS_INSTANCE_ID/variable
Returns variable logs of the given process instance.
[GET] /history/instance/PROCESS_INSTANCE_ID/variable/VARIABLE_ID
Returns a variable log of the specified variable of the given process instance.
[GET] /history/process/PROCESS_INSTANCE_ID
Returns logs of the given process instance, excluding logs of its nodes and variables.
[POST] /history/clear
Clears all process, variable, and node logs.
History Variable Calls

In the following REST calls, variables are used to search process instances, variables, and their values.

The calls below accept an optional boolean query parameter:

  • activeProcesses: if set to true, only the information from active process instances is returned.

The following history variable calls are provided:

[GET] /history/variable/VARIABLE_ID
Returns variable logs of the given process variable.
[GET] /history/variable/VARIABLE_ID/value/VALUE

Returns variable logs of the given process variable with the specified value.

Example 21.16. Local Invocation and Its REST Version

auditLogService.findVariableInstancesByNameAndValue("countVar", "three", true);
curl -v -u admin 'localhost:8080/business-central/rest/history/variable/countVar/value/three?activeProcesses=true'
[GET] /history/variable/VARIABLE_ID/instances
Returns process instance logs for the processes that contain the given process variable.
[GET] /history/variable/VARIABLE_ID/value/VALUE/instances
Returns process instance logs for the processes that contain the given process variable with the specified value.

21.1.4.3. Task Calls

The task calls allow you to execute task operations as well as query the tasks and get task details.

The following task calls are provided:

[GET] /task/TASK_ID
Returns JaxbTask with details about the given task.
[POST] /task/TASK_ID/TASK_OPERATION
Executes the given task operation. For more information, see Section 21.1.4.3.1, “Task Operations”.
[GET] /task/TASK_ID/content
Returns JaxbContent with a content of the given task. For more information, see Section 21.1.4.3.2, “Content Operations”.
[GET] /task/content/CONTENT_ID
Returns JaxbContent with a task content. For more information, see Section 21.1.4.3.2, “Content Operations”.
[GET] /task/query
Another entry point for the /query/runtime/task calls of the REST Query API. See Section 21.1.5, “REST Query API”.
21.1.4.3.1. Task Operations

The following operations can be executed on a task:

Table 21.2. Task Operations

TaskAction

activate

Activate the task.

claim

Claim the task.

claimnextavailable

Claim the next available task assigned to the user.

complete

Complete the task with the specified map parameters. See Section 21.1.4.1.1, “Map Parameters”.

delegate

Delegate the task to the user specified by the targetEntityId query parameter.

exit

Exit the task.

This operation can be performed by any user or a group specified as the administrator of a human task. If the task does not specify any values, the system automatically adds user Administrator and group Administrators to the task.

fail

Fail the task.

forward

Forward the task.

release

Release the task.

resume

Resume the task.

skip

Skip the task.

start

Start the task.

stop

Stop the task.

suspend

Suspend the task.

nominate

Nominate either a user or a group, specified by the user or the group query parameter, for the task.

21.1.4.3.2. Content Operations

Both task and content operations return the serialized content associated with the given task.

The content associated with a task is stored in a database in a serialized form either as a string with XML data or a map with several different key-value pairs. The content is serialized using the algorithm based on Protocol Buffers: protobuf. This serialization process is usually executed by the static methods in the org.jbpm.services.task.utils.ContentMarshallerHelper class.

If the client that calls the task content operation do not have access to the org.jbpm.services.task.utils.ContentMarshallerHelper class, the task content cannot be deserialized. When using the REST call to obtain task content, the content is first deserialized using the ContentMarshallerHelper class and then serialized with the common Java serialization mechanism.

Due to restrictions of REST operations, only the objects for which the following is true can be returned by the task content operations:

  • The requested objects are instances of a class that implements the Serializable interface. In the case of Map objects, they only contain values that implement the Serializable interface.
  • The objects are not instances of a local class, an anonymous class, or arrays of a local or an anonymous class.
  • The object classes are present on the class path of the server application.

21.1.5. REST Query API

The REST Query API allows developers to query tasks, process instances, and their variables. The operations results are grouped by the process instance they belong to.

21.1.5.1. URL Layout

The rich query operations can be performed using the following URLs:

  • http://SERVER:PORT/business-central/rest/query/runtime/task

    Rich query for task summaries and process variables.

  • http://SERVER:PORT/business-central/rest/query/runtime/process

    Rich query for process instances and process variables.

You can specify a number of different query parameters. For more information, see Section 21.1.5.2, “Query Parameters”.

21.1.5.2. Query Parameters

In the text below, query parameters are strings such as processInstanceId, taskId, or tid. These query parameters are not case sensitive, with the exception of those also specifying the name of a user-defined variable. Parameters are the values passed with query parameters, for example org.process.frombulator, 29, or harry.

When you submit a REST call to the query operation, the URL could be similar to the following:

http://localhost:8080/business-central/rest/query/runtime/process?processId=org.process.frombulator&piid=29

A query containing multiple query parameters searches for their intersection. However, many of the query parameters described later can be entered multiple times. In such case, the query searches for any results that match one or more of the entered values.

Example 21.17. Repeated Query Parameters

processId=org.example.process&processInstanceId=27&processInstanceId=29

This process instance query returns a result that contains information about process instances with the org.example.process process definition and ID 27 or 29.

Warning

When running Business Central on WebSphere application server, the server ignores the parameters of REST Query API calls without a value (for example http://localhost:9080/business-central/rest/query/runtime/process?vv=john&all). However, the server accepts the call if you specify an empty value for these parameters. For example http://localhost:9080/business-central/rest/query/runtime/process?vv=john&all=.

21.1.5.2.1. Range and Regular Expression Parameters

There are two ways to define a value of a query parameter: using ranges or a simple regular expression.

21.1.5.2.2. Range Query Parameters

To define the start of a range, add _min to the parameter’s name. To define the end of a range, add _max to the parameter’s name. Range ends are inclusive.

Defining only one end of the range results in querying on an open ended range.

Example 21.18. Range Parameters

processId=org.example.process&taskId_min=50&taskId_max=53

This task query returns a result that contains only the information about tasks associated with the org.example.process process definition and the tasks that have an ID between 50 and 53, inclusive.

The following tak query differs:

processId=org.example.process&taskId_min=52

This task query returns a result that contains only the information about tasks associated with the org.example.process process definition and the tasks that have an ID larger than or equal to 52.

21.1.5.2.3. Regular Expression Query Parameters

To use regular expressions in a query parameter, add _re to the parameter’s name. The regular expression language contains two special characters:

  • * means 0 or more characters
  • . means 1 character

The slash character (\) is not interpreted.

Example 21.19. Regular Expression Parameters

processId_re=org.example.*&processVersion=2.0

This process instance query returns a result that fulfills the following:

  • Contains only the information about process instances associated with a process definition whose name matches the regular expression org.example.*. This includes:

    • org.example.process
    • org.example.process.definition.example.long.name
    • orgXexampleX
  • Contains only the information about process instances that have process version 2.0.

21.1.5.3. List of Query Parameters

Query parameters that can be defined in ranges have an X in the MIN/MAX column. Query parameters that use regular expressions have an X in the Regex column. The last column describes whether a query parameter can be used in task queries, process instance queries, or both.

processinstanceid

The process instance ID.

Short FormRegexMIN/MAXTask, Process

piid

 

X

T, P

processid

The process definition ID.

Short FormRegexMIN/MAXTask, Process

pid

X

 

T, P

deploymentid

The deployment ID.

Short FormRegexMIN/MAXTask, Process

did

X

 

T, P

taskid

The task ID.

Short FormRegexMIN/MAXTask, Process

tid

 

X

T

initiator

The task initiator or creator.

Short FormRegexMIN/MAXTask, Process

init

X

 

T

potentialowner

The task potential owner.

Short FormRegexMIN/MAXTask, Process

po

X

 

T

taskowner

The task owner.

Short FormRegexMIN/MAXTask, Process

to

X

 

T

businessadmin

The task business administrator.

Short FormRegexMIN/MAXTask, Process

ba

X

 

T

taskstatus

The task status.

Short FormRegexMIN/MAXTask, Process

tst

  

T

processinstancestatus

The process instance status.

Short FormRegexMIN/MAXTask, Process

pist

  

T, P

processversion

The process version.

Short FormRegexMIN/MAXTask, Process

pv

X

 

T, P

startdate

The process instance start date.1

Short FormRegexMIN/MAXTask, Process

stdt

 

X

T, P

enddate

The process instance end date.1

Short FormRegexMIN/MAXTask, Process

edt

 

X

T, P

varid

The variable ID.

Short FormRegexMIN/MAXTask, Process

vid

X

 

T, P

varvalue

The variable value.

Short FormRegexMIN/MAXTask, Process

vv

X

 

T, P

var

The variable ID and value.2

Short FormRegexMIN/MAXTask, Process

var

  

T, P

varregex

The variable ID and value.3

Short FormRegexMIN/MAXTask, Process

vr

X

 

T, P

all

Retrieves all variable instance logs.4

Short FormRegexMIN/MAXTask, Process

all

  

T, P

[1] The date operations require strings with the yy-MM-dd_HH:mm:ss date format as their values. However, you can submit only a part of the date:

  • Submitting only the date (yy-MM-dd) means that a time of 00:00:00 is used (the beginning of the day).
  • Submitting only the time (HH:mm:ss) means that the current date is used.

Table 21.3. Example Date Strings

Date StringActual Meaning

15-05-29_13:40:12

May 29th, 2015, 13:40:12 (1:40:12 PM)

14-11-20

November 20th, 2014, 00:00:00

9:30:00

Today, 9:30:00 (AM)

For more information about the used format, see the Class SimpleDateFormat documentation.

[2] The var query parameter is used differently than other parameters. If you want to specify both the variable ID and the value of a variable, as opposed to just the variable ID, do so by using the var query parameter. The syntax is var_{VARIABLE_ID}={VARIABLE_VALUE}.

For example, the query parameter and parameter pair var_myVar=foo3 queries for process instances with a variable called myVar that have value foo3.

[3] The varreggex (or just vr) parameter works similarly as the var query parameter. The value part of the query parameter can be a regular expression.

[4] By default, only the information from the latest variable instance logs is retrieved. Using this parameters, you can retrieve all the variable instance logs that match the given criteria.

Table 21.4. Query Parameters Examples

ParameterShort FormExample

processinstanceid

piid

piid=23

processid

pid

processid=com.acme.example

workitemid

wid

wid_max=11

deploymentid

did

did_re=com.willy.loompa.*

taskid

tid

taskid=4

initiator

init

init_re=Davi*

stakeholder

stho

stho=theBoss&stho=theBossesAssistant

potentialowner

po

potentialowner=sara

taskowner

to

taskowner_re=*anderson

businessadmin

ba

ba=admin

taskstatus

tst

tst=Reserved

processinstancestatus

pist

pist=3&pist=4

processversion

pv

processVersion_re=4.2*

startdate

stdt

stdt_min=00:00:00

enddate

edt

edt_max=15-01-01

varid

vid

varid=numCars

varvalue

vv

vv=abracadabra

var

var

var_numCars=10

varregex

vr

vr_nameCar=chitty*

all

all

all

21.1.5.4. Query Output Format

The REST Query API calls return the following results:

  • JaxbQueryProcessInstanceResult for all process instance queries.
  • JaxbQueryTaskResult for all task queries.

21.1.6. Execute Operations

For remote communication, it is recommended to use the Remote Java API. See Section 21.5, “Remote Java API”.

For performing runtime operations that involves passing a custom Java object used in the process (such as starting a process instance with process variables, or completing a task with task variables), you can use the approach mentioned in Section 21.5.2.3, “Custom Model Objects and Remote API”.

If it is not possible to use the Remote Java API or if your requirement is to use the REST API directly, you may consider using the execute operations. While the REST API accepts only string or integer values as parameters, the execute operation allows you to send complex Java objects to perform Red Hat JBoss BPM Suite runtime operations.

The execute operations are created to support the Remote Java API. Use the operations only in exceptional circumstances, such as:

  • When you need to pass complex objects as parameters.
  • When it is not possible to use /runtime or /task endpoints.

Additionally, you can consider using the execute operations in cases when you are running any other client besides Java.

In the following example, a complex object org.MyPOJO is passed as a parameter to start a process:

package com.redhat.gss.jbpm;

import java.io.StringReader;
import java.io.StringWriter;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.core.MediaType;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import org.MyPOJO;
import org.apache.commons.codec.binary.Base64;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientRequestFactory;
import org.jboss.resteasy.client.ClientResponse;
import org.kie.api.command.Command;
import org.kie.remote.client.jaxb.JaxbCommandsRequest;
import org.kie.remote.client.jaxb.JaxbCommandsResponse;
import org.kie.remote.jaxb.gen.JaxbStringObjectPairArray;
import org.kie.remote.jaxb.gen.StartProcessCommand;
import org.kie.remote.jaxb.gen.util.JaxbStringObjectPair;
import org.kie.services.client.serialization.JaxbSerializationProvider;
import org.kie.services.client.serialization.jaxb.impl.JaxbCommandResponse;

public class StartProcessWithPOJO {

  /*
   * Set the parameters according your installation:
   */
  private static final String DEPLOYMENT_ID = "org.kie.example:project1:3.0";
  private static final String PROCESS_ID = "project1.proc_start";
  private static final String PROCESS_PARAM_NAME = "myPOJO";
  private static final String APP_URL = "http://localhost:8080/business-central/rest";
  private static final String USER = "jesuino";
  private static final String PASSWORD = "redhat2014!";

  public static void main(String[] args) throws Exception {
    // List of commands to be executed:
    List<Command> commands = new ArrayList<>();

    // A sample command to start a process:
    StartProcessCommand startProcessCommand = new StartProcessCommand();
    JaxbStringObjectPairArray params = new JaxbStringObjectPairArray();
    params.getItems().add(new JaxbStringObjectPair(PROCESS_PARAM_NAME, new MyPOJO("My POJO TESTING")));
    startProcessCommand.setProcessId(PROCESS_ID);
    startProcessCommand.setParameter(params);
    commands.add(startProcessCommand);
    List<JaxbCommandResponse<?>> response = executeCommand(DEPLOYMENT_ID, commands);
    System.out.printf("Command %s executed.\n", response.toString());
    System.out.println("commands1" + commands);
  }

  private static List<JaxbCommandResponse<?>> executeCommand(String deploymentId, List<Command> commands) throws Exception {

    URL address = new URL(APP_URL + "/execute");
    ClientRequest request = createRequest(address);

    request.header(JaxbSerializationProvider.EXECUTE_DEPLOYMENT_ID_HEADER, DEPLOYMENT_ID);
    JaxbCommandsRequest commandMessage = new JaxbCommandsRequest();
    commandMessage.setCommands(commands);
    commandMessage.setDeploymentId(DEPLOYMENT_ID);
    String body = convertJaxbObjectToString(commandMessage);
    request.body(MediaType.APPLICATION_XML, body);
    ClientResponse<String> responseObj = request.post(String.class);
    String strResponse = responseObj.getEntity();
    System.out.println("RESPONSE FROM THE SERVER: \n" + strResponse);
    JaxbCommandsResponse cmdsResp = convertStringToJaxbObject(strResponse);

    return cmdsResp.getResponses();
  }

  private static ClientRequest createRequest(URL address) {
    return new ClientRequestFactory()
      .createRequest(address.toExternalForm())
      .header("Authorization", getAuthHeader());
  }

  private static String getAuthHeader() {
    String auth = USER + ":" + PASSWORD;
    byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(Charset.forName("US-ASCII")));

    return "Basic " + new String(encodedAuth);
  }

  private static String convertJaxbObjectToString(Object object) throws JAXBException {
    // Add your classes here.

    Class<?>[] classesToBeBound = { JaxbCommandsRequest.class, MyPOJO.class };
    Marshaller marshaller = JAXBContext
      .newInstance(classesToBeBound)
      .createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    StringWriter stringWriter = new StringWriter();
    marshaller.marshal(object, stringWriter);
    String output = stringWriter.toString();
    System.out.println("REQUEST CONTENT: \n" + output);

    return output;
  }

  private static JaxbCommandsResponse convertStringToJaxbObject(String str)
    throws JAXBException {
      Unmarshaller unmarshaller = JAXBContext
        .newInstance(JaxbCommandsResponse.class)
        .createUnmarshaller();

      return (JaxbCommandsResponse) unmarshaller.unmarshal(new StringReader(str));
    }
}

In this example, the org.kie.remote.jaxb.gen package classes are used for the client, which are in the org.kie.remote:kie-remote-client artifact. The deployment ID is set using a new HTTP header Kie-Deployment-Id that is also available as the JaxbSerializationProvider.EXECUTE_DEPLOYMENT_ID_HEADER Java constant.

The /execute call takes the JaxbCommandsRequest object as its parameter. The JaxbCommandsRequest object contains a list of org.kie.api.command.Command objects. The commands are stored in the JaxbCommandsRequest object, which are converted to a string representation and sent to the execute REST call. The JaxbCommandsRequest parameters are deploymentId and a Command object.

When you send a command to the /execute endpoint, a Java code is used to convert the Command object to String in an XML format. Once you generate the XML, you can use any Java or non-Java client to send it to the REST endpoint exposed by Business Central.

Note that the org.MyPOJO class must be the same in your client code as well as on the server side. To achieve this, share it through a Maven dependency: create the org.MyPOJO class using the Data Modeler in Business Central and in your REST client, add the dependency of the project which includes the org.MyPOJO class. An example of the pom.xml file with the dependency of the project created in Business Central that contains the org.MyPOJO class and other required dependencies follows.

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.redhat.gss.jbpm</groupId>
  <artifactId>bpms-start-process</artifactId>
  <version>1.0</version>
  <name>Start process using execute</name>
  <properties>
    1
    <version.org.jboss.bom.eap>6.4.7.GA</version.org.jboss.bom.eap>
    2
    <version.org.jboss.bom.brms>6.4.0.GA-redhat-2</version.org.jboss.bom.brms>
    <maven.compiler.target>1.7</maven.compiler.target>
    <maven.compiler.source>1.7</maven.compiler.source>
  </properties>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.jboss.bom.brms</groupId>
        <artifactId>jboss-brms-bpmsuite-platform-bom</artifactId>
        <type>pom</type>
        <version>${version.org.jboss.bom.brms}</version>
        <scope>import</scope>
      </dependency>
      <dependency>
        <groupId>org.jboss.bom.eap</groupId>
        <artifactId>jboss-javaee-6.0-with-tools</artifactId>
        <version>${version.org.jboss.bom.eap}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <dependency>
        <groupId>org.jboss.bom.brms</groupId>
        <artifactId>jboss-javaee-6.0-with-brms-bpmsuite</artifactId>
        <version>${version.org.jboss.bom.brms}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.kie.remote</groupId>
      <artifactId>kie-remote-client</artifactId>
    </dependency>
    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-core</artifactId>
    </dependency>
    <dependency>
      <groupId>org.jboss.resteasy</groupId>
      <artifactId>resteasy-jaxrs</artifactId>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
    </dependency>
    <dependency>
      <groupId>commons-codec</groupId>
      <artifactId>commons-codec</artifactId>
    </dependency>
    <!-- A Business Central project dependency which contains the POJO. -->
    <dependency>
      <artifactId>remote-process-start-with-bean</artifactId>
      <groupId>com.redhat.gss</groupId>
      <version>1.0</version>
    </dependency>
  </dependencies>
</project>
1
See the supported Red Hat JBoss EAP version in the Supported Platforms chapter of the Red Hat JBoss BPM Suite Installation Guide.
2
See the current version in the Supported Component Versions chapter of the Red Hat JBoss BPM Suite Installation Guide.

In the example, com.redhat.gss:remote-process-start-with-bean:1.0 is the kJAR created by Business Central. The kJAR includes the org.MyPOJO class. By sharing the dependency, you ensure that your org.MyPOJO class on the server matches with the one on the client.

Another way to achieve this is to create a data model using Red Hat JBoss Developer Studio, export the JAR file, and add it as a dependency of both the Business Central kJAR and your REST client.

21.1.6.1. Execute Operation Commands

In this section, a list of commands accepted by the execute REST endpoint is provided.

See the constructor and set methods on the actual command classes for more information about which parameters the commands accept.

The following commands are used for interacting with the process engine:

  • AbortWorkItemCommand
  • CompleteWorkItemCommand
  • GetWorkItemCommand
  • AbortProcessInstanceCommand
  • GetProcessIdsCommand
  • GetProcessInstanceByCorrelationKeyCommand
  • GetProcessInstanceCommand
  • GetProcessInstancesCommand
  • SetProcessInstanceVariablesCommand
  • SignalEventCommand
  • StartCorrelatedProcessCommand
  • StartProcessCommand
  • GetVariableCommand
  • GetFactCountCommand
  • GetGlobalCommand
  • GetIdCommand
  • FireAllRulesCommand

The following commands are used for interacting with a Task service:

  • ActivateTaskCommand
  • AddTaskCommand
  • CancelDeadlineCommand
  • ClaimNextAvailableTaskCommand
  • ClaimTaskCommand
  • CompleteTaskCommand
  • CompositeCommand
  • DelegateTaskCommand
  • ExecuteTaskRulesCommand
  • ExitTaskCommand
  • FailTaskCommand
  • ForwardTaskCommand
  • GetAttachmentCommand
  • GetContentCommand
  • GetTaskAssignedAsBusinessAdminCommand
  • GetTaskAssignedAsPotentialOwnerCommand
  • GetTaskByWorkItemIdCommand
  • GetTaskCommand
  • GetTasksByProcessInstanceIdCommand
  • GetTasksByStatusByProcessInstanceIdCommand
  • GetTasksOwnedCommand
  • NominateTaskCommand
  • ProcessSubTaskCommand
  • ReleaseTaskCommand
  • ResumeTaskCommand
  • SkipTaskCommand
  • StartTaskCommand
  • StopTaskCommand
  • SuspendTaskCommand

The following commands are used for managing and retrieving historical (audit log) information:

  • ClearHistoryLogsCommand
  • FindActiveProcessInstancesCommand
  • FindNodeInstancesCommand
  • FindProcessInstanceCommand
  • FindProcessInstancesCommand
  • FindSubProcessInstancesCommand
  • FindSubProcessInstancesCommand
  • FindVariableInstancesByNameCommand
  • FindVariableInstancesCommand
Simple Call Example

An example of /rest/execute operation for:

  • processID: evaluation
  • deploymentID: org.jbpm:Evaluation:1.0

Parameters to start the process are employee and reason.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<command-request>
  <deployment-id>org.jbpm:Evaluation:1.0</deployment-id>
  <ver>6.2.0.1</ver>
  <user>krisv</user>
  <start-process processId="evaluation">
    <parameter>
      <item key="reason">
        <value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Yearly performance evaluation</value>
      </item>
      <item key="employee">
        <value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">krisv</value>
      </item>
    </parameter>
  </start-process>
</command-request>

Include the following HTTP headers in your request:

  • The Content-Type header: application/xml.
  • The Authorization header with basic authentication information, as specificed by RFC2616.

An example response:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <command-response>
    <deployment-id>org.jbpm:Evaluation:1.0</deployment-id>
    <ver>6.2.0.1</ver>
    <process-instance index="0">
    <process-id>evaluation</process-id>
    <id>15</id>
    <state>1</state>
    <parentProcessInstanceId>0</parentProcessInstanceId>
    <command-name>StartProcessCommand</command-name>
  </process-instance>
</command-response>
Custom Data Type Call Example

The execute operations support sending user-defined class instances as parameters in the command, which requires JAXB for serialization and deserialization. To be able to deserialize the custom class on the server side, include the Kie-Deployment-Id header.

The following request starts a process which contains a custom TestObject class as a parameter:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<command-request>
  <deployment-id>demo:testproject:1.0</deployment-id>
  <ver>6.2.0.1</ver>
  <user>krisv</user>
  <start-process processId="testproject.testprocess">
    <parameter>
      <item key="testobject">
        <value xsi:type="testObject" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
          <field1>1</field1>
          <field2>2</field2>
        </value>
      </item>
    </parameter>
  </start-process>
</command-request>

Include the following HTTP headers in your request:

  • The Content-Type header: application/xml.
  • The Authorization header with basic authentication information, as specificed by RFC2616.
  • The Kie-Deployment-Id header with deploymentID that contains a definition of the custom class.

21.1.7. REST API Summary

The URL templates in the table below are relative to the following URL:

http://SERVER:PORT/business-central/rest

Table 21.5. Knowledge Store REST Operations

URL TemplateHTTP MethodDescription

/jobs/JOB_ID

GET

Returns a job status.

/jobs/JOB_ID

DELETE

Removes a job.

/organizationalunits

GET

Returns a list of organizational units.

/organizationalunits/ORGANIZATIONAL_UNIT_NAME

GET

Returns a single organizational unit.

/organizationalunits

POST

Creates an organizational unit.

/organizationalunits/ORGANIZATIONAL_UNIT_NAME

POST

Updates an organizational unit.

/organizationalunits/ORGANIZATIONAL_UNIT_NAME

DELETE

Removes an organizational unit.

/organizationalunits/ORGANIZATIONAL_UNIT_NAME/repositories/REPOSITORY_NAME

POST

Adds a repository to an organizational unit.

/organizationalunits/ORGANIZATIONAL_UNIT_NAME/repositories/REPOSITORY_NAME

DELETE

Removes a repository from an organizational unit.

/repositories

GET

Returns a list of repositories.

/repositories/REPOSITORY_NAME

GET

Returns a single repository.

/repositories

POST

Creates or clones a repository.

/repositories/REPOSITORY_NAME

DELETE

Removes a repository.

/repositories/REPOSITORY_NAME/projects

GET

Returns a list of projects in a repository.

/repositories/REPOSITORY_NAME/projects

POST

Creates a project in a repository.

/repositories/REPOSITORY_NAME/projects/PROJECT_NAME

DELETE

Removes a project in a repository.

/repositories/REPOSITORY_NAME/projects/PROJECT_NAME/maven/compile

POST

Compiles a project.

/repositories/REPOSITORY_NAME/projects/PROJECT_NAME/maven/test

POST

Tests a project.

/repositories/REPOSITORY_NAME/projects/PROJECT_NAME/maven/install

POST

Installs a project.

/repositories/REPOSITORY_NAME/projects/PROJECT_NAME/maven/deploy

POST

Deploys a project.

Table 21.6. Deployment REST Operations

URL TemplateHTTP MethodDescription

/deployment

GET

Returns a list of (deployed) deployments.

/deployment/DEPLOYMENT_ID

GET

Returns a status and information about a deployment.

/deployment/DEPLOYMENT_ID/deploy

POST

Submits a request to deploy a deployment.

/deployment/DEPLOYMENT_ID/undeploy

POST

Submits a request to undeploy a deployment.

/deployment/DEPLOYMENT_ID/deactivate

POST

Deactivates a deployment.

/deployment/DEPLOYMENT_ID/activate

POST

Activates a deployment.

Table 21.7. Process Image REST Operations

URL TemplateHTTP MethodDescription

/runtime/DEPLOYMENT_ID/process/PROCESS_ID/image

GET

Returns an SVG image with a process definition diagram.

/runtime/DEPLOYMENT_ID/process/PROCESS_ID/image/PROCESS_INSTANCE_ID

GET

Returns an SVG image with a process instance diagram.

Table 21.8. Runtime REST Operations

URL TemplateHTTP MethodDescription

/runtime/DEPLOYMENT_ID/process/PROCESS_ID/start

POST

Starts a new process instance. Accepts query map parameters.

/runtime/DEPLOYMENT_ID/process/PROCESS_ID/startform

GET

Returns a URL where the process form can be found.

/runtime/DEPLOYMENT_ID/process/instance/PROCESS_INSTANCE_ID

GET

Returns process instance details.

/runtime/DEPLOYMENT_ID/process/instance/PROCESS_INSTANCE_ID/abort

POST

Aborts a process instance.

/runtime/DEPLOYMENT_ID/process/instance/PROCESS_INSTANCE_ID/signal

POST

Sends a signal event to a process instance. Accepts query map parameters.

/runtime/DEPLOYMENT_ID/process/instance/PROCESS_INSTANCE_ID/variable/VARIABLE_ID

GET

Returns a variable from a process instance.

/runtime/DEPLOYMENT_ID/signal/SIGNAL_CODE

POST

Sends a signal event to a deployment unit.

/runtime/DEPLOYMENT_ID/withvars/process/PROCESS_ID/start

POST

Starts a new process instance and return a process instance details with its variables.

Note that even if a passed variable is not defined in the underlying process definition, it is created and initialized with the passed value.

/runtime/DEPLOYMENT_ID/withvars/process/instance/PROCESS_INSTANCE_ID

GET

Returns process instance details with its variables.

/runtime/DEPLOYMENT_ID/withvars/process/instance/PROCESS_INSTANCE_ID/signal

POST

Sends a signal event to a process instance. Accepts query map parameters.

The following query parameters are accepted:

  • The signal parameter specifies the name of the signal to be sent.
  • The event parameter specifies the (optional) value of the signal to be sent.

/runtime/DEPLOYMENT_ID/workitem/WORK_ITEM_ID/complete

POST

Completes a work item. Accepts query map parameters.

/runtime/DEPLOYMENT_ID/workitem/WORK_ITEM_ID/abort

POST

Aborts a work item.

Table 21.9. Task REST Operations

URL TemplateHTTP MethodDescription

/task/query

GET

Returns a TaskSummary list.

/task/content/CONTENT_ID

GET

Returns a content of a task.

/task/TASK_ID/content

GET

Returns a content of a task.

/task/TASK_ID

GET

Returns a task.

/task/TASK_ID/activate

POST

Activates a task.

/task/TASK_ID/claim

POST

Claims a task.

/task/TASK_ID/claimnextavailable

POST

Claim the next available task.

/task/TASK_ID/complete

POST

Complete a task. Accepts query map parameters.

/task/TASK_ID/delegate

POST

Delegates a task.

/task/TASK_ID/exit

POST

Exits a task.

/task/TASK_ID/fail

POST

Fails a task.

/task/TASK_ID/forward

POST

Forwards a task.

/task/TASK_ID/nominate

POST

Nominates a task.

/task/TASK_ID/release

POST

Releases a task.

/task/TASK_ID/resume

POST

Resumes a task after suspending.

/task/TASK_ID/skip

POST

Skips a task.

/task/TASK_ID/start

POST

Starts a task.

/task/TASK_ID/stop

POST

Stops a task.

/task/TASK_ID/suspend

POST

Suspends a task.

/task/TASK_ID/showTaskForm

GET

Generates a URL to show a task form on a remote application as a JaxbTaskFormResponse instance.

Table 21.10. History REST Operations

URL TemplateHTTP MethodDescription

/history/instances

GET

Returns a list of all process instance history records.

/history/instance/PROCESS_INSTANCE_ID

GET

Returns a list of process instance history records for a process instance.

/history/instance/PROCESS_INSTANCE_ID/child

GET

Returns a list of process instance history records for subprocesses of a process instance.

/history/instance/PROCESS_INSTANCE_ID/node

GET

Returns a list of node history records for a process instance.

/history/instance/PROCESS_INSTANCE_ID/node/NODE_ID

GET

Returns a list of node history records for a node in a process instance.

/history/instance/PROCESS_INSTANCE_ID/variable

GET

Returns a list of variable history records for a process instance.

/history/instance/PROCESS_INSTANCE_ID/variable/VARIABLE_ID

GET

Returns a list of variable history records for a variable in a process instance.

/history/process/PROCESS_DEFINITION_ID

GET

Returns a list of process instance history records for process instances using the given process definition.

/history/variable/VARIABLE_ID

GET

Returns a list of variable history records for a variable.

/history/variable/VARIABLE_ID/instances

GET

Returns a list of process instance history records for process instances that contain a variable with the given variable ID.

/history/variable/VARIABLE_ID/value/VALUE

GET

Returns a list of variable history records for variable(s) with the given variable ID and the given value.

/history/variable/VARIABLE_ID/value/VALUE/instances

GET

Returns a list of process instance history records for process instances with the specified variable that contains the specified variable value.

/history/clear/

POST

Removes all process, node, and history records.

Table 21.11. Query REST Operations

URL TemplateHTTP MethodDescription

/query/runtime/process

GET

Query for process instances and process variables. Returns a JaxbQueryProcessInstanceResult object.

/query/runtime/task

GET

Query for task summaries and process variables. Returns a JaxbQueryTaskResult object.

/query/task

GET

Query for tasks. Returns a JaxbTaskSummaryListResponse object.

Supported query parameters are workItemId, taskId, businessAdministrator, potentialOwner, status, taskOwner, processInstanceId, language, and union.

Note

None of these REST endpoints has an equivalent Java client. Return values are examples of classes that can be used when you retrieve responses of calls made from your Java application. Each response is either in an XML or JSON format.

21.1.8. Control of REST API

You can use the following roles:

Table 21.12. Available Roles, Their Type and Scope of Access

NameTypeScope of access

rest-all

GET, POST, DELETE

All direct REST calls, excluding a remote client.

rest-project

GET, POST, DELETE

Knowledge store REST calls.

rest-deployment

GET, POST

Deployment unit REST calls.

rest-process

GET, POST

Runtime and history REST calls.

rest-process-read-only

GET

Runtime and history REST calls.

rest-task

GET, POST

Task REST calls.

rest-task-read-only

GET

Task REST calls.

rest-query

GET

REST query API calls.

rest-client

POST

Remote client calls.

21.2. JMS

The Java Message Service (JMS) is an API that allows Java Enterprise components to communicate with each other asynchronously and reliably.

Operations on the runtime engine and tasks can be done through the JMS API exposed by Business Central. However, it is not possible to manage deployments or the knowledge base using this JMS API.

Unlike the REST API, it is possible to send a batch of commands to the JMS API that will all be processed in one request after which the responses to the commands will be collected and returned in one response message.

Note

It is not recommended to use JMS directly. Use the Remote Java API when you want to communicate with Business Central. The better way is to use the Intelligent Process Server Java Client API. See Chapter 19, Intelligent Process Server Java Client API Overview.

21.2.1. JMS Queue Setup

When you deploy Business Central on the Java EE application server, it automatically creates the following JMS queues:

  • KIE.SESSION
  • KIE.TASK
  • KIE.RESPONSE
  • KIE.AUDIT
  • KIE.EXECUTOR
  • KIE.SIGNAL

The KIE.SESSION and KIE.TASK queues are used to send request messages to the JMS API. Command response messages will be then placed on the KIE.RESPONSE queues. Command request messages that involve starting and managing business processes should be sent to the KIE.SESSION queue and command request messages that involve managing human tasks should be sent to the KIE.TASK queue.

Although there are two different input queues, KIE.SESSION and KIE.TASK, it is to provide multiple input queues to optimize processing: command request messages will be processed in the same manner regardless of which queue they are sent to. However, in some cases, users may send more requests involving human tasks than requests involving business processes, but then not want the processing of business process-related request messages to be delayed by the human task messages. By sending the appropriate command request messages to the appropriate queues, this problem can be avoided.

The term command request message used above refers to a JMS byte message that contains a serialized JaxbCommandsRequest object. At the moment, only XML serialization is supported as opposed to, for example, JSON or protobuf.

JMS queue KIE.EXECUTOR is used in the Job Executor component to speed up processing of asynchronous tasks and defined jobs. See Section 11.12.3, “Job Executor for Asynchronous Execution” for more information about Job Executor. Note that the executor can work without JMS. You can disable JMS, for example, when you deploy Red Hat JBoss BPM Suite on container without full JMS support out of the box, such as Tomcat. To disable JMS, set the following property: org.kie.executor.jms=false.

21.2.2. Example JMS Usage

The following example shows the usage of the JMS API. The numbers (callouts) in the example refer to notes below that explain particular parts of the example. It is provided for the advanced users that do not wish to use the Red Hat JBoss BPM Suite Remote Java API which otherwise incorporates the logic shown below.

// Usual Java imports skipped.

import org.drools.core.command.runtime.process.StartProcessCommand;
import org.jbpm.services.task.commands.GetTaskAssignedAsPotentialOwnerCommand;
import org.kie.api.command.Command;
import org.kie.api.runtime.process.ProcessInstance;
import org.kie.api.task.model.TaskSummary;
// 1
import org.kie.services.client.api.command.exception.RemoteCommunicationException;
import org.kie.services.client.serialization.JaxbSerializationProvider;
import org.kie.services.client.serialization.SerializationConstants;
import org.kie.services.client.serialization.SerializationException;
import org.kie.services.client.serialization.jaxb.impl.JaxbCommandResponse;
import org.kie.services.client.serialization.jaxb.impl.JaxbCommandsRequest;
import org.kie.services.client.serialization.jaxb.impl.JaxbCommandsResponse;
import org.kie.services.client.serialization.jaxb.rest.JaxbExceptionResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DocumentationJmsExamples {

  protected static final Logger logger = LoggerFactory.getLogger(DocumentationJmsExamples.class);

  public void sendAndReceiveJmsMessage() {

    String USER = "charlie";
    String PASSWORD = "ch0c0licious";

    String DEPLOYMENT_ID = "test-project";
    String PROCESS_ID_1 = "oompa-processing";
    URL serverUrl;
    try {
      serverUrl = new URL("http://localhost:8080/business-central/");
    } catch (MalformedURLException murle) {
      logger.error("Malformed URL for the server instance!", murle);
      return;
    }

    // Create JaxbCommandsRequest instance and add commands:
    Command<?> cmd = new StartProcessCommand(PROCESS_ID_1);
    int oompaProcessingResultIndex = 0;
    // 5
    JaxbCommandsRequest req = new JaxbCommandsRequest(DEPLOYMENT_ID, cmd);
    // 2
    req.getCommands().add(new GetTaskAssignedAsPotentialOwnerCommand(USER, "en-UK"));
    int loompaMonitoringResultIndex = 1;
    // 5
    // Get JNDI context from server:
    InitialContext context = getRemoteJbossInitialContext(serverUrl, USER, PASSWORD);

    // Create JMS connection:
    ConnectionFactory connectionFactory;
    try {
      connectionFactory = (ConnectionFactory) context.lookup("jms/RemoteConnectionFactory");
    } catch (NamingException ne) {
      throw new RuntimeException("Unable to lookup JMS connection factory.", ne);
    }

    // Set up queues:
    Queue sendQueue, responseQueue;
    try {
      sendQueue = (Queue) context.lookup("jms/queue/KIE.SESSION");
      responseQueue = (Queue) context.lookup("jms/queue/KIE.RESPONSE");
    } catch (NamingException ne) {
      throw new RuntimeException("Unable to lookup send or response queue", ne);
    }

    // Send command request:
    Long processInstanceId = null; // needed if you are doing an operation on a PER_PROCESS_INSTANCE deployment
    String humanTaskUser = USER;
    JaxbCommandsResponse cmdResponse = sendJmsCommands(DEPLOYMENT_ID, processInstanceId, humanTaskUser, req, connectionFactory, sendQueue, responseQueue, USER, PASSWORD, 5);

    // Retrieve results:
    ProcessInstance oompaProcInst = null;
    List<TaskSummary> charliesTasks = null;

    // 6

    for (JaxbCommandResponse<?> response : cmdResponse.getResponses()) {
      if (response instanceof JaxbExceptionResponse) {
        // Something went wrong on the server side:
        JaxbExceptionResponse exceptionResponse = (JaxbExceptionResponse) response;
        throw new RuntimeException(exceptionResponse.getMessage());
      }

      // 5

      if (response.getIndex() == oompaProcessingResultIndex) {
        oompaProcInst = (ProcessInstance) response.getResult();
      // 6
      } else if (response.getIndex() == loompaMonitoringResultIndex) {
    	// 5
        charliesTasks = (List<TaskSummary>) response.getResult();
      // 6
      }
    }
  }

  private JaxbCommandsResponse sendJmsCommands(String deploymentId, Long processInstanceId, String user, JaxbCommandsRequest req, ConnectionFactory factory, Queue sendQueue, Queue responseQueue, String jmsUser, String jmsPassword, int timeout) {

    req.setProcessInstanceId(processInstanceId);
    req.setUser(user);

    Connection connection = null;
    Session session = null;
    String corrId = UUID.randomUUID().toString();
    String selector = "JMSCorrelationID = '" + corrId + "'";
    JaxbCommandsResponse cmdResponses = null;
    try {
      // Setup:
      MessageProducer producer;
      MessageConsumer consumer;
      try {
        if (jmsPassword != null) {
          connection = factory.createConnection(jmsUser, jmsPassword);
        } else {
          connection = factory.createConnection();
        }

        session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
        producer = session.createProducer(sendQueue);
        consumer = session.createConsumer(responseQueue, selector);

        connection.start();
      } catch (JMSException jmse) {
        throw new RemoteCommunicationException("Unable to setup a JMS connection.", jmse);
      }
      // 7

      JaxbSerializationProvider serializationProvider = new JaxbSerializationProvider();
      // If necessary, add user-created classes here:
      // xmlSerializer.addJaxbClasses(MyType.class, AnotherJaxbAnnotatedType.class);

      // Create msg:
      BytesMessage msg;
      try {
        msg = session.createBytesMessage();
        // 3
        // Set properties:
        msg.setJMSCorrelationID(corrId);
        // 3
        msg.setIntProperty(SerializationConstants.SERIALIZATION_TYPE_PROPERTY_NAME, JaxbSerializationProvider.JMS_SERIALIZATION_TYPE);

        // 3

        Collection<Class<?>> extraJaxbClasses = serializationProvider.getExtraJaxbClasses();
        if (!extraJaxbClasses.isEmpty()) {
          String extraJaxbClassesPropertyValue = JaxbSerializationProvider.classSetToCommaSeperatedString(extraJaxbClasses);
          msg.setStringProperty(SerializationConstants.EXTRA_JAXB_CLASSES_PROPERTY_NAME, extraJaxbClassesPropertyValue);
          msg.setStringProperty(SerializationConstants.DEPLOYMENT_ID_PROPERTY_NAME, deploymentId);
        }

        // Serialize request:
        String xmlStr = serializationProvider.serialize(req);
        msg.writeUTF(xmlStr);

      // 3

      } catch (JMSException jmse) {
        throw new RemoteCommunicationException("Unable to create and fill a JMS message.", jmse);
      } catch (SerializationException se) {
        throw new RemoteCommunicationException("Unable to deserialze JMS message.", se.getCause());
      }

      // Send:
      try {
        producer.send(msg);
      } catch (JMSException jmse) {
        throw new RemoteCommunicationException("Unable to send a JMS message.", jmse);
      }

      // Receive:
      Message response;

      // 4

      try {
        response = consumer.receive(timeout);
      } catch (JMSException jmse) {
        throw new RemoteCommunicationException("Unable to receive or retrieve the JMS response.", jmse);
      }

      if (response == null) {
        logger.warn("Response is empty, leaving");
        return null;
      }
      // Extract response:
      assert response != null : "Response is empty.";
      try {
        String xmlStr = ((BytesMessage) response).readUTF();
        cmdResponses = (JaxbCommandsResponse) serializationProvider.deserialize(xmlStr);
      } catch (JMSException jmse) {
        throw new RemoteCommunicationException("Unable to extract "
          + JaxbCommandsResponse.class.getSimpleName()
          + " instance from JMS response.", jmse);
      } catch (SerializationException se) {
        throw new RemoteCommunicationException("Unable to extract "
          + JaxbCommandsResponse.class.getSimpleName()
          + " instance from JMS response.", se.getCause());
      }
      assert cmdResponses != null : "Jaxb Cmd Response was null!";
    } finally {
      if (connection != null) {
        try {
          connection.close();
          session.close();
        } catch (JMSException jmse) {
          logger.warn("Unable to close connection or session!", jmse);
        }
      }
    }
    return cmdResponses;
  }

  private InitialContext getRemoteJbossInitialContext(URL url, String user, String password) {

    Properties initialProps = new Properties();
    initialProps.setProperty(InitialContext.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
    String jbossServerHostName = url.getHost();
    initialProps.setProperty(InitialContext.PROVIDER_URL, "remote://"+ jbossServerHostName + ":4447");
    initialProps.setProperty(InitialContext.SECURITY_PRINCIPAL, user);
    initialProps.setProperty(InitialContext.SECURITY_CREDENTIALS, password);

    for (Object keyObj : initialProps.keySet()) {
      String key = (String) keyObj;
      System.setProperty(key, (String) initialProps.get(key));
    }
    try {
      return new InitialContext(initialProps);
    } catch (NamingException e) {
      throw new RemoteCommunicationException("Unable to create " + InitialContext.class.getSimpleName(), e);
    }
  }
}
  1. These classes can all be found in the kie-services-client and the kie-services-jaxb JARs.
  2. The JaxbCommandsRequest instance is the "holder" object in which you can place all of the commands you want to execute in a particular request. By using the JaxbCommandsRequest.getCommands() method, you can retrieve the list of commands to add more commands to the request.

    A deployment ID is required for command request messages that deal with business processes. Command request messages that only contain human task-related commands do not require a deployment ID.

  3. Note that the JMS message sent to the remote JMS API must be constructed as follows:

    • It must be a JMS byte message.
    • It must have a filled JMS Correlation ID property.
    • It must have an int property called serialization set to an acceptable value: only 0 at the moment.
    • It must contain a serialized instance of a JaxbCommandsRequest, added to the message as a UTF string.
  4. The same serialization mechanism used to serialize the request message will be used to serialize the response message.
  5. To match the response, use the index field of the returned JaxbCommandResponse instances. This index field will match the index of the initial command. Because not all commands will return a result, it is possible to send three commands with a command request message, and then receive a command response message that only includes one JaxbCommandResponse message with an index value 1. This value then identifies it as the response to the second command.
  6. Since many of the results returned by various commands are not serializable, the JMS API of Business Central converts these results into JAXB equivalents, all of which implement the JaxbCommandResponse interface. The JaxbCommandResponse.getResult() method then returns the JAXB equivalent to the actual result, which will conform to the interface of the result.

    For example, in the code above, the StartProcessCommand returns ProcessInstance. To return this object to the requester, the ProcessInstance is converted to JaxbProcessInstanceResponse and then added as JaxbCommandResponse to the command response message. The same applies to List<TaskSummary> that is returned by GetTaskAssignedAsPotentialOwnerCommand.

    However, not all methods that can be called on ProcessInstance can be called on the JaxbProcessInstanceResponse because JaxbProcessInstanceResponse is simply a representation of a ProcessInstance object. This applies to various other command response as well. In particular, methods which require an active (backing) KieSession, such as ProcessInstance.getProcess() or ProcessInstance.signalEvent(String type, Object event), will throw UnsupportedOperationException.

  7. By default, a session is created in kieServerMDB with the acknowledge mode set to Session.AUTO_ACKNOWLEDGE and the transacted value set to false, resulting in the following response as shown in the example:

    session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);

    If a generic resource adapter is used with JMS, this session setting can generate a null pointer error. You can either temporarily work around this issue or resolve it going forward:

    • To work around this issue when a generic resource adapter is used, set the transacted value to true and set the session type to SESSION_TRANSACTED:

      session = connection.createSession(true, Session.SESSION_TRANSACTED);
    • To resolve this issue when a generic resource adapter is used, add the following under <system properties> in the standalone.xml file of Red Hat JBoss EAP:

      org.kie.server.jms.session.tx=true  // If not set, defaults to `false`.
      org.kie.server.jms.session.ack=$INTEGER  // Integer value matching one of the javax.jms.Session constants that represent `ack` mode.

21.3. SOAP API

Simple Object Access Protocol (SOAP) is a type of distribution architecture used for exchanging information. SOAP requires a minimal amount of overhead on the system and is used as a protocol for communication, while it is versatile enough to allow the use of different transport protocols.

Like REST, SOAP allows client-server communication. Clients can initiate requests to servers using URLs with parameters. The servers then process the requests and return responses based on the particular URL.

21.3.1. CommandWebService

Business Central in Red Hat JBoss BPM Suite provides a SOAP interface in the form of CommandWebService. A Java client is provided as a generated CommandWebService class and can be used as follows.

Classes generated by the kie-remote-client module function as a client-side interface for SOAP. The CommandWebServiceClient class referenced in the test code below is generated by the Web Service Description Language (WSDL) in the kie-remote-client JAR.

import org.kie.remote.client.api.RemoteRuntimeEngineFactory;
import org.kie.remote.client.jaxb.JaxbCommandsRequest;
import org.kie.remote.client.jaxb.JaxbCommandsResponse;
import org.kie.remote.jaxb.gen.StartProcessCommand;
import org.kie.remote.services.ws.command.generated.CommandWebService;
import org.kie.services.client.serialization.jaxb.impl.JaxbCommandResponse;

public JaxbProcessInstanceResponse startProcessInstance(String user, String password, String processId, String deploymentId, String applicationUrl) throws Exception {

  CommandWebService client = RemoteRuntimeEngineFactory
    .newCommandWebServiceClientBuilder()
    .addDeploymentId(deploymentId)
    .addUserName(user)
    .addPassword(password)
    .addServerUrl(applicationUrl)
    .buildBasicAuthClient();

  // Get a response from the WebService:
  StartProcessCommand cmd = new StartProcessCommand();
  cmd.setProcessId(processId);
  JaxbCommandsRequest req = new JaxbCommandsRequest(deploymentId, cmd);
  final JaxbCommandsResponse response = client.execute(req);

  JaxbCommandResponse<?> cmdResp = response.getResponses().get(0);

  return (JaxbProcessInstanceResponse) cmdResp;
}

The SOAP interface of Business Central in Red Hat JBoss BPM Suite is currently available for Red Hat JBoss EAP, IBM WebSphere, and Oracle WebLogic servers.

21.4. EJB Interface

Starting with version 6.1, the Red Hat JBoss BPM Suite execution engine supports an EJB interface for accessing KieSession and TaskService remotely. This enables close transaction integration between the execution engine and remote customer applications.

The implementation of the EJB interface is a single framework-independent and container-agnostic API that can be used with framework-specific code. The services are exposed using the org.jbpm.services.api and org.jbpm.services.ejb packages. CDI is supported as well through the org.jbpm.services.cdi package.

The implementation does not support RuleService at the moment, however, the ProcessService class exposes an execute method that enables you to use various rule-related commands, such as InsertCommand and FireAllRulesCommand.

Deployment of EJB Client

The EJB interface is supported on Red Hat JBoss EAP only.

Download the Red Hat JBoss BPM Suite 6.4 Maven Repository ZIP file from the Red Hat Customer Portal. The EJB client is available as a JAR file jbpm-services-ejb-client-VERSION-redhat-MINOR_VERSION in the maven-repository/org/jbpm/jbpm-services-ejb-client directory of the downloaded file.

Note

The inclusion of EJB does not mean that CDI-based services are replaced. CDI and EJB can be used together, however, it is not recommended. Since EJBs are not available by default in Business Central, the kie-services package must be present on the class path. The EJB services are suitable for embedded use cases.

21.4.1. EJB Interface Artifacts

The artifacts that provide the EJB interface to the jBPM services are contained in the following packages:

  1. org.jbpm.services.ejb.api: the extension of the Services API for the needs of the EJB interface.
  2. org.jbpm.services.ejb.impl: EJB wrappers on top of the core service implementation.
  3. org.jbpm.services.ejb.client: the EJB remote client implementation. The implementation is supported on Red Hat JBoss EAP only.

The org.jbpm.services.ejb.api package mentioned above contains the following service interfaces that can be used by remote EJB clients:

  • DefinitionServiceEJBRemote: use this interface to gather information about processes (ID, name, and version), process variables (name and type), defined reusable subprocesses, domain-specific services, user tasks, and user tasks inputs and outputs.
  • DeploymentServiceEJBRemote: use this interface to initiate deployments and undeployments. Methods include deploy, undeploy, getRuntimeManager, getDeployedUnits, isDeployed, activate, deactivate, and getDeployedUnit. Calling the deploy method with an instance of DeploymentUnit deploys the unit into the runtime engine by building a RuntimeManager instance. After a successful deployment, an instance of DeployedUnit is created and cached for further usage.

    To use the methods mentioned above, the artifacts of the project must be installed in a Maven repository.

  • ProcessServiceEJBRemote: use this interface to control a lifecycle of one or more processes and work items.
  • RuntimeDataServiceEJBRemote: use this interface to retrieve data related to the runtime: process instances, process definitions, node instance information, and variable information. The interface includes several convenience methods for gathering task information based on owner, status, and time.
  • UserTaskServiceEJBRemote: use this interface to control a lifecycle of a user task. The included methods are for example activate, start, stop, and execute.
  • QueryServiceEJBRemote: provides advanced query capabilities.
  • ProcessInstanceMigrationServiceEJBRemote: provides a migration service for process instances. If a new version of a process definition is deployed and the active process instances should be migrated, use this interface to do so.
Note

Process instance migration is available only with Red Hat JBoss BPM Suite 6.4 and higher.

A synchronization service that synchronizes the information between Business Central and EJBs is available as well. The synchronization interval can be set using the org.jbpm.deploy.sync.int system property. However, note that you have to wait for the service to finish the synchronization before trying to access the updated information using REST.

Note

When you deploy the jBPM services EJB API, the executor is registered during the deployment of a kJAR. Hence the JNDI name used is only visible for the module where the EJB is deployed. If you want to use the executor service from a different module, use the org.jbpm.executor.service.ejb-jndi system property that enables you to configure the executor service JNDI name. For more information, see the List of System Properties section of the Red Hat JBoss BPM Suite Administration and Configuration Guide.

21.4.2. Generating EJB Services WAR File

Follow the procedure below to create an EJB Services WAR file using the EJB interface.

  1. Register a Human Task callback using a startup class:

    @Singleton
    @Startup
    public class StartupBean {
    
      @PostConstruct
      public void init()
      { System.setProperty("org.jbpm.ht.callback", "jaas"); }
    
    }
  2. Run the following command to generate the WAR file:

    mvn assembly:assembly
  3. Deploy the generated WAR file sample-war-ejb-app.war on the Red Hat JBoss EAP instance where Red Hat JBoss BPM Suite is running.

    Warning

    If you are deploying the EJB WAR file on the same Red Hat JBoss EAP instance, avoid using the Singleton strategy for your runtime sessions. The Singleton strategy causes both applications to load the same ksession instance from the underlying file system and causes optimistic lock exceptions.

    If you want to deploy the file on a Red Hat JBoss EAP instance separate from the one where Red Hat JBoss BPM Suite is running:

    • Configure your application or the application server to invoke a remote EJB.
    • Configure your application or the application server to propagate the security context.

    If you are using Hibernate to create a database schema for jBPM, update the persistence.xml file in Business Central. Edit the hibernate.hbm2ddl.auto property and set its value to update instead of create.

  4. To test it, create a simple web application and inject the EJB Services:

    @EJB(lookup = "ejb:/sample-war-ejb-app/ProcessServiceEJBImpl!org.jbpm.services.ejb.api.ProcessServiceEJBRemote")
    private ProcessServiceEJBRemote processService;
    
    @EJB(lookup = "ejb:/sample-war-ejb-app/UserTaskServiceEJBImpl!org.jbpm.services.ejb.api.UserTaskServiceEJBRemote")
    private UserTaskServiceEJBRemote userTaskService;
    
    @EJB(lookup = "ejb:/sample-war-ejb-app/RuntimeDataServiceEJBImpl!org.jbpm.services.ejb.api.RuntimeDataServiceEJBRemote")
    private RuntimeDataServiceEJBRemote runtimeDataService;

For more information about invoking remote EJBs, see the Invoking Session Beans chapter of the Red Hat JBoss EAP Development Guide.

21.5. Remote Java API

The Remote Java API provides KieSession, TaskService, and AuditService interfaces to the JMS and REST APIs.

The interface implementations provided by the Remote Java API incorporate the underlying logic needed to communicate with the JMS or REST APIs. In other words, these implementations allow you to interact with Business Central through the known interfaces such as the KieSession or TaskService interface, without having to deal with the underlying transport and serialization details.

The Remote Java API Provides Clients, Not Instances

While the KieSession, TaskService, and AuditService instances provided by the Remote Java API may "look" and "feel" like local instances of the same interfaces, make sure to remember that these instances are only wrappers around a REST or JMS client that interacts with a remote REST or JMS API.

This means that if a requested operation fails on the server, the Remote Java API client instance on the client side will throw RuntimeException indicating that the REST call failed. This is different from the behavior of a "real" (or local) instance of a KieSession, TaskService, and AuditService instance: the exception the local instances will throw will relate to how the operation failed. Also, while local instances require different handling, such as having to dispose of KieSession, client instances provided by the Remote Java API hold no state and thus do not require any special handling.

Lastly, operations on a Remote Java API client instance that would normally throw other exceptions, such as the TaskService.claim(taskId, userId) operation when called by a user who is not a potential owner, will now throw RuntimeException instead when the requested operation fails on the server.

Note

It is recommended to use Intelligent Process Server instead of Business Central. Intelligent Process Server provides more intuitive and easier way to use the Java Client API. See Chapter 19, Intelligent Process Server Java Client API Overview.

The very first step in interacting with the remote runtime is to create the RemoteRuntimeEngine instance. The recommended way is to use RemoteRestRuntimeEngineBuilder or RemoteJmsRuntimeEngineBuilder. There is a number of different methods for both the JMS and REST client builders that allow the configuration of parameters such as the base URL of the REST API, JMS queue location, or timeout while waiting for responses.

Procedure: Creating RemoteRuntimeEngine Instance

  1. Instantiate the RemoteRestRuntimeEngineBuilder or RemoteJmsRuntimeEngineBuilder by calling either RemoteRuntimeEngineFactory.newRestBuilder() or RemoteRuntimeEngineFactory.newJmsBuilder().
  2. Set the required parameters.
  3. Finally, call the build() method.

Detailed examples can be found in Section 21.5.2, “REST Client”, Section 21.5.2.2, “Calling Tasks Without Deployment ID”, and Section 21.5.2.3, “Custom Model Objects and Remote API”.

Once the RemoteRuntimeEngine instance has been created, there are a couple of methods that can be used to instantiate the client classes you want to use:

Remote Java API Methods

KieSession RemoteRuntimeEngine.getKieSession()
This method instantiates a new (client) KieSession instance.
TaskService RemoteRuntimeEngine.getTaskService()
This method instantiates a new (client) TaskService instance.
A`uditService RemoteRuntimeEngine.getAuditService()`
This method instantiates a new (client) AuditService instance.

Starting Project: Adding Dependencies

To start your own project, specify the Red Hat JBoss BPM Suite BOM in the project’s pom.xml file. Also, make sure you add the kie-remote-client dependency. See the following example:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.jboss.bom.brms</groupId>
      <artifactId>jboss-brms-bpmsuite-bom</artifactId>
      <version>6.4.2.GA-redhat-2</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

<dependencies>
  <dependency>
    <groupId>org.kie.remote</groupId>
    <artifactId>kie-remote-client</artifactId>
  </dependency>
</dependencies>

For the supported Maven BOM version, see Supported Component Versions of the Red Hat JBoss BPM Suite Installation Guide.

21.5.1. Common Configuration

The following common methods can be called on both RemoteRestRuntimeEngineBuilder and RemoteJmsRuntimeEngineBuilder when creating a new instance of RemoteRuntimeEngine:

addUrl(java.net.URL param)
URL of the deployed Business Central. For example http://localhost:8080/business-central/.
addUserName(String param)
The password to access the REST API.
addPassword(String param)
The password to access the REST API.
addDeploymentId(String param)
The name (ID) of the deployment the RuntimeEngine must interact with. This can be an empty String in case you are only interested in task operations.
addTimeout(int param)
The maximum number of seconds the engine must wait for a response from the server.
addProcessInstanceId(long param)
The method that adds the process instance ID, which may be necessary when interacting with deployments that employ the per process instance runtime strategy.
addExtraJaxbClasses(MyClass.class)
The method that adds extra classes to the class path available to the serialization mechanisms. When passing instances of user-defined classes in a Remote Java API call, it is important to have added the classes using this method first so that the class instances can be serialized correctly.
clearJaxbClasses()
If RemoteRuntimeEngineBuilder is being reused to build multiple instances of RemoteRuntimeEngineFactory, this method can be called between build() methods to reset the list of user-defined classes being used by the builder.
addCorrelationProperties(String[] params)
Adds the correlation key properties which are necessary when interacting with a correlation-key identitied KieSession.
clearCorrelationProperties()
Clears all the correlation key properties added by the addCorrelationProperties method.

21.5.2. REST Client

The RemoteRuntimeEngineFactory class is the starting point for building and configuring a new RemoteRuntimeEngine instance that can interact with the Remote API. This class creates an instance of a REST client builder using the newRestBuilder() method. This builder is then used to create a RemoteRuntimeEngine instance that acts as a client to the remote REST API.

In addition to the methods mentioned in Section 21.5.1, “Common Configuration”, the following configuration methods can be called on RemoteRestRuntimeEngineBuilder:

addUrl(java.net.URL param)
Configures a URL of the deployed Business Central. For example http://localhost:8080/business-central/.
disableTaskSecurity()

Allows an authenticated user to work on tasks on behalf of other users.

This requires the org.kie.task.insecure property to be set to true on the server side as well.

addHeader(String param1, String param2)

Adds a custom HTTP header field that will be sent with each request.

Multiple calls to this method with the same header field name will not replace existing header fields with the same header field name.

clearHeaderFields()
Clears all custom header fields for this builder.

Once you have configured all the necessary properties, call build() to get access to RemoteRuntimeEngine.

Important

If the REST API access control is turned on, which is done by default, the given user who wants to use RemoteRuntimeEngine calls has to have the rest-client and rest-all roles assigned.

The following example illustrates how the Remote Java API can be used with the REST API.

package org.kie.remote.client.documentation;

import java.net.URL;
import java.util.List;

import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.manager.RuntimeEngine;
import org.kie.api.runtime.process.ProcessInstance;
import org.kie.api.task.TaskService;
import org.kie.api.task.model.TaskSummary;
import org.kie.remote.client.api.RemoteRuntimeEngineFactory;

public class RemoteJavaApiRestClientExample {

 public void startProcessAndStartTask(URL baseUrl, String deploymentId, String user, String password) {

   // The baseUrl should contain a URL similar to
   // "http://localhost:8080/business-central/".

   // RuntimeEngine instance with the necessary information to communicate
   // with the REST services.

   // Select a user with the rest-all role.

   RuntimeEngine engine = RemoteRuntimeEngineFactory
     .newRestBuilder()
     .addDeploymentId(deploymentId)
     .addUrl(baseUrl)
     .addUserName(user)
     .addPassword(password)
     .build();

       // Create KieSession and TaskService instances and use them:
       KieSession ksession = engine.getKieSession();
       TaskService taskService = engine.getTaskService();

       // Each operation on a KieSession, TaskService, or AuditLogService (client) instance
       // sends a request for the operation to the server side and waits for the response.
       // If something goes wrong on the server side, the client will throw an exception.
       ProcessInstance processInstance = ksession.startProcess("com.burns.reactor.maintenance.cycle");
       long procId = processInstance.getId();

       String taskUserId = user;
       taskService = engine.getTaskService();
       List<TaskSummary> tasks = taskService.getTasksAssignedAsPotentialOwner(user, "en-UK");

       long taskId = -1;
       for (TaskSummary task : tasks) {
           if (task.getProcessInstanceId() == procId) {
               taskId = task.getId();
           }
       }

       if (taskId == -1) {
           throw new IllegalStateException("Unable to find task for " + user + " in process instance " + procId);
       }

       taskService.start(taskId, taskUserId);
   }
 }
}

21.5.2.1. Retrieving Potential Owners of Human Task

To guarantee high performance, the getPotentialOwners() method of the TaskSummary class does not return the list of potential owners of a task.

Instead, you should retrieve information about owners on an individual task basis. In the following example, the mentioned Task is from the org.kie.api.task.model.Task package. Also notice that the method getTaskById() uses the task ID as a parameter.

import org.kie.api.task.model.OrganizationalEntity;
import org.kie.api.task.model.Task;

public List<OrganizationalEntity> getPotentialOwnersByTaskId(long taskId) {
    Task task = taskService.getTaskById(taskId);
    return task.getPeopleAssignments().getPotentialOwners();
}

In addition, actual owners and users created by them can be retrieved using the getActualOwnerId() and getCreatedById() methods.

For a list of Maven dependencies, see Embedded jBPM Engine Dependencies.

21.5.2.2. Calling Tasks Without Deployment ID

The addDeploymentId() method called on the instance of RemoteRuntimeEngineBuilder requires the calling application to pass the deploymentId parameter to connect to Business Central. The deploymentId is the ID of the deployment with which the RuntimeEngine interacts. However, there may be applications that require working with human tasks and dealing with processes across multiple deployments. In such cases, where providing deploymentId parameters for multiple deployments to connect to Business Central is not feasible, it is possible to skip the parameter when using the fluent API of RemoteRestRuntimeEngineBuilder.

This API does not require the calling application to pass the deploymentId parameter. If a request requires the deploymentId parameter, but does not have it configured, an exception is thrown.

import org.kie.api.runtime.manager.RuntimeEngine;
import org.kie.remote.client.api.RemoteRestRuntimeEngineBuilder;
import org.kie.remote.client.api.RemoteRestRuntimeEngineFactory;
import org.kie.remote.client.api.RemoteRuntimeEngineFactory;

import java.net.URL;

...

RuntimeEngine engine = RemoteRuntimeEngineFactory
  .newRestBuilder()
  .addUrl(instanceUrl)
  .addUserName(user)
  .addPassword(password)
  .build();

  // This call does not require the deployment ID and ends successfully:

  engine.getTaskService().claim(23l, "user");

  // This code throws a "MissingRequiredInfoException" because the
  // deployment ID is required:

  engine.getKieSession().startProcess("org.test.process");

For a list of Maven dependencies, see Embedded jBPM Engine Dependencies.

21.5.2.3. Custom Model Objects and Remote API

Working with custom model objects from a client application using the Remote API is supported in Red Hat JBoss BPM Suite. Custom model objects can be created using the Data Modeler in Business Central. Once built and deployed successfully into a project, these objects are part of the project in the local Maven repository.

Note

Reuse model objects instead of recreating them locally in the client application.

The process to access and manipulate these objects from a client application follows.

Procedure: Accessing Custom Model Objects Using Remote API

  1. Ensure that the custom model objects have been installed into the local Maven repository of the project that they are a part of. To achieve that, the project has to be built successfully.
  2. If your client application is a Maven-based project, include project the custom model objects as a Maven dependency in the pom.xml configuration file of the client application.

    To find the Maven GAV of the project: in Business Central, go to AuthoringProject Authoring and ToolsProject Editor.

    If the client application is not a Maven-based project, download the Red Hat JBoss BPM Suite project which includes the model classes: in Business Central, go to AuthoringArtifact Repository. Add this JAR file of the project on the build path of your client application.

  3. You can now use the custom model objects in your client application and invoke methods on them using the Remote API. See the following example with a Person custom model object.

    import java.net.URL;
    import java.util.HashMap;
    import java.util.Map;
    
    import org.kie.api.runtime.KieSession;
    import org.kie.api.runtime.manager.RuntimeEngine;
    import org.kie.api.runtime.process.ProcessInstance;
    import org.kie.remote.client.api.RemoteRestRuntimeEngineBuilder;
    import org.kie.remote.client.api.RemoteRestRuntimeEngineFactory;
    import org.kie.remote.client.api.RemoteRuntimeEngineFactory;
    
    ...
    
    RuntimeEngine engine = RemoteRuntimeEngineFactory
      .newRestBuilder()
      .addUrl(instanceUrl)
      .addUserName(user)
      .addPassword(password)
      .addExtraJaxbClasses(Person.class)
      .addDeploymentId(deploymentId)
      .build();
    
    KieSession kSession = engine.getKieSession();
    
    Map<String, Object> params = new HashMap<>();
    Person person = new Person();
    person.setName("anton");
    params.put("pVar", person);
    ProcessInstance pi = kSession.startProcess(PROCESS2_ID, params);
    System.out.println("Process Started: " + pi.getId());

    For a list of Maven dependencies, see Embedded jBPM Engine Dependencies.

    Ensure that your client application has imported the correct Red Hat JBoss BPM Suite libraries for the example to work.

If you are creating a data object, make sure that the class has the @org.kie.api.remote.Remotable annotation. The @org.kie.api.remote.Remotable annotation makes the entity available for use with JBoss BPM Suite remote services such as REST, JMS, and WS.

There are two ways to add the annotation:

  1. On the Drools & jBPM screen of the data object in Business Central, select the Remotable check box.

    You can also add the annotation manually. On the right side of the Data Object editor screen in Business Central, choose the Advanced tab and click add annotation. In the Add new annotation dialog window, define the annotation class name as org.kie.api.remote.Remotable and click the search button.

  2. It is also possible to edit the source of the class directly. See the following example:

    package org.bpms.helloworld;
    
    @org.kie.api.remote.Remotable
    
    public class Person implements java.io.Serializable {
    	...
    
    }

If you are creating a data object, make sure that the class has the @org.kie.api.remote.Remotable annotation. The @org.kie.api.remote.Remotable annotation makes the entity available for use with the Red Hat JBoss BPM Suite remote services such as REST, JMS, and WS.

21.5.3. JMS Client

RemoteRuntimeEngineFactory works similarly as the REST variation: it is a starting point for building and configuring a new RemoteRuntimeEngine instance that can interact with the remote JMS API. The main use for this class is to create a builder instance of JMS using the newJmsBuilder() method. The builder is then used to create a RemoteRuntimeEngine instance that will act as a client to the remote JMS API.

In addition to methods mentioned in Section 21.5.1, “Common Configuration”, the following configuration methods can be called on RemoteJmsRuntimeEngineBuilder:

addRemoteInitialContext(javax.jms.InitialContext param)
A remote InitialContext instance from the server, created using JNDI.
addConnectionFactory(javax.jms.ConnectionFactory param)
A ConnectionFactory instance used to connect to KieSessionQueue or TaskServiceQueue.
addKieSessionQueue(javax.jms.Queue param)
Sets the JMS queue for requests related to a process instance.
addTaskServiceQueue(javax.jms.Queue param)
Sets the JMS queue for requests related to the task service usage.
addResponseQueue(javax.jms.Queue param)
Sets a JMS queue used for receiving responses.
addJbossServerHostName(String param)
Sets a host name to look up and retrieve a remote instance of InitialContext.
addHostName(String param)
Sets a host name of JMS queues.
addJmsConnectorPort(int param)
Sets a port for the JMS Connector.
addKeystorePassword(String param)
Sets a JMS Keystore password.
addKeystoreLocation(String param)
Specifies a JMS Keystore location.
addTruststorePassword(String param)
Sets a JMS Truststore password.
addTruststoreLocation(String param)
Specifies a JMS Truststore location.
useKeystoreAsTruststore()
Configures the client to use the same file for both Keystore and Truststore.
useSsl(boolean param)
Sets whether this client instance uses secured connection.
disableTaskSecurity()

Turns off SSL usage when communicating with Business Central.

Note that disabling task security exposes users to a man-in-the-middle attack, since no encryption will be used when sending a message containing a password.

The following example illustrates how the Remote Java API can be used with the JMS API.

import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.manager.RuntimeEngine;
import org.kie.api.runtime.process.ProcessInstance;
import org.kie.api.task.TaskService;
import org.kie.api.task.model.TaskSummary;
import org.kie.remote.client.api.RemoteRuntimeEngineFactory;
import org.kie.services.client.builder.objects.MyType;

public class RemoteJavaApiJmsClientExample {

    public void startProcessAndTaskViaJmsRemoteJavaAPI (URL serverUrl, String deploymentId, String user, String password) {
      // The serverURL should contain a URL similar to "http://localhost:8080/business-central".
      // Select a user with the rest-all role.

      // Set up remote JMS runtime engine factory:
      RuntimeEngine engine = RemoteRuntimeEngineFactory
        .newJmsBuilder()
        .addDeploymentId(deploymentId)
        .addJbossServerHostName(serverUrl.getHost())
        .addUserName(user)
        .addPassword(password)
        .build();

        // Interface with JMS API
        KieSession ksession = engine.getKieSession();

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("paramName", new MyType("name", 23));
        ProcessInstance processInstance = ksession.startProcess("com.burns.reactor.maintenance.cycle", params);
        long procId = processInstance.getId();
        TaskService taskService = engine.getTaskService();
        List<Long> tasks = taskService.getTasksByProcessInstanceId(procId);
        taskService.start(tasks.get(0), user);
    }
}
Configuration Using InitialContext Instance

When configuring the RemoteJmsRuntimeEngineBuilder with an InitialContext instance as a parameter, it is necessary to retrieve the (remote) instance of InitialContext first from the server. See the following example:

private InitialContext getRemoteJbossInitialContext(URL url, String user, String password) {

  Properties initialProps = new Properties();
  initialProps.setProperty(InitialContext.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
  String jbossServerHostName = url.getHost();
  initialProps.setProperty(InitialContext.PROVIDER_URL, "remote://"+ jbossServerHostName + ":4447");
  initialProps.setProperty(InitialContext.SECURITY_PRINCIPAL, user);
  initialProps.setProperty(InitialContext.SECURITY_CREDENTIALS, password);

  for (Object keyObj : initialProps.keySet()) {
    String key = (String) keyObj;
    System.setProperty(key, (String) initialProps.get(key));
  }

  try {
    return new InitialContext(initialProps);
  } catch (NamingException e) {
      throw new RemoteCommunicationException("Unable to create "
         + InitialContext.class.getSimpleName(), e);
  }
}

You can work with JMS queues directly without using RemoteRuntimeEngine. For more information, see the How to Use JMS Queues Without the RemoteRuntimeEngine in Red Hat JBoss BPMS article. However, this approach is not a recommended way to use the provided JMS interface.

21.5.4. Supported Methods

The Remote Java API provides client-like instances of the RuntimeEngine, KieSession, TaskService, and AuditService interfaces. This means that while many of the methods in those interfaces are available, some are not. The following tables list the available methods. Methods not listed in the tables below throw UnsupportedOperationException explaining that the called method is not available.

abortProcessInstance(long processInstanceId)
Aborts a process instance. Return value: void.
getProcessInstance(long processInstanceId)
Returns a process instance. Return value: ProcessInstance.
getProcessInstance(long processInstanceId, boolean readonly)
Returns a process instance. Return value: ProcessInstance.
getProcessInstances()
Returns all (active) process instances. Return value: Collection<ProcessInstance>.
signalEvent(String type, Object event)
Signals all (active) process instances. Return value: void.
signalEvent(String type, Object event, long processInstanceId)
Signals a process instance. Return value: void.
startProcess(String processId)
Starts a new process and returns a process instance if the process instance has not immediately completed. Return value: ProcessInstance.
startProcess(String processId, Map<String, Object> parameters)
Starts a new process and returns a process instance if the process instance has not immediately completed. Return value: ProcessInstance.
getFactCount()
Returns the total fact count. Return value: Long.
getGlobal(String identifier)
Returns a global fact. Return value: Object.
setGlobal(String identifier, Object value)
Sets a global fact. Return value: void.

Available WorkItemManager Methods

abortWorkItem(long id)
Aborts a work item. Return value: void.
completeWorkItem(long id, Map<String, Object> results)
Completes a work item. Return value: void.
getWorkItem(long workItemId)
Returns a work item. Return value: WorkItem.

Available Task Operation TaskService Methods

addTask(Task task, Map<String, Object> params)
Adds a new task. Return value: Long.
activate(long taskId, String userId)
Activates a task. Return value: void.
claim(long taskId, String userId)
Claims a task. Return value: void.
claimNextAvailable(String userId, String language)
Claims the next available task for a user. Return value: void.
complete(long taskId, String userId, Map<String, Object> data)
Completes a task. Return value: void.
delegate(long taskId, String userId, String targetUserId)
Delegates a task. Return value: void.
exit(long taskId, String userId)
Exits a task. Return value: void.
fail(long taskId, String userId, Map<String, Object> faultData)
Fails a task. Return value: void.
forward(long taskId, String userId, String targetEntityId)
Forwards a task. Return value: void.
nominate(long taskId, String userId, List<OrganizationalEntity> potentialOwners)
Nominates a task. Return value: void.
release(long taskId, String userId)
Releases a task. Return value: void.
resume(long taskId, String userId)
Resumes a task. Return value: void.
skip(long taskId, String userId)
Skips a task. Return value: void.
start(long taskId, String userId)
Starts a task. Return value: void.
stop(long taskId, String userId)
Stops a task. Return value: void.
suspend(long taskId, String userId)
Suspends a task. Return value: void.
addOutputContent(long taskId, Map<String, Object> params)[4]
Adds output parameters to a task. Return value: RemoteApiResponse<Long>.
getOutputContentMap(long taskId) [4]
Retrieves the output parameters of a task. Return value: RemoteApiResponse<Map<String, Object>>.

Available Task Retrieval and Query TaskService Methods

getTaskByWorkItemId(long workItemId)
Return value: Task.
getTaskById(long taskId)
Return value: Task.
getTasksAssignedAsBusinessAdministrator(String userId, String language)
Return value: List<TaskSummary>.
getTasksAssignedAsPotentialOwner(String userId, String language)
Return value: List<TaskSummary>.
getTasksAssignedAsPotentialOwnerByStatus(String userId, List<Status> status, String language)
Return value: List<TaskSummary>.
getTasksOwned(String userId, String language)
Return value: List<TaskSummary>.
getTasksOwnedByStatus(String userId, List<Status> status, String language)
Return value: List<TaskSummary>.
getTasksByStatusByProcessInstanceId(long processInstanceId, List<Status> status, String language)
Return value: List<TaskSummary>.
getTasksByProcessInstanceId(long processInstanceId)
Return value: List<TaskSummary>.
getTasksAssignedAsPotentialOwnerByProcessId(String userId, String processId)
Return value: List<TaskSummary>.
getContentById(long contentId)
Return value: Content.
getAttachmentById(long attachId)
Return value: Attachment.
Note

The language parameter is not used for task retrieval and query TaskService methods anymore. However, the method signatures still contain it to support backward compatibility. This parameter will be removed in future releases.

Available AuditService Methods

findProcessInstances()
Return value: List<ProcessInstanceLog>.
findProcessInstances(String processId)
Return value: List<ProcessInstanceLog>.
findActiveProcessInstances(String processId)
Return value: List<ProcessInstanceLog>.
findProcessInstance(long processInstanceId)
Return value: ProcessInstanceLog.
findSubProcessInstances(long processInstanceId)
Return value: List<ProcessInstanceLog>.
findNodeInstances(long processInstanceId)
Return value: List<NodeInstanceLog>.
findNodeInstances(long processInstanceId, String nodeId)
Return value: List<NodeInstanceLog>.
findVariableInstances(long processInstanceId)
Return value: List<VariableInstanceLog>.
findVariableInstances(long processInstanceId, String variableId)
Return value: List<VariableInstanceLog>.
findVariableInstancesByName(String variableId, boolean onlyActiveProcesses)
Return value: List<VariableInstanceLog>.
findVariableInstancesByNameAndValue(String variableId, String value, boolean onlyActiveProcesses)
Return value: List<VariableInstanceLog>.
clear()
Return value: void.

21.6. Troubleshooting

21.6.1. Serialization Issues

Sometimes, users may wish to pass instances of their own classes as parameters to commands sent in a REST request or JMS message. In order to do this, there are a number of requirements.

  1. The user-defined class satisfy the following in order to be property serialized and deserialized by the JMS or REST API:

    • The user-defined class must be correctly annotated with JAXB annotations, including the following:

      • The user-defined class must be annotated with a javax.xml.bind.annotation.XmlRootElement annotation with a non-empty name value
      • All fields or getter/setter methods must be annotated with a javax.xml.bind.annotation.XmlElement or javax.xml.bind.annotation.XmlAttribute annotations.

        Furthermore, the following usage of JAXB annotations is recommended:

      • Annotate the user-defined class with a javax.xml.bind.annotation.XmlAccessorType annotation specifying that fields should be used, (javax.xml.bind.annotation.XmlAccessType.FIELD). This also means that you should annotate the fields (instead of the getter or setter methods) with @XmlElement or @XmlAttribute annotations.
      • Fields annotated with @XmlElement or @XmlAttribute annotations should also be annotated with javax.xml.bind.annotation.XmlSchemaType annotations specifying the type of the field, even if the fields contain primitive values.
      • Use objects to store primitive values. For example, use the java.lang.Integer class for storing an integer value, and not the int class. This way it will always be obvious if the field is storing a value.
    • The user-defined class definition must implement a no-arg constructor.
    • Any fields in the user-defined class must either be object primitives (such as a Long or String) or otherwise be objects that satisfy the first 2 requirements in this list (correct usage of JAXB annotations and a no-arg constructor).
  2. The class definition must be included in the deployment JAR of the deployment that the JMS message content is meant for.

    Note

    If you create your class definitions from an XSD schema, you may end up creating classes that inconsistently (among classes) refer to a namespace. This inconsistent use of a namespace can end up preventing a these class instance from being correctly deserialized when received as a parameter in a command on the server side.

    For example, you may create a class that is used in a BPMN2 process, and add an instance of this class as a parameter when starting the process. While sending the command/operation request (via the Remote (client) Java API) will succeed, the parameter will not be correctly deserialized on the server side, leading the process to eventually throw an exception about an unexpected type for the class.

  3. The sender must set a deploymentId string property on the JMS bytes message to the name of the deploymentId. This property is necessary in order to be able to load the proper classes from the deployment itself before deserializing the message on the server side.
Retrieving Process Variables

While submitting an instance of a user-defined class is possible using both the JMS and REST API, retrieving an instance of the process variable is only possible through the REST API.

21.6.2. Insecure Task Operations

By default, you may only work with tasks as the authenticated user. If you try to claim tasks on behalf of another user, you may get an exception similar to:

PermissionDeniedException thrown with message 'User '[UserImpl:'john']' does not have permissions to execute operation 'Claim' on task id 14'

This is caused by the security settings. To bypass the security settings:

  1. Set the org.kie.task.insecure=true property on your server. For example, on Red Hat JBoss EAP, add the following into EAP_HOME/standalone/configuration/standalone.xml:

    <system-properties>
      ...
      <property name="org.kie.task.insecure" value="true"/>
      ...
    </system-properties>
  2. On the client side, do one of the following:

    • Use the disableTaskSecurity() method when building the RuntimeEngine object:

      RuntimeEngine engine = RemoteRuntimeEngineFactory
        .newRestBuilder()
        .addDeploymentId(deploymentId)
        .addUrl(baseUrl)
        .addUserName(user)
        .addPassword(password)
        .disableTaskSecurity()
        .build();
    • Set the org.kie.task.insecure system property to true.

If you are still experiencing the exception in your application, configure the UserGroupCallback settings. See Configuring UserGroupCallback for further information.



[4] To access this method, you must use the org.kie.remote.client.api.RemoteTaskService class instead of the TaskService class.