-
create a plain Maven project
-
add dependencies
<dependency> <groupId>org.kie</groupId> <artifactId>kie-api</artifactId> <scope>provided</scope> </dependency>
-
implement a class that extend
org.kie.api.runtime.process.WorkItemHandler
In the kjar:
-
define it in the wid file (just for the editor sake)
[ "name" : "YourWIH", "displayName" : "YourWIH", "category" : "your wih", "description" : "", "icon" : "defaultservicenodeicon.png", "parameters" : [ "Param1" : new StringDataType(), "Param2" : new StringDataType() ], "results" : [ "Result" : new StringDataType() ] ]
-
add the dependency in pom.xml
-
define it in the kie-deployment-descriptor :
<work-item-handlers> <work-item-handler> <resolver>mvel</resolver> <identifier>new com.sample.YourWIH(ksession)</identifier> <parameters/> <name>YourWIH</name> </work-item-handler> </work-item-handlers>
-
workitem handlers can be initialized with the following parameters:
- ksession
- taskService
- runtimeManager
- classLoader
- entityManagerFactory
- kieContainer
Source: KModuleRegisterableItemsFactory
-
In a SpringBoot context it's possible to delegate the WIH registration to the framework:
-
Use a Spring bean identifier:
<work-item-handler> <resolver>spring</resolver> <identifier>beanIdentifier</identifier> <parameters/> <name>MyWorkItem</name> </work-item-handler>
-
Annotate the WIH class:
@Component("MyWorkItem") public class MyWorkItemWorkItemHandler extends AbstractLogOrThrowWorkItemHandler {
-
Further info: registering custom tasks
If you add the WIH in WorkDefinition.wid
the icon should be included in the global
folder of the project.
Otherwise, if you create another wid file you can add the icon everywhere in the resources folder.
- Service implementation: Java or Webservices (to avoid webservices, because there are more options with "Web Service" WIH)
- Service interface: fully qualified Java class name
- Service operation: name of the method (static method)
- Assignments:
- input must be
Parameter
- output must be
Result
- input must be
Example of method implementation:
public static Object call(Object param) throws Exception {
return param;
}
- Edit data I/O (assignments)
- Add the following data input and assignments:
NAME | DATA TYPE | SOURCE |
---|---|---|
Parameter | String | info |
ParameterType | String | java.lang.String |
- Add the following data output and assignments:
NAME | DATA TYPE | SOURCE |
---|---|---|
Result | String | info |
Internal implementation: https://github.com/kiegroup/jbpm/blob/master/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/handler/ServiceTaskHandler.java
<work-item-handlers>
<work-item-handler>
<resolver>mvel</resolver>
<identifier>new org.jbpm.process.instance.impl.demo.SystemOutWorkItemHandler()</identifier>
<parameters/>
<name>Log</name>
</work-item-handler>
<work-item-handler>
<resolver>mvel</resolver>
<identifier>new org.jbpm.process.workitem.bpmn2.ServiceTaskHandler(ksession, classLoader)</identifier>
<parameters/>
<name>Service Task</name>
</work-item-handler>
<work-item-handler>
<resolver>mvel</resolver>
<identifier>new org.jbpm.process.workitem.webservice.WebServiceWorkItemHandler(ksession, classLoader)</identifier>
<parameters/>
<name>WebService</name>
</work-item-handler>
<work-item-handler>
<resolver>mvel</resolver>
<identifier>new org.jbpm.process.workitem.rest.RESTWorkItemHandler(classLoader)</identifier>
<parameters/>
<name>Rest</name>
</work-item-handler>
</work-item-handlers>
Enable your project to use the REST work item handler (aka Service Task):
-
Open the project Settings > Service Tasks
-
Click Install button for the
Rest
service task -
Insert username and password for the rest basic authentication. You can override those value for a specific call
-
Save the configuration
Optionally, check the configuration details in Settings > Deployment > Work item handlers
The value for Rest should be:
new org.jbpm.process.workitem.rest.RESTWorkItemHandler("username", "password")
-
Add the dependency
<dependency> <groupId>org.jbpm</groupId> <artifactId>jbpm-workitems-rest</artifactId> <version>${version.org.kie}</version> <scope>provided</scope> </dependency>
-
Open or create a new Business Process
-
From the palette select the Service Tasks drawer (the gears icon)
-
Drag and drop the the REST task on the process diagram
-
Select the Rest task
-
From the Properties panel select Assignments to configure the Rest task behaviour:
Data Input:
- Url - resource location to be invoked - mandatory
- Method - HTTP method that will be executed - defaults to GET
- ContentType - data type in case of sending data - mandatory for POST, PUT
- ContentData - actual data to be sent - mandatory for POST,PUT
- ConnectTimeout - connection time out - default to 60 seconds
- ReadTimeout - read time out - default to 60 seconds
- Username - user name for authentication - overrides one given on handler initialization)
- Password - password for authentication - overrides one given on handler initialization)
- AuthUrl - url that is handling authentication (usually j_security_check url)
- HandleResponseErrors - optional parameter that instructs handler to throw errors in case of non successful response codes (other than 2XX)
- ResultClass - fully qualified class name of the class that response should be transformed to, if not given string format will be returned
Data Output:
- Result: the target DTO (a.k.a. Data Transfer Object: a Java Object that will be used to map the data send from and by the rest service)
If you want disregard some json properties, add the following annotation to the Java DTO:
@org.codehaus.jackson.annotate.JsonIgnoreProperties(ignoreUnknown = true)
This will say to the JSON mapper engine to ignore the JSON properties that are not present in the DTO, otherwise you'll get an exception. Indirectly import all json libraries:
<dependency>
<groupId>org.kie.server</groupId>
<artifactId>kie-server-api</artifactId>
<scope>provided</scope>
</dependency>
Define the property name:
@JsonProperty("caller-id")
Usually, REST service should declare how they serialize the data through the Header property Content-Type
that in most case will assume the following values:
application/json
application/xml
Some REST services return a more complex Content-Type to add more details.
E.g. Content-Type: application/json;charset=utf-8
Unfortunately, the standard REST Workitem handler (WIH) is not able to handle this situation. Here you will found a modified version of the WIH that address the problem.
How do I use the REST Service Task for SSL enabled REST service in BPM Suite 6?
create a maven project
copy the WSDL in the resources
folder
create in the project root the jaxb-bindings.xml
with the following content:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
elementFormDefault="qualified" attributeFormDefault="unqualified"
jaxb:extensionBindingPrefixes="xjc" jaxb:version="1.0">
<xs:annotation>
<xs:appinfo>
<jaxb:globalBindings>
<xjc:serializable />
</jaxb:globalBindings>
</xs:appinfo>
</xs:annotation>
</xs:schema>
launch wsconsume.sh
$ <EAP_HOME>/bin/wsconsume.sh -b jaxb-bindings.xml -k -n -s src/main/java/ src/main/resources/POCJBSS.WSDL
$ rm -rf output
- URL = http url for WSDL
- endpoint =
location
ofsoap:address
- mode =
SYNC
- interface =
name
ofportType
- operation =
name
ofoperation
- namespace =
targetNamespace
Some webservices uses bare type (not wrapped), so in order to match the service signature you have to transform the wrapper class in an object's array.
requestArray = new Object[] {
request.getField1(),
request.getField2(),
request.getField3()
};
Workaround?
https://issues.redhat.com/browse/JBPM-9291
Configuration
new org.jbpm.process.workitem.kafka.KafkaWorkItemHandler("bootstrapServers", "clientId", "keySerializerClass", "valueSerializerClass")
Input parameters
- Topic (String)
- Key (Object)
- Value (Object)
Output parameters
- Result = "success" (always)
As part of the integration story with AMQ streams one of the capabilities should be to have a kie-server extension that could listen to a Kafka topic and act upon the events received, using Start or Intermediate Catch Events (Signals/Messages).
Kie server extension:
https://issues.redhat.com/browse/JBPM-9436
https://issues.redhat.com/browse/BAPL-1763
The user would like to receive events with the information of a process instance execution, some example for this events could be completed task, completed process, started task, etc. The engine should have a configurable listener that could emit those events when the actions occur connecting to an external AMQ Streams topic
https://issues.redhat.com/browse/BAPL-1646
Test emails:
Configure at project level the WorkitemHandler:
-
Open Project Editor > Deployment Descriptor
new org.jbpm.process.workitem.email.EmailWorkItemHandler("localhost", "8086","me@localhost","password")
Detailed information in: Human Tasks
https://access.redhat.com/solutions/396853#eap6client
https://github.com/selrahal/jbpm-rest
- COMPLETE - it completes the service task with the variables from the completed subprocess instance - these variables will be given to the service task as output of the service interaction and thus mapped to main process instance variables
- ABORT - it aborts the service task and moves on the process without setting any variables
- RETRY - it retries the service task logic (calls the work item handler again) with variables from both the original service task parameters and the variables from subprocess instance - variables from subprocess instance overrides any variables of the same name
- RETHROW - it simply throws the error back to the caller - this strategy should not be used with wait state subprocesses as it will simply rollback the transaction and thus the completion of the subprocess instance
Exception Handling Strategy Usage Example
See: http://mswiderski.blogspot.com/2018/10/handle-service-exceptions-via-subprocess.html
The most effective way to store the runtime events is to leverage the event emitters.
NoSQL enters jBPM ... as an experiment ... so far Elasticsearch empowers jBPM