JBoss.orgCommunity Documentation
The workbench contains an execution server (for executing processes and tasks), which also allows you to invoke various process and task related operations through a remote API. As a result, you can setup your process engine "as a service" and integrate this into your applications easily by doing remote requests and/or sending the necessary triggers to the execution server whenever necessary (without the need to embed or manage this as part of your application).
Both a REST and JMS based service are available (which you can use directly), and a Java remote client allows you to invoke these operations using the existing KieSession and TaskService interfaces (you also use for local interaction), making remote integration as easy as if you were interacting with a local process engine.
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 take care of the underlying
logic needed to communicate with the JMS or REST APIs. In other words, these implementations
will allow you to interact with a remote workbench instance (i.e. KIE workbench or the jBPM
Console) via known interfaces such as the KieSession
or TaskService
interface,
without having to deal with the underlying transport and serialization details.
The first step in interacting with the remote runtime is to use a RemoteRuntimeEngineFactory
static newRestBuilder()
, newJmsBuilder()
or newCommandWebServiceClientBuilder()
to create
a builder instance. Use the new builder instance to configure and to create a RuntimeEngine
instance to interact with the server.
Each of the REST, JMS or WebService RemoteClientBuilder
instances exposes different
methods that allow the configuration of properties like the base URL of the REST API, JMS queue
locations or timeout while waiting for responses.
While the KieSession
, TaskSerivce
and AuditService
instances provided by the Remote Java API
may "look" and "feel" like local instances of the same interfaces, please 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 a RuntimeException
indicating that the REST call failed. This is
different from the behaviour of a "real" (or local) instance of a KieSession
, TaskSerivce
and
AuditService
instance because the exception the local instances will throw will relate to how the
operation failed. 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 a RuntimeException
instead when the requested operation
fails on the server.
Also, while local instances require different handling (such as having to dispose of a KieSession
),
client instances provided by the Remote Java API hold no state and thus do not require any special
handling.
Finally, the instances returned by the client KieSession
and TaskService
instances (for example,
process instances or task summaries) are not the same (internal) objects as used by the core engines.
Instead, these returned instances are simple data transfer objects (DTOs) that implement the same
interfaces but are designed to only return the associated data. Modifying or casting these returned
instances to an internal implementation class will not succeed.
Each builder has a number of different (required or optional) methods to configure a client
RuntimeEngine
instance.
Remote Rest Runtime Engine Builder methods
addDeploymentId(String deploymentId)
when
Set the deployment id of the deployment
addExtraJaxbClasses(Class… extraJaxbClasses )
when
Add extra classes to the classpath available to the serialization mechanisms
When passing instances of user-defined classes in a Remote Java API call, it’s important to use this method first to add the classes so that the class instances can be serialized correctly.
addPassword(String password)
always
addProcessInstanceId(long process)
when
Set the process instance id of the deployment
PER_PROCESS_INSTANCE
deploymentaddTimeout(int timeoutInSeconds)
Set the timeout for the REST call
The default is 5 seconds.
addUrl(URL serverInstanceUrl)
always
Set the URL for the application instance
This should be a URL that roughly corresponds to
http://server:port/business-central/
or
http://server:port/kie-wb/
.
addUserName(String userName)
always
clearJaxbClasses()
The following example illustrates how the Remote Java API can be used with the REST API.
public void startProcessAndHandleTaskViaRestRemoteJavaAPI(URL serverRestUrl, String deploymentId, String user, String password) {
// the serverRestUrl should contain a URL similar to "http://localhost:8080/jbpm-console/"
// Setup the factory class with the necessarry information to communicate with the REST services
RuntimeEngine engine = RemoteRuntimeEngineFactory.newRestBuilder()
.addUrl(serverRestUrl)
.addTimeout(5)
.addDeploymentId(deploymentId)
.addUserName(user)
.addPassword(password)
// if you're sending custom class parameters, make sure that
// the remote client instance knows about them!
.addExtraJaxbClasses(MyType.class)
.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.
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();
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);
// resultData can also just be null
Map<String, Object> resultData = new HashMap<String, Object>();
taskService.complete(taskId, taskUserId, resultData);
}
When configuring the remote JMS client, you must choose one of the following ways to configure the JMS connection:
Pass the ConnectionFactory
instance and the KieSession, TaskService and Response Queue
instances when configuring the remote java client. To do that, please use the following methods:
addConnectionFactory(ConnectionFactory)
addKieSessionQueue(Queue)
addTaskServiceQueue(Queue)
addResponseQueue(Queue)
addHostName(String)
addJmsConnectorPort(String)
or pass a remote InitialContext
instance that contains references to the necessary
ConnectionFactory
and Queue
instances (see previous bullet).
addRemoteInitialContext(InitialContext)
or pass a String with the hostname of the JBoss EAP server that KIE Workbench is running on
addJbossServerHostName(String)
In addition, if you are doing an operation on a task via the remote JMS client (and are not
using the disableTaskSecurity()
method), then you must also configure SSL. The following methods
(described in more detail below) are available for this:
addHostName(String)
addJmsConnectorPort(int)
addKeystoreLocation(String)
addKeystorePassword(String)
addTruststoreLocation(String)
addTruststorePassword(String)
useKeystoreAsTruststore()
Each builder has a number of different (required or optional) methods to configure a client
RuntimeEngine
instance.
Remote JMS Runtime Engine Builder methods
addConnectionFactory(ConnectionFactory connectionFactory)
when
Add a ConnectionFactory
used to create JMS session to send and receive messages
ConnectionFactory
and Queue
instancesaddDeploymentId(String deploymentId)
when
Set the deployment id of the deployment
addExtraJaxbClasses(Class… extraJaxbClasses )
when
Add extra classes to the client for when user-defined class instances are passed as parameters to client methods
When passing instances of user-defined classes in a Remote Java API call, it’s important to use this method first to add the classes so that the class instances can be serialized correctly.
addHostName(String hostname)
when
Set the host name for the server that the client is making a JMS connection with
configuring the JMS java client by setting ConnectionFactory
and Queue
instances
configuring the JMS java client to use SSL
addJbossServerHostName(String hostname)
Set the host name of the JBoss EAP server that the client is making a JMS connection with
After using this method, no other configuration is needed with regards to the server. However, additional server parameters (host name, port) may be needed when also configuring SSL.
Make sure that the EAP version-appropriate org.jboss.naming:jboss-naming
dependency is available
on the classpath when doing this
addJmsConnectorPort(int port)
when
Set the port used for the JMS connection connection with the server
configuring the JMS java client by passing ConnectionFactory
and Queue
instances
configuring the JMS java client to use SSL
addKeystoreLocation(String keystorePath)
when
Set the location (path) of the keystore
addKeystorePassword(String keystorePassword)
when
Set the password for the keystore
addKieSessionQueue(Queue ksessionQueue)
when
Pass the javax.jms.Queue
instance representing
the KIE.SESSION queue used to receive process instance requests from the client
ConnectionFactory
and Queue
instancesaddPassword(String password)
always
addProcessInstanceId(long process)
when
Set the process instance id of the deployment
addRemoteInitialContext(InitialContext remoteInitialContext)
Set the remote InitialContext
instance from the remote application server, which is then used to retrieve the ConnectionFactory
and Queue
instances
After using this method, no other configuration is needed with regards to the server. However, additional server parameters (host name, port) may be needed when also configuring SSL.
addResponseQueue(Queue responseQueue)
when
Pass the javax.jms.Queue
instance representing
the KIE.RESPONSE queue used to send responses to the client
ConnectionFactory
and Queue
instancesaddTaskServiceQueue(Queue taskServiceQueue)
when
Pass the javax.jms.Queue
instance representing
the KIE.TASK queue used to receive task operation requests to the client
ConnectionFactory
and Queue
instancesaddTimeout(int timeoutInSeconds)
addTruststoreLocation(String truststorePath)
when
Set the location (path) of the keystore
addTruststoreLocation(String truststorePassword)
when
Set the password for the keystore
addUserName(String userName)
always
Set the name of the user connecting to the server
This is also the user whose permissions will be used when doing any task operations
clearJaxbClasses()
disableTaskSecurity()
useKeystoreAsTruststore()
In order to instantiate a remote InitialContext
via JNDI, the application-server-specific
dependencies need to be included on the classpath.
For JBoss EAP 6, the artifact (jar) containing this class is the
org.jboss:jboss-remote-naming
artifact (jar), version
1.0.5.Final
or higher. Depending on the version of AS 7 or EAP 6 that you
use, this version may vary.
If you are using a different application server, please see your specific
application server documentation for the parameters and artifacts necessary to create an
InitialContextFactory
instance or otherwise get a remote
InitialContext
instance (via JNDI) from the application server instance.
The following example illustrates how to configure a Remote Java API JMS client using
a remote InitialContext
instance along with SSL. In this case, the same file is being used as
both the client’s keystore (the client’s identifying keys and certificates) and as the client’s
truststore (the client’s list of trusted certificates from other parties, in this case, the server).
public void startProcessAndHandleTaskViaJmsRemoteJavaAPISsl(String hostNameOrIpAdress, int jmsSslConnectorPort,
String deploymentId, String user, String password,
String keyTrustStoreLocation, String keyTrustStorePassword,
String processId) {
InitialContext remoteInitialContext = getRemoteInitialContext();
RuntimeEngine engine = RemoteRuntimeEngineFactory.newJmsBuilder()
.addDeploymentId(deploymentId)
.addRemoteInitialContext(remoteInitialContext)
.addUserName(user)
.addPassword(password)
.addHostName(hostNameOrIpAdress)
.addJmsConnectorPort(jmsSslConnectorPort)
.useKeystoreAsTruststore()
.addKeystoreLocation(keyTrustStoreLocation)
.addKeystorePassword(keyTrustStorePassword)
.build();
// create JMS request
KieSession ksession = engine.getKieSession();
ProcessInstance processInstance = ksession.startProcess(processId);
long procInstId = processInstance.getId();
logger.debug("Started process instance: " + procInstId );
TaskService taskService = engine.getTaskService();
List<TaskSummary> taskSumList
= taskService.getTasksAssignedAsPotentialOwner(user, "en-UK");
TaskSummary taskSum = null;
for( TaskSummary taskSumElem : taskSumList ) {
if( taskSumElem.getProcessInstanceId().equals(procInstId) ) {
taskSum = taskSumElem;
}
}
long taskId = taskSum.getId();
logger.debug("Found task " + taskId);
// get other info from task if you want to
Task task = taskService.getTaskById(taskId);
logger.debug("Retrieved task " + taskId );
taskService.start(taskId, user);
Map<String, Object> resultData = new HashMap<String, Object>();
// insert results for task in resultData
taskService.complete(taskId, user, resultData);
logger.debug("Completed task " + taskId );
}
Starting with this release, a simple webservice has been added to the remote API.
Remote Webservice Client Builder methods
addDeploymentId(String deploymentId)
when
Set the deployment id of the deployment
addExtraJaxbClasses(Class… extraJaxbClasses )
when
Add extra classes to the client for when user-defined class instances are passed as parameters to client methods
When passing instances of user-defined classes in a Remote Java API call, it’s important to use this method first to add the classes so that the class instances can be serialized correctly.
addServerUrl(URL applicationUrl)
always
addPassword(String password)
always
addTimeout(int timeoutInSeconds)
addUserName(String userName)
always
Set the name of the user connecting to the server
This is also the user whose permissions will be used when doing any task operations
setWsdlLocationRelativePath()
useHttpRedirect()
As mentioned above, 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 lists the methods
which are available. Methods not listed in the below, will throw an UnsupportedOperationException
explaining that the
called method is not available.
Table 17.1. Available process-related KieSession
methods
Return type | Method signature | Description |
---|---|---|
|
|
Abort the process instance |
|
|
Return the process instance |
|
|
Return the process instance |
|
|
Return all (active) process instances |
|
|
Signal all (active) process instances |
|
|
Signal the process instance |
|
|
Start a new process and return the process instance (if the process instance has not immediately completed) |
|
|
Start a new process and return the process instance (if the process instance has not immediately completed) |
Table 17.2. Available rules-related KieSession
methods<
Return type | Method signature | Description |
---|---|---|
|
|
Return the total fact count |
|
|
Return a global fact |
|
|
Return the id of the |
|
|
Set a global fact |
|
|
Fire all rules |
Table 17.3. Available WorkItemManager
methods
Return type | Method signature | Description |
---|---|---|
|
|
Abort the work item |
|
|
Complete the work item |
|
|
Return the work item |
Table 17.4. Available task operation TaskService
methods
Return type | Method signature | Description |
---|---|---|
|
|
Add a new task |
|
|
Activate a task |
|
|
Claim a task |
|
|
Claim a task |
|
|
Claim the next available task for a user |
|
|
Claim the next available task for a user |
|
|
Complete a task |
|
|
Delegate a task |
|
|
Exit a task |
|
|
Fail a task |
|
|
Forward a task |
|
|
Nominate a task |
|
|
Release a task |
|
|
Remove a task |
|
|
Resume a task |
|
|
Skip a task |
|
|
Start a task |
|
|
Stop a task |
|
|
Suspend a task |
Table 17.5. Available task retrieval and query TaskService
methods
Return type | Method signature |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
`List<TaskSummary> |
|
|
|
|
|
|
|
Table 17.6. Available AuditService
methods
Return type | Method signature |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
REST API calls to the execution server allow you to remotely manage processes and tasks and retrieve
various dynamic information from the execution server. The majority of the calls are synchronous,
which means that the call will only finish once the requested operation has completed on the server.
The exceptions to this are the deployment POST
calls, which will return the status of the request
while the actual operation requested will asynchronously execute.
When using Java code to interface with the REST API, the classes used in POST operations or
otherwise returned by various operations can be found in the (org.kie.remote:)kie-services-client
JAR.
This section lists REST calls that interface process instances.
The deploymentId component of the REST calls below must conform to the following regular expression:
[\w\.-]+(:[\w\.-]+){2,2}(:[\w\.-]*){0,2}
For more information about the composition of the deployment id, see the Deployment Calls section.
[POST]
/runtime/{deploymentId}/process/{processDefId}/start
JaxbProcessInstanceResponse
instance, that contains basic information about the
process instance.Notes:
[_a-zA-Z0-9-:\.]+
Parameters:
[POST]
rest/runtime/{deploymentId}/process/{processDefId}/startform
JaxbProcessInstanceFormResponse
instance, that contains the URL to the start process
form.Notes:
[_a-zA-Z0-9-:\.]+
[GET]
/runtime/{deploymentId}/process/instance/{procInstId}
JaxbProcessInstanceResponse
instance.Notes:
[0-9]+
[POST]
/runtime/{deploymentId}/process/instance/{procInstId+}/abort
JaxbGenericResponse
indicating whether or not the operation has succeeded.Notes:
[0-9]+
[POST]
/runtime/{deploymentId}/process/instance/{procInstId}/signal
JaxbGenericResponse
indicating whether or not the operation has succeeded.Notes:
[0-9]+
Parameters: This operation takes a signal
and a event
query parameter.
signal
parameter value is used as the name of the signal. This parameter is required.event
parameter value is used as the value of the event. This value may use the number
query parameter syntax described above.[GET]
/runtime/{deploymentId}/process/instance/{procInstId}/variable/{varName}
Notes:
[0-9]+
[POST]
/runtime/{deploymentId}/signal
KieSession
JaxbGenericResponse
indicating whether or not the operation has succeeded.Notes:
[0-9]+
Parameters: This operation takes a signal
and a event
query parameter.
signal
parameter value is used as the name of the signal. This parameter is required.event
parameter value is used as the value of the event. This value may use the number query parameter syntax described above.[GET]
/runtime/{deploymentId}/workitem/{workItemId}
WorkItem
instanceJaxbWorkItem
instanceNotes:
[0-9]+
[POST]
/runtime/{deploymentId}/workitem/{workItemId}/complete
WorkItem
JaxbGenericResponse
indicating whether or not the operation has succeededNotes:
[0-9]+
Parameters:
[POST]
/runtime/{deploymentId}/workitem/{workItemId: [0-9-]+}/abort
WorkItem
JaxbGenericResponse
indicating whether or not the operation has succeededNotes:
[0-9]+
[POST]
/runtime/{deploymentId}/withvars/process/{processDefId}/start
Returns a JaxbProcessInstanceWithVariablesResponse
that contains:
JaxbProcessInstanceResponse
Notes:
[_a-zA-Z0-9-:\.]+
[POST]
/runtime/{deploymentId}/withvars/process/instance/{procInstId}
JaxbProcessInstanceWithVariablesResponse
(see the above REST call)Notes:
[0-9]+
[POST]
/runtime/{deploymentId}/withvars/process/instance/{procInstId}/signal
JaxbProcessInstanceWithVariablesResponse
(see above)Notes:
[0-9]+
Parameters:: This operation takes a signal
and a event
query parameter.
signal
parameter value is used as the name of the signal. This parameter is required.event
parameter value is used as the value of the event. This value may use the number query parameter syntax described above.[POST]
/history/clear
[GET]
/history/instances
ProcessInstanceLog
instancesJaxbHistoryLogList
instance that contains a list of JaxbProcessInstanceLog
instancesNotes:
[GET]
/history/instance/{procInstId}
ProcessInstanceLog
instance associated with the specified process instanceJaxbHistoryLogList
instance that contains a JaxbProcessInstanceLog
instanceNotes:
[0-9]+
[GET]
/history/instance/{procInstId}/child
ProcessInstanceLog
instances associated with any child/sub-processes associated with the specified process instanceJaxbHistoryLogList
instance that contains a list of JaxbProcessInstanceLog
instancesNotes:
[0-9]+
[GET]
/history/instance/{procInstId}/node
NodeInstanceLog
instances associated with the specified process instanceJaxbHistoryLogList
instance that contains a list of JaxbNodeInstanceLog
instancesNotes:
[0-9]+
[GET]
/history/instance/{procInstId}/variable
VariableInstanceLog
instances associated with the specified process instanceJaxbHistoryLogList
instance that contains a list of JaxbVariableInstanceLog
instancesNotes:
[0-9]+
[GET]
/history/instance/{procInstId}/node/{nodeId}
NodeInstanceLog
instances associated with the specified process instance that have the given (node) idJaxbHistoryLogList
instance that contains a list of JaxbNodeInstanceLog
instancesNotes:
[0-9]+
[a-zA-Z0-9-:\.]+
[GET]
/history/instance/{procInstId}/variable/{varId}
VariableInstanceLog
instances associated with the specified process instance that have the given (variable) idJaxbHistoryLogList
instance that contains a list of JaxbVariableInstanceLog
instancesNotes:
[0-9]+
[a-zA-Z0-9-:\.]+
[GET]
/history/process/{processDefId}
ProcessInstanceLog
instances associated with the specified process definitionJaxbHistoryLogList
instance that contains a list of JaxbProcessInstanceLog
instancesNotes:
[_a-zA-Z0-9-:\.]+
[GET]
/history/variable/{varId}
VariableInstanceLog
instances associated with the specified variable idJaxbHistoryLogList
instance that contains a list of JaxbVariableInstanceLog
instancesNotes:
[a-zA-Z0-9-:\.]+
[GET]
/history/variable/{varId}/value/{value}
VariableInstanceLog
instances associated with the specified variable id that contain the value specifiedJaxbHistoryLogList
instance that contains a list of JaxbVariableInstanceLog
instancesNotes:
[a-zA-Z0-9-:\.]+
[GET]
/history/variable/{varId}/instances
ProcessInstance
instances that contain the variable specified by the given variable id.JaxbProcessInstanceListResponse
instance that contains a list of JaxbProcessInstanceResponse
instancesNotes:
[a-zA-Z0-9-:\.]+
[GET]
/history/variable/{varId}/value/{value}/instances
ProcessInstance
instances that contain the variable specified by the given variable id which contains the (variable) value specifiedJaxbProcessInstanceListResponse
instance that contains a list of JaxbProcessInstanceResponse
instancesNotes:
[a-zA-Z0-9-:\.]+
[GET]
/runtime/{deploymentId}/history/variable/{varId}
VariableInstanceLog
instances associated with the specified variable idJaxbHistoryLogList
instance that contains a list of JaxbVariableInstanceLog
instancesNotes:
[a-zA-Z0-9-:\.]+
[GET]
/runtime/{deploymentId}/history/variable/{varId}/value/{value}
VariableInstanceLog
instances associated with the specified variable id that contain the value specifiedJaxbHistoryLogList
instance that contains a list of JaxbVariableInstanceLog
instancesNotes:
[a-zA-Z0-9-:\.]+
[GET]
/runtime/{deploymentId}/history/variable/{varId}/instances
ProcessInstance
instances that contain the variable specified by the given variable id.JaxbProcessInstanceListResponse
instance that contains a list of JaxbProcessInstanceResponse
instancesNotes:
[a-zA-Z0-9-:\.]+
[GET]
/runtime/{deploymentId}/history/variable/{varId}/value/{value}/instances
ProcessInstance
instances that contain the variable specified by the given variable id which contains the (variable) value specifiedJaxbProcessInstanceListResponse
instance that contains a list of JaxbProcessInstanceResponse
instancesNotes:
[a-zA-Z0-9-:\.]+
The following section describes the three different types of task calls:
* Task REST operations that mirror the TaskService
interface, allowing the user to interact with the remote TaskService
instance
* The Task query REST operation, that allows users to query for Task
instances
* Other Task REST operations that retrieve information
Task operation authorizations. Task REST operations use the user information (used to authorize and authenticate the HTTP call) to check whether or not the requested operations can happen. This also applies to REST calls that retrieve information, such as the task query operation. REST calls that request information will only return information about tasks that the user is allowed to see.
With regards to retrieving information, only users associated with a task may retrieve information about the task. However, the authorizations of progress and other modifications of task information are more complex. See the Task Permissions section in the Task Service documentation for more infomration.
Given that many users have expressed the wish for a "super-task-user" that can execute task REST operations on all tasks, regardless of the users associated with the task, there are now plans to implement that feature. However, so far for the 6.x releases, this feature is not available.
All of the task operation calls described in this section use the user (id) used in the REST basic authorization as input for the user parameter in the specific call.
Some of the operations take an optional lanaguage
query parameter. If this parameter is not given
as a element of the URL itself, the default value of “en-UK” is used.
The taskId component of the REST calls below must conform to the following regex:
[0-9]+
[POST]
/task/{taskId}/activate
JaxbGenericResponse
with the status of the operation[POST]
/task/{taskId}/claim
JaxbGenericResponse
with the status of the operation[POST]
/task/{taskId}/claimnextavailable
JaxbGenericResponse
with the status of the operationlanguage
query parameter.[POST]
/task/{taskId}/complete
- Completes a task
- Returns a JaxbGenericResponse
with the status of the operation
- Parameters: Takes map query parameters, which are the "results" input for the complete operation
[POST]
/task/{taskId}/delegate
JaxbGenericResponse
with the status of the operationtargetId
query parameter, which identifies the user or group to which the task is delegated[POST]
/task/{taskId}/exit
JaxbGenericResponse
with the status of the operation[POST]
/task/{taskId}/fail
JaxbGenericResponse
with the status of the operation[POST]
/task/{taskId}/forward
JaxbGenericResponse
with the status of the operationtargetId
query parameter, which identifies the user or group to which the task is forwarded[POST]
/task/{taskId}/nominate
JaxbGenericResponse
with the status of the operationuser
or group
query parameter, which identify the user(s) or group(s) that are nominated for the task[POST]
/task/{taskId}/release
JaxbGenericResponse
with the status of the operation[POST]
/task/{taskId}/resume
JaxbGenericResponse
with the status of the operation[POST]
/task/{taskId}/skip
JaxbGenericResponse
with the status of the operation[POST]
/task/{taskId}/start
JaxbGenericResponse
with the status of the operation[POST]
/task/{taskId}/stop
- Stops a task
- Returns a JaxbGenericResponse
with the status of the operation
[POST]
/task/{taskId}/suspend
JaxbGenericResponse
with the status of the operation[GET]
/task/{taskId}/showTaskForm
JaxbTaskFormResponse
instance, that contains the URL to the task form./task/query
/task/query
operation queries all non-archived tasks based on the parameters given.JaxbTaskSummaryListResponse
with a list of TaskSummaryImpl
Parameters:
All parameters except for the union
parameter may be repeated.
businessAdministrator
potentialOwner
processInstanceId
status
taskId
taskOwner
workItemId
language
union
Example 17.1. Query usage
This call retrieves the task summaries of all tasks that have a work item id of 3, 4, or 5. If you specify the same parameter multiple times, the query will select tasks that match any of that parameter.
http://server:port/rest/task/query?workItemId=3&workItemId=4&workItemId=5
The next call will retrieve any task summaries for which the task id is 27 and for which the work item id is 11. Specifying different parameters will result in a set of tasks that match both (all) parameters.
`http://server:port/rest/task/query?workItemId=11&taskId=27`
The next call will retrieve any task summaries for which the task id is 27 or the
work item id is 11. While these are different parameters, the union
parameter is being used
here so that the union of the two queries (the work item id query and the task id query) is returned.
http://server:port/rest/task/query?workItemId=11&taskId=27&union=true`
The next call will retrieve any task summaries for which the status is Created
and the potential owner of the task is Bob
. Note that the letter case for the status
parameter value is case-'in’sensitve.
http://server:port/rest/task/query?status=creAted&potentialOwner=Bob`
The next call will return any task summaries for which the status is Created
and the potential owner of the task is bob
. Note that the potential owner parameter is
case-'sensitive'. bob
is not the same user id as Bob
!
http://server:port/rest/task/query?status=created&potentialOwner=bob`
The next call will return the intersection of the set of task summaries for which the
process instance is 201, the potential owner is bob
and for which the status is Created
or Ready
.
http://server:port/rest/task/query?status=created&status=ready&potentialOwner=bob&processInstanceId=201
That means that the task summaries that have the following characteristics would be included:
bob
, status Ready
bob
, status Created
And that following task summaries will not be included:
bob
, status Created
Ready
bob
, status `Complete`
[GET]
/task/{taskId}/content
JaxbContent
with the content of the taskNotes:
[0-9]+
[GET]
/task/content/{contentId}
JaxbContent
with the content of the taskNotes:
[0-9]+
The calls described in this section allow users to manage deployments. Deployments are in fact
KieModule
JARs which can be deployed or undeployed, either via the UI or via the REST calls described
below. Configuration options, such as the runtime strategy, should be specified when deploying the deployment:
the configuration of a deployment can not be changed after it has already been deployed.
The above deploymentId regular expression describes an expression that contains the following elements, separated from eachother by a :
character:
In a more formal sense, the deploymentId component of the REST calls below must conform to the following regex:
`[\w\.-]+(:[\w\.-]+){2,2}(:[\w\.-]*){0,2}`
This regular expression is explained as follows:
[\w\.-]
element, which occurs 3 times in the above regex, refers to a character set that can contain the following character sets:This [\w\.-]
element occurs at least 3 times and at most 5 times, separated by a :
character each time.
Example 17.2. Accepted deploymentId's
com.wonka:choco-maker:67.190
These example `deploymentId’s contain the optional kbase and ksession id groups.
com.wonka:choco-maker:67.190:oompaBase
com.wonka:choco-maker:67.190:oompaLoompaBase:gloopSession
There are 2 operations that can be used to modify the status of a deployment:
/deployments/{deploymentId}/deploy
/deployments/{deploymentId}/undeploy
These POST
deployment calls are both asynchronous, which
means that the information returned by the POST
request does not reflect the
eventual final status of the operation itself.
As noted above, both the /deploy
and /undeploy
operations are
asynchronous REST operations. Successfull requests to these URLs will return the
status 202
upon the request completion. RFC 2616 defines the 202
status
as meaning the following:
RFC 2616: "the request has been accepted for processing, but the processing has not been completed."
This means the following:
GET
operations described below, are snapshots and the information (including the status of the
deployment unit) may have changed by the time the user client receives the answer to the GET
request.[GET]
/deployment/
JaxbDeploymentUnitList
instance[GET]
/deployment/ {deploymentId}
JaxbDeploymentUnit
instance containing the information (including the configuration) of the deployment unit.Notes:
[POST]
/deployment/{deploymentId}/deploy
JaxbDeploymentJobResult
instance with the status of the request
Parameters: Takes a strategy
query parameter, which
must have one of the following (case-_in_sensitive) values:
SINGLETON
PER_REQUEST
PER_PROCESS_INSTANCE
SINGLETON
.Notes:
GET
calls
described above.It is possible to post a deployment descriptor (or a fragment of it) while
submitting deploy request. That allows to override other deployment descriptors in
the hierarchy. To do so the content type of the request must be set to application/xml
and the request
body should be a a valid deployment descriptor content.
Example 17.3. Changing the audit logging mode from default JPA to JMS submit
<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>
Since deployment descriptors can be merged differently, it’s possibile to provide the merge mode as part of deploy request by adding query parameter:
mergemode
where values should be one of the following
[POST]
/deployment/{deploymentId}/undeploy
deploymentId
JaxbDeploymentJobResult
instance with the status of the request
Notes:
GET
calls described above.While there is a /runtime/{id}/execute
and a task/execute
method, both will take all types
of commands. This is possible because execute takes a JaxbCommandsRequest object, which contains a list of
(org.kie.api.command.)Command
objects. The JaxbCommandsRequest
has fields to store the proper
deploymentId
and processInstanceId
information.
Of course, if you send a request with a command that needs this information (deploymentId
, for example)
and don’t fill the deploymentId
in, the request will fail.
[POST]
/execute
Command
JaxbCommandResponse
implementation with the result of the operationTable 17.8. Runtime commands
AbortWorkItemCommand |
GetProcessInstancesCommand |
GetIdCommand |
CompleteWorkItemCommand |
SetProcessInstanceVariablesCommand |
SetGlobalCommand |
GetWorkItemCommand |
SignalEventCommand | |
StartCorrelatedProcessCommand |
DeleteCommand | |
AbortProcessInstanceCommand |
StartProcessCommand |
FireAllRulesCommand |
GetProcessIdsCommand |
GetVariableCommand |
InsertObjectCommand |
GetProcessInstanceByCorrelationKeyCommand |
GetFactCountCommand |
UpdateCommand |
Table 17.9. Task commands
ActivateTaskCommand |
FailTaskCommand |
GetTasksOwnedCommand |
AddTaskCommand |
ForwardTaskCommand |
NominateTaskCommand |
CancelDeadlineCommand |
GetAttachmentCommand |
ProcessSubTaskCommand |
ClaimNextAvailableTaskCommand |
GetContentCommand |
ReleaseTaskCommand |
ClaimTaskCommand |
GetTaskAssignedAsBusinessAdminCommand |
ResumeTaskCommand |
CompleteTaskCommand |
GetTaskAssignedAsPotentialOwnerCommand |
SkipTaskCommand |
CompositeCommand |
GetTaskByWorkItemIdCommand |
StartTaskCommand |
DelegateTaskCommand |
GetTaskCommand |
StopTaskCommand |
ExecuteTaskRulesCommand |
GetTasksByProcessInstanceIdCommand |
SuspendTaskCommand |
Table 17.10. History/Audit commands
ClearHistoryLogsCommand |
FindProcessInstanceCommand |
FindSubProcessInstancesCommand |
FindActiveProcessInstancesCommand |
FindProcessInstancesCommand |
FindVariableInstancesByNameCommand |
FindNodeInstancesCommand |
FindSubProcessInstancesCommand |
FindVariableInstancesCommand |
The following /rest/execute
call can be used to start a process (with process id ‘evaluation’ in
the project with deployment id ‘org.jbpm:Evaluation:1.0’) and two parameters (parameter employee
equal to ‘krisv’ and reason
equal to ‘Yearly performance evaluation’).
<?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>
Note that the request should also contain the following HTTP headers:
application/xml
The response will contain information about the process instance that was just started:
<?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>
The /execute
operation also supports sending user-defined class instances as parameters in the
command. This relies on JAXB for serialization and deserialization. To be able to deserialize the
custom class on the server side, a "Kie-Deployment-Id" header must also be set to the deployment id
of the project.
For example, when starting a process or completing a task, a user typically passes additional parameters (process variable values or the result data for the completed task). These values are then either primitives (Strings, ints, etc.) or user-defined classes that were created using the data modeler in the workbench, added directly to the deployed project or part of a dependency to the deployment (project).
The following request starts a process which contains a custom TestObject
class (with two fields)
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>
Just as in the basic example above, both a Content-Type
and Authorization
header should be set
in the request.
The 3 headers that therefore need to be set in the requst are the following:
application/xml
The URL templates in the table below are relative to the one of the following URLs:
/runtime/{deploymentId}/process/{procDefID}/start
/runtime/{deploymentId}/process/{procDefID}/startform
/runtime/{deploymentId}/process/instance/{procInstanceID}
/runtime/{deploymentId}/process/instance/{procInstanceID}/abort
/runtime/{deploymentId}/process/instance/{procInstanceID}/signal
/runtime/{deploymentId}/process/instance/{procInstanceID}/variable/{varId}
/runtime/{deploymentId}/signal/{signalCode}
/runtime/{deploymentId}/workitem/{workItemID}/complete
/runtime/{deploymentId}/workitem/{workItemID}/abort
/runtime/{deploymentId}/withvars/process/{procDefinitionID}/start
/runtime/{deploymentId}/withvars/process/instance/{procInstanceID}/
/runtime/{deploymentId}/withvars/process/instance/{procInstanceID}/signal
send a signal event to the 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
/task/query
/task/content/{contentID}
/task/{taskID}
/task/{taskID}/activate
/task/{taskID}/claim
/task/{taskID}/claimnextavailable
/task/{taskID}/complete
/task/{taskID}/delegate
/task/{taskID}/exit
/task/{taskID}/fail
/task/{taskID}/forward
/task/{taskID}/nominate
/task/{taskID}/release
/task/{taskID}/resume
/task/{taskID}/skip
/task/{taskID}/start
/task/{taskID}/stop
/task/{taskID}/suspend
/task/{taskID}/content
/task/{taskID}/showTaskForm
/history/clear/
/history/instances
/history/instance/{procInstId}
/history/instance/{procInstId}/child
/history/instance/{procInstId}/node
/history/instance/{procInstId}/node/{nodeId}
/history/instance/{procInstId}/variable
/history/instance/{procInstId}/variable/{variableId}
/history/process/{procDefId}
/history/variable/{varId}
/history/variable/{varId}/instances
/history/variable/{varId}/value/{value}
/history/variable/{varId}/value/{value}/instances
/deployments
/deployment/{deploymentId}
/deployment/{deploymentId}/deploy
/deployment/{deploymentId}/undeploy
The REST Query API allows users of the jBPM console and the KIE workbench (as well as products based on these applications) to "richly" query tasks, variables and process instances.
The rich query operations can be reached via the following URLs:
http://server.address:port/{application-id}/rest/query/ runtime task * [GET] rich query for task summaries and process variables process * [GET] rich query for process instances and process variables
Both url’s take a number of different query parameters. See the next section for a description of these.
In the documentation below,
processInstanceId
, taskId
and tid
. The case (lowercase
or uppercase) of these parameters does not matter, except when the query parameter
also specifies the name of a user-defined variable.org.process.frombulator
, 29
and harry
.When you submit a REST call to the query operation, your URL will look something like this:
http://localhost:8080/business-central/rest/query/runtime/process/processId=org.process.frombulator&piid=29
A query containing multiple different query parameters will search for the intersection of the given parameters.
However, many of the query parameters described below can be entered multiple times: when multiple values are given for the same query parameter, the query will then search for any results that match one or more of the values entered.
Example 17.4. Repeated query parameters
The following process instance query:
processId=org.example.process&processInstanceId=27&processInstanceId=29
will return a result that
Some query criteria can be given in ranges while for others, a simple regular expression language can be used to describe the value.
Query parameters that
In order to pass the lower end or start of a range, add _min
to end of the parameter name.
In order to pass the upper end or end of a range, add _max
to end of the parameter name.
Range ends are inclusive.
Only passing one end of the range (the lower or upper end), results in querying on an open ended range.
Example 17.5. Range parameters
The following task query:
processId=org.example.process&taskId_min=50&taskId_max=53
will return a result that
While the following task query:
processId=org.example.process&taskId_min=52
will return a result that
In order to apply regular expressions to a query parameter, add “_re” to the end of the parameter name.
The regular expression language contains 2 special characters:
*
means 0 or more characters.
means 1 characterThe slash character (\
) is not interpreted.
Example 17.6. Regular expression parameters
The following process instance query
processId_re=org.example.*&processVersion=2.0
will return a result that
only contains 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
The "task or process" column describes whether or not a query parameter can be used with the task and/or the process instance query operations.
Table 17.11. Query parameters
parameter | short form | description | regex | min / max | task or process |
---|---|---|---|---|---|
|
|
Process instance id |
X |
T,P | |
|
|
Process id |
X |
T,P | |
|
|
Work item id |
T,P | ||
|
|
Deployment id |
X |
T,P | |
|
|
Task id |
X |
T | |
|
|
Task initiator/creator |
X |
T | |
|
|
Task stakeholder |
X |
T | |
|
|
Task potential owner |
X |
T | |
|
|
Task owner |
X |
T | |
|
|
Task business admin |
X |
T | |
|
|
Task status |
T | ||
`processinstancestatus |
|
Process instance status |
T,P | ||
|
|
Process version |
X |
T,P | |
|
|
Process instance start date1 |
X |
T,P | |
|
|
Process instance end date1 |
X |
T,P | |
|
|
Variable id |
X |
T,P | |
|
|
Variable value |
X |
T,P | |
|
|
Variable id and value 2 |
T,P | ||
|
|
Variable id and value 3 |
X |
T,P | |
|
|
Which variable history logs 4 |
T,P |
[1] The date operations take strings with a specific date format as their values: yy-MM-dd_HH:mm:ss
.
However, users can also submit only part of the date:
yy-MM-dd
) means that a time of 00:00:00 is used (the beginning of the day).HH:mm:ss
) means that the current date is used.Table 17.12. Example date strings
Date str ing | Actual meaning |
---|---|
|
May 29th, 2015, 13:40:12 (1:40:12 PM) |
|
November 20th, 2014, 00:00:00 |
|
Today, 9:30:00 (AM) |
For the format used, see the SimpleDateFormat documentation.
[2] The var
query parameter is used differently than other parameters. If you want to specify
both the variable id and value of a variable (as opposed to just the variable id), then you can
do it by using the var
query parameter. The syntax is var_<variable-id>=<variable-value>
Example 17.7.
var_X=Y
example
The query parameter and parameter pair var_myVar=value3
queries for process instances with
variables4 that are called myVar
and that have the value value3
[3] The varreggex
(or shortened version vr
) parameter works similarly to the var
query
parameter. However, the value part of the query parameter can be a regular expression.
[4] By default, only the information from most recent (last) variable instance logs is retrieved. However, users can also retrieve all variable instance logs (that match the given criteria) by using this parameter.
Table 17.13. Query parameters examples
parameter | short form | example |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The process instance query returns a JaxbQueryProcessInstanceResult instance.
The task query returns a JaxbQueryTaskResult instance.
Results are structured as follows:
A JaxbQueryProcessInstanceInfo object contains:
A JaxbQueryTaskInfo info object contains:
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 via the JMS API exposed by the jBPM console and KIE workbench. However, it’s not possible to manage deployments or the knowledge base via 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 return in one response message.
When the Workbench is deployed on the JBoss AS or EAP server, it automatically creates 3 queues:
jms/queue/KIE.SESSION
jms/queue/KIE.TASK
jms/queue/KIE.RESPONSE
The KIE.SESSION
and KIE.TASK
queues should be 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
and
command request messages that involve managing human tasks, should be sent to the KIE.TASK
queue.
Although there are 2 different input queues, KIE.SESSION
and KIE.TASK
, this is only in order to
provide multiple input queues so as to optimize processing: command request messages will be
processed in the same manner regardless of which queue they’re sent to. However, in some cases,
users may send many 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 text message that contains a
serialized JaxbCommandsRequest
object. At the moment, only XML serialization (as opposed to, JSON
or protobuf, for example) is supported.
While it is possible to interact with a BPMS or KIE workbench server instance by sending and
processing JMS messages that you create yourself, it will always be easier to use the remote Java
API that’s supplied by the kie-services-client
jar.
For more information about how to use the remote Java API to interact with the JMS API of a server instance, see the <link linkend='remote.java.api.jms'>Remote Java API</link> section.
The JMS API accepts TextMessage
instances that contain serialized JaxbCommandsRequest
objects.
These JaxbCommandsRequest
instances can be filled with multiple command objects. In this way,
it’s possible to send a batch of commands for processing to the JMS API.
When users wish to include their own classes with requests, there a number of requirements that must be met for the user-defined classes. For more information about these requirements, see the Sending and receiving user class instances section in the remote API additional documentation section.
The following is a rather long example that shows how to use the JMS API. The numbers ("callouts") along the side of the example refer to notes below that explain particular parts of the example. It’s supplied for those advanced users that do not wish to use the jBPM Remote Java API.
The jBPM Remote Java API, described here, will otherwise take care of all of the logic shown below.
package org.kie.remote.client.documentation.jms;
import static org.kie.services.client.serialization.SerializationConstants.DEPLOYMENT_ID_PROPERTY_NAME;
import static org.kie.services.client.serialization.SerializationConstants.SERIALIZATION_TYPE_PROPERTY_NAME;
import static org.kie.services.shared.ServicesVersion.VERSION;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.kie.api.command.Command;
import org.kie.api.runtime.process.ProcessInstance;
import org.kie.api.task.model.TaskSummary;
import org.kie.remote.client.api.RemoteRuntimeEngineFactory;
import org.kie.remote.client.api.exception.MissingRequiredInfoException;
import org.kie.remote.client.api.exception.RemoteApiException;
import org.kie.remote.client.api.exception.RemoteCommunicationException;
import org.kie.remote.client.jaxb.ClientJaxbSerializationProvider;
import org.kie.remote.client.jaxb.JaxbCommandsRequest;
import org.kie.remote.client.jaxb.JaxbCommandsResponse;
import org.kie.remote.jaxb.gen.AuditCommand;
import org.kie.remote.jaxb.gen.GetTaskAssignedAsPotentialOwnerCommand;
import org.kie.remote.jaxb.gen.StartProcessCommand;
import org.kie.remote.jaxb.gen.TaskCommand;
import org.kie.services.client.serialization.JaxbSerializationProvider;
import org.kie.services.client.serialization.SerializationException;
import org.kie.services.client.serialization.SerializationProvider;
import org.kie.services.client.serialization.jaxb.impl.JaxbCommandResponse;
import org.kie.services.client.serialization.jaxb.rest.JaxbExceptionResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SendJmsExample {
protected static final Logger logger = LoggerFactory.getLogger(SendJmsExample.class);
public void sendCommandsViaJms( String user, String password, String connectionUser, String connectionPassword,
String deploymentId, String processId, String hostName ) {
/**
* JMS setup
*/
// Get JNDI context from server
InitialContext context = RemoteRuntimeEngineFactory.getRemoteJbossInitialContext(hostName, connectionUser, connectionPassword);
// 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);
}
// Setup queues
Queue sessionQueue, taskQueue, sendQueue, responseQueue;
try {
sendQueue = sessionQueue = (Queue) context.lookup("jms/queue/KIE.SESSION");
taskQueue = (Queue) context.lookup("jms/queue/KIE.TASK");
responseQueue = (Queue) context.lookup("jms/queue/KIE.RESPONSE");
} catch( NamingException ne ) {
throw new RuntimeException("Unable to lookup send or response queue", ne);
}
/**
* Command preparation
*/
StartProcessCommand startProcCmd = new StartProcessCommand();
startProcCmd.setProcessId(processId);
/**
* Send command via JMS and receive response
*/
SerializationProvider serializationProvider = ClientJaxbSerializationProvider.newInstance();
ProcessInstance procInst = (ProcessInstance) sendJmsCommand(startProcCmd,
connectionUser, connectionPassword,
user, password, deploymentId, null,
connectionFactory, sendQueue, responseQueue,
serializationProvider, Collections.EMPTY_SET, JaxbSerializationProvider.JMS_SERIALIZATION_TYPE,
5 * 1000);
/**
* Command preparation
*/
GetTaskAssignedAsPotentialOwnerCommand gtaapoCmd = new GetTaskAssignedAsPotentialOwnerCommand();
gtaapoCmd.setUserId(user);
// Send command request
Long processInstanceId = null; // needed if you're doing an operation on a PER_PROCESS_INSTANCE deployment
/**
* Send command via JMS and receive response
*/
@SuppressWarnings("unchecked")
List<TaskSummary> taskSumList = (List<TaskSummary>) sendJmsCommand(gtaapoCmd,
connectionUser, connectionPassword,
user, password, deploymentId, processInstanceId,
connectionFactory, sendQueue, responseQueue,
serializationProvider, Collections.EMPTY_SET, JaxbSerializationProvider.JMS_SERIALIZATION_TYPE,
5 * 1000);
long taskId = taskSumList.get(0).getId();
}
// @formatter:off
public static Object sendJmsCommand( Command command,
String connUser, String connPassword,
String userName, String password, String deploymentId, Long processInstanceId,
ConnectionFactory factory, Queue sendQueue, Queue responseQueue,
SerializationProvider serializationProvider, Set<Class<?>> extraJaxbClasses, int serializationType,
long timeoutInMillisecs ) {
// @formatter:on
if( deploymentId == null && !(command instanceof TaskCommand || command instanceof AuditCommand) ) {
throw new MissingRequiredInfoException("A deployment id is required when sending commands involving the KieSession.");
}
JaxbCommandsRequest req;
if( command instanceof AuditCommand ) {
req = new JaxbCommandsRequest(command);
} else {
req = new JaxbCommandsRequest(deploymentId, command);
}
req.setProcessInstanceId(processInstanceId);
req.setUser(userName);
req.setVersion(VERSION);
Connection connection = null;
Session session = null;
JaxbCommandsResponse cmdResponse = null;
String corrId = UUID.randomUUID().toString();
String selector = "JMSCorrelationID = '" + corrId + "'";
try {
// setup
MessageProducer producer;
MessageConsumer consumer;
try {
if( password != null ) {
connection = factory.createConnection(connUser, connPassword);
} 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);
}
// Create msg
TextMessage textMsg;
try {
// serialize request
String xmlStr = serializationProvider.serialize(req);
textMsg = session.createTextMessage(xmlStr);
// set properties
// 1. corr id
textMsg.setJMSCorrelationID(corrId);
// 2. serialization info
textMsg.setIntProperty(SERIALIZATION_TYPE_PROPERTY_NAME, serializationType);
if( extraJaxbClasses != null && !extraJaxbClasses.isEmpty() ) {
if( deploymentId == null ) {
throw new MissingRequiredInfoException(
"Deserialization of parameter classes requires a deployment id, which has not been configured.");
}
textMsg.setStringProperty(DEPLOYMENT_ID_PROPERTY_NAME, deploymentId);
}
// 3. user/pass for task operations
boolean isTaskCommand = (command instanceof TaskCommand);
if( isTaskCommand ) {
if( userName == null ) {
throw new RemoteCommunicationException(
"A user name is required when sending task operation requests via JMS");
}
if( password == null ) {
throw new RemoteCommunicationException(
"A password is required when sending task operation requests via JMS");
}
textMsg.setStringProperty("username", userName);
textMsg.setStringProperty("password", password);
}
// 4. process instance id
} 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(textMsg);
} catch( JMSException jmse ) {
throw new RemoteCommunicationException("Unable to send a JMS message.", jmse);
}
// receive
Message response;
try {
response = consumer.receive(timeoutInMillisecs);
} catch( JMSException jmse ) {
throw new RemoteCommunicationException("Unable to receive or retrieve the JMS response.", jmse);
}
if( response == null ) {
logger.warn("Response is empty");
return null;
}
// extract response
assert response != null: "Response is empty.";
try {
String xmlStr = ((TextMessage) response).getText();
cmdResponse = (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 cmdResponse != null: "Jaxb Cmd Response was null!";
} finally {
if( connection != null ) {
try {
connection.close();
if( session != null ) {
session.close();
}
} catch( JMSException jmse ) {
logger.warn("Unable to close connection or session!", jmse);
}
}
}
String version = cmdResponse.getVersion();
if( version == null ) {
version = "pre-6.0.3";
}
if( !version.equals(VERSION) ) {
logger.info("Response received from server version [{}] while client is version [{}]! This may cause problems.",
version, VERSION);
}
List<JaxbCommandResponse<?>> responses = cmdResponse.getResponses();
if( responses.size() > 0 ) {
JaxbCommandResponse<?> response = responses.get(0);
if( response instanceof JaxbExceptionResponse ) {
JaxbExceptionResponse exceptionResponse = (JaxbExceptionResponse) response;
throw new RemoteApiException(exceptionResponse.getMessage());
} else {
return response.getResult();
}
} else {
assert responses.size() == 0: "There should only be 1 response, not " + responses.size() + ", returned by a command!";
return null;
}
}
}
These classes can all be found in the | |
The | |
Note that the JMS message sent to the remote JMS API must be constructed as follows:
| |
The same serialization mechanism used to serialize the request message will be used to serialize the response message. |
Except for the Execute calls, all other REST calls described below can use either JAXB or JSON.
All REST calls, unless otherwise specified, use JAXB serialization.
When using JSON, make sure to add the JSON media type ("application/json"
) to the
ACCEPT
header of your REST call.
Sometimes, users may wish to pass instances of their own classes as parameters to commands sent in a REST or Webservice request or JMS message. In order to do this, there are a number of requirements.
The user-defined class satisfy the following in order to be property serialized and deserialized:
It should be possible to serialize and deserialize the user-defined class using JAXB. For simple custom classes, this might be available out-of-the-box, but for more complex types, this might mean the classes need to be correctly annotated with JAXB annotations, including the following:
javax.xml.bind.annotation.XmlRootElement
annotation with a non-empty name
valuejavax.xml.bind.annotation.XmlElement
or javax.xml.bind.annotation.XmlAttribute
annotations.Furthermore, the following usage of JAXB annotations is recommended:
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.@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.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.Long
or
String
) or otherwise be objects that satisfy the same requiremends in this list (correct
usage of JAXB annotations and a no-arg constructor).The sender must pass the deployment id in the header of the request. This property is necessary to able to load the proper classes from the deployment itself before deserializing the message on the server side.
deploymentId
string property on the JMS text message must be set.While submitting an instance of a user-defined class is possible via both the JMS and REST API, retrieving an instance of the process variable is only possible via the REST API.
When interacting with the Remote API, users may want to pass instances of their own classes as parameters to certain operations. As mThis will only be possible if the KJar for a deployment includes these classes.
REST calls that involve the TaskService
(e.g. that start with /task
..), often do not
contain any information about the associated deployment. In that case, an extra query parameter will have to be
added to the REST call so that the server can find the appropriate deployment with the class (definition) and
correctly deserialize the information passed with the call.
For these REST calls which do not contain the deployment id, you’ll need to add the following parameter:
Table 17.14. Deployment id query parameter
Parameter name | Description |
---|---|
deploymentId |
Value (must match the regex |
Some of the REST calls below return lists of information. The results of these operations can be paginated, which means that the lists can be split up and returned according to the parameters sent by the user.
For example, if the REST call parameters indicate that page 2 with page size 10 should be returned for the results, then results 10 to (and including) 19 will be returned.
The first page is always page 1 (as opposed to page "0").
Table 17.15. Pagination query parameter syntax
Parameter name | Description |
---|---|
page |
The page number requested. The default value is 1. |
p |
Synonym for the above |
pageSize |
The number of elements per page to return. The default value is 10. |
s |
Synonym for the above |
If both a "long" pagination parameter and its synonym are used, then only the value from the "long" variant is used. For
example, if the page
is given with a value of 11 and the p
parameter is given with a value of 37, then the value of the
page
parameter, 11 , will be used and the p
parameter will be ignored.
For the following operations, pagination is always used. See above for the default values used.
Table 17.16. REST operations using pagination
REST call URL | Short Description |
---|---|
|
Returns a list of |
|
Returns a list of |
|
Returns a list of |
|
Returns a list of |
|
Returns a list of |
|
Returns a list of |
|
Returns a list of |
|
Returns a list of |
|
Returns a list of |
|
Returns a list of |
|
Returns a list of |
|
Returns a list of |
|
Returns a list of |
|
Returns a |
|
Returns a |
If you’re triggering an operation with a REST API call that would normally (e.g. when interacting the same operation on a
local KieSession
or TaskService
instance) take an instance of a java.util.Map
as one of its parameters,
you can submit key-value pairs to the operation to simulate this behaviour by passing a query parameter whose name starts
with map_
.
Example 17.8. Query parameter examples
If you pass the query parameter map_kEy=vAlue
in a REST call, then the
Map
that’s passed to the actual underlying KieSession
or TaskService
operation will contain this (String, String
) key value pair: "kEy" ⇒ "vAlue"
.
You could pass this parameter like so:
http://localhost:8080/kie-wb/rest/runtime/myproject/process/wonka.factory.loompa.hire/start?map_kEy=vAlue
Map query parameters also use the object query parameter syntax described
below, so the following query parameter, map_total=5000
will be translated
into a key-value pair in a map where the key is the String "total" and the
value is a Long with the value of 5000. For example:
http://localhost:8080/kie-wb/rest/runtime/myproject/process/wonka.factory.oompa.chocolate/start?map_total=5000`
The following operations take query map parameters:
/runtime/{deploymentId}/process/{processDefId}/start
/runtime/{deploymentId}/workitem/{processItemId}/complete
/runtime/{deploymentId}/withvars/process/{processDefId}/start
/task/{taskId}/complete
/task/{taskId}/fail
While REST calls obviously only take strings as query parameters, using the following notation for query parameters will mean that the string is translated into a different type of object when the value of the string is used in the actual operation:
The remote API calls allow access to the underlying deployments, regardless of whether these
deployments use the Singleton
, Per-Process-Instance
or Per-Request
strategies.
While there’s enough information in the URL in order to access deployments that use the
Singleton
, or Per-Request
strategies, that’s not always the case with the
Per-Process-Instance
runtimes because the remote API operation will need the process instance id
in order to identify the deployment.
Therefore, for REST calls for which the URL does not contain the process instance id, you’ll need to add the following parameter:
Table 17.18. Per-Process-Instance runtime query parameter
Parameter name | Description |
---|---|
runtimeProcInstId |
Value (must match the regex |