How to use a REST WorkItem Handler in jBPM

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