In jBPM, a Work Item Handler is a Java class that implements the org.kie.runtime.instance.WorkItemHandler interface and can be used to execute some tasks during a Process. jBPM provides some built-in WorkItemHandlers. In this tutorial we will learn how to use one of the most common ones, the REST WorkItem Handler.
We will use as starting point the Driver License process that we already discussed in this tutorial: Developing a jBPM 7 Web application example
In addition to our initial process, we will add a bit of complexity by including a REST Task which will send a POST callback to our Web application:
Within our REST Task, we have set some Input/Output parameters which are allowed in the REST Workitem Handler:
As you can see, our REST WorkItemHandler will send a POST Request to this Url: “http://localhost:8090/callback“. The content will be using json and will authenticate with the credentials “wbadmin/wbadmin”. As ContentData, we will pass the process variable “name”.
Coding our Web application
In addition to our initial example of Web application, we will add the callback endpoint that will print the “name” variable that has been initially added to the Process list of variables:
@SpringBootApplication @RestController public class Application { @Autowired private ProcessService processService; @Autowired private RuntimeDataService runtimeDataService; @Autowired private UserTaskService userTaskService; public static void main(String[] args) { SpringApplication.run(Application.class, args); } @GetMapping("/hello") public ResponseEntity<String> sayHello(@RequestParam Integer age) throws Exception { // Provided as an example. Not actually needed by our process. Map<String, Object> vars = new HashMap<>(); vars.put("name", "John Smith"); Long processInstanceId = processService.startProcess("business-application-kjar-1_0-SNAPSHOT", "com.mastertheboss.LicenseDemo", vars); Map<String, Object> params = new HashMap<String, Object>(); params.put("age", age); List<TaskSummary> taskSummaries = runtimeDataService.getTasksAssignedAsPotentialOwner("john", new QueryFilter()); taskSummaries.forEach(s->{ Status status = taskSummaries.get(0).getStatus(); if ( status == Status.Ready ) userTaskService.claim(s.getId(), "john"); userTaskService.start(s.getId(), "john"); userTaskService.complete(s.getId(), "john", params); }); return ResponseEntity.status(HttpStatus.CREATED).body("Task completed!"); } @PostMapping("/callback") public ResponseEntity<Void> datamodelCallback(Principal principal, @RequestBody String name) throws Exception { System.out.println("Hey : "+ principal); System.out.println("There is a license request from " + name); return ResponseEntity.ok().build(); } }
In addition, within the KJAR Project, we will declare the RESTWorkItemHandler in the file kie-deployment-descriptor.xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <deployment-descriptor xsi:schemaLocation="http://www.jboss.org/jbpm deployment-descriptor.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <persistence-uni t>org.jbpm.domain</persistence-unit> <audit-persistence-unit>org.jbpm.domain</audit-persistence-unit> <audit-mode>JPA</audit-mode> <persistence-mode>JPA</persistence-mode> <runtime-strategy>PER_PROCESS_INSTANCE</runtime-strategy> <marshalling-strategies/> <event-listeners/> <task-event-listeners/> <globals/> <work-item-handlers> <work-item-handler> <resolver>mvel</resolver> <identifier>new org.jbpm.process.workitem.rest.RESTWorkItemHandler("john", "john")</identifier> <parameters/> <name>Rest</name> </work-item-handler> </work-item-handlers> <environment-entries/> <configurations/> <required-roles/> <remoteable-classes/> <limit-serialization-classes>true</limit-serialization-classes> </deployment-descriptor>
Depoying and running the example RESTWorkItemHandler
The source code for this example is availabe here: https://github.com/fmarchioni/mastertheboss/tree/master/jbpm/rest-wih
Start by installing on your local Maven repository the kjar project
$ cd business-application-kjar $ mvn clean install
Then build, install and run the Spring Boot application service:
$ cd business-application-service $ mvn clean install spring-boot:run
The application will start. You can now trigger the REST endpoint with a value for “age”, as required by the process:
$ curl http://localhost:8090/hello?age=14
You will see from your application logs that the process has started, the REST endpoint has been invoked and the Task has been completed:
Welcome to license check 2 Hey : org.springframework.security.authentication.UsernamePasswordAuthenticationToken@7d173f98: Principal: org.springframework.security.core.userdetails.User@43c67b64: Username: wbadmin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_admin; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Granted Authorities: ROLE_admin There is a license request from John Smith Enter you age John Smith Thanks Rejected
Congratulations, you have just learned how to create and deploy your first RESTWorkItemHandler.
If you want to learn how to create a Custom WorkItemHandler, check this tutorial: How to create a custom WorkItem Handler in jBPM