Consuming business assets via REST
By: Karina Macedo Varela
Tags: How To, Jbpm, Rest, Process, Integration

As expected as default over any REST communication, when the integration via client and Kie Server is done via REST, there is no guarantee on the delivery or retry of this message.

The initialization of Kie Services Client requires an instance of org.kie.server.client.KieServicesConfiguration .

When using the REST approach, we should create the instance of KieServicesConfiguration with the method KieServicesFactory.newRestConfiguration .

To create a new Rest Configuration, it’s required to inform the auth data, URL where the Kie Server is located. Optionally it is possible to set the timeout in milliseconds for this connection attempt.

Recommendation about the URL: If the architecture contains only one Kie Server, point the client URL configuration to the Kie Server domain: “/kie-server/services/rest/server”. If the architecture contains multiple kie servers, you might need to add a kie smart router component. The kie smart router is especially useful in auto-scalable cloud environments when it is hard to maintain the clients’ code that interacts via dynamic addresses. In this case, the URL should point to the smart-router root URL.

TIP: When using smart-router, the kie server url path “kie-server/services/rest/server/” is omitted. In kie-server a new process can be created with a URL like: http://localhost:8080/kie-server/services/rest/server/containers/{containerId}/processes/{processId}/instances. In smart router, the same action is available via: http://localhost:9000/containers/{containerId}/processes/{processId}/instances.

The default timeout is 5000ms, and the default Marshaling Format is JAXB (XML). Consider we have an up and running instance of Kie Server on a WildFly serving on localhost:8080, where we are connecting with user “kieserver”, password “kieserver1!” and setting a timeout of 6 seconds. The Kie Client Configuration could be created like:

private static final String KIESERVER_URL = "http://localhost:8080/kie-server/services/rest/server";

private static final String KIESERVER_USER = "kieserver";

private static final String KIESERVER_PASSWORD = "kieserver1!";

private static final long KIESERVER_CONNECTION_TIMEOUT = 6000l;

private static final MarshallingFormat KIESERVER_MARSHALLING = MarshallingFormat.JSON;

final KieServicesConfiguration connectionConfig = KieServicesFactory.newRestConfiguration( KIESERVER_URL, KIESERVER_USER, KIESERVER_PASSWORD, KIESERVER_CONNECTION_TIMEOUT);

connectionConfig.setMarshallingFormat(KIESERVER_MARSHALLING);

When using a client application, developers generally use custom domain objects to interact with business processes, tasks, or rules. For example, if starting a medical attendance, probably, the patient information is an input for this process. All these information are modeled into data objects. Kie Server has the capability to automatically marshal and unmarshal objects that are sent and retrieved by it. This being said, if you are starting a process using a client application, you could just say “Kie Server, start a new process with this instance of Patient object”. When properly configured, the client automatically creates a rest request where these parameters are sent using a format (the Marshalling Format), in this case, a JSON format.

When the request reaches Kie Server, it is able to parse this object and associate it to the respective process variable. But when we are using objects other than the basic ones (String, Boolean, Long, Integer, Object, …), we need to inform to the Configuration, which are these custom classes we are transmitting via requests.

The following example, adds a “Patient” custom data object class to the Kie Configuration so that Kie Server knows how to marshall and unmarshall it. The extra classes configuration looks like below, where :

Set<Class<?>> customClassesList = new HashSet<Class<?>>(); customClassesList.add(Patient.class); connectionConfig.addExtraClasses(extraClassList);

TIP: Currently, the Marshalling Format options are XTREAM, XML and JSON. Check more details on org.kie.server.api.marshalling.MarshallingFormat class.

Once configured, the developer is now ready to create an instance of the client and consume the assets. Let’s check this step by step on practice.

Integrating a Quarkus Application with Kie Server

In order to create a client application to consume a business project deployed in a Kie Container, inside Kie Server, let’s use Quarkus.

Creating the Quarkus Project — the client app

$ mkdir -p ~/projects/labs

2. Inside $HOME/projects/labs/ , create a new Quarkus project using the maven archetype below. A pre-configured project will be created with the REST class pointed in the command below.

$ mvn io.quarkus:quarkus-maven-plugin:1.5.2.Final:create -DprojectGroupId=org.kvarela -DprojectArtifactId=kie-client-lab -DclassName="org.kvarela.rest.client.HelloKieServerResource" -Dpath="/hello-kieserver" -Dextensions="resteasy-jsonb" $ cd kie-client-lab/

3. Run it using mvn compile quarkus:dev -Dquarkus.http.port=8081 . In the first time, Maven will download the required libraries and start the application in sequence

3. Open Eclipse or any other preferred IDE, and import this maven project. You have a new Java application with rest capabilities ready to go. If you want to confirm, point your browser to http:/​/​localhost:8081/​hello-​kieserver and check the output “hello” printed.

Now let’s configure this project, enabling it to consume business assets from jBPM engine, Kie Server.

The Kie Service — Configuring Kie Client API and testing the client application

To configure the KIE client API and use it, you can follow the step-by-step below. If you want to check the complete application you can check it here: https://github.com/kmacedovarela/kie-client-lab

<dependency>

<groupId>org.kie.server</groupId>

<artifactId>kie-server-client</artifactId>

<version>${jbpm.version}</version>

</dependency>

IMPORTANT: In versions prior to 7.39.0.Final, there is a conflict in between imported Jackson libraries (details in JBPM-8937 ). Due to that, a little trick is necessary to exclude jackson dependencies from kie-server-client, and import the proper libraries versions.

2. Now, add a class that is responsible for connecting the client application to the Kie Server, during the application startup. Name it KieClientInitializer (or any another preferred name);

public class KieClientInitializer implements java.io.Serializable {

3. Annotate it with @javax.enterprise.context.ApplicationScoped , and add a new method onStart . Let's also add some logging to test our app. This method will be invoked during the application start up. It should look like this:

@ApplicationScoped

public class KieClientInitializer implements java.io.Serializable { private static final Logger LOGGER = LoggerFactory.getLogger("KieClientInitializer");

void onStart(@Observes StartupEvent ev) {

// LOGGER.info("The application is starting...");

}

}

4. Validate your configuration by restarting quarkus, and checking if your logs are outputted. Something similar to the bold logs below.

2020-06-28 21:16:54,879 INFO [KieClientInitializer] (Quarkus Main Thread) The application is starting... 2020-06-28 21:16:54,990 INFO [io.quarkus] (Quarkus Main Thread) kie-client-lab 1.0-SNAPSHOT on JVM (powered by Quarkus 1.5.2.Final) started in 1.185s. Listening on: 2020-06-28 21:16:54,990 INFO [io.quarkus] (Quarkus Main Thread) kie-client-lab 1.0-SNAPSHOT on JVM (powered by Quarkus 1.5.2.Final) started in 1.185s. Listening on: http://0.0.0.0:8081 2020-06-28 21:16:54,993 INFO [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated. 2020-06-28 21:16:54,993 INFO [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, resteasy, resteasy-jsonb]

INFO: Java EE EJB provides the annotation @javax.ejb.Startup to create a startup service. In a Quarkus application, we are going to use start event to initialize our connection. More information can be found at: https:/​/​quarkus.​io/​guides/​application-​lifecycle-​events-​guide

5. Following the variable examples presented in the previous explanations, create the REST connection settings, and initialize your REST connection.

5.1. Add the KieServicesClient variable. We will use this client to list all the deployed kie containers. There is a client for each need as mentioned in this post, like, interacting with processes, rules, etc...

private static KieServicesClient kieServicesClient;

5.2. Declare the class variables containing the connection settings:

private static final String KIESERVER_URL = "http://localhost:8080/kie-server/services/rest/server";

private static final String KIESERVER_USER = "kieserver";

private static final String KIESERVER_PASSWORD = "kieserver1!";

private static final MarshallingFormat KIESERVER_MARSHALLING = MarshallingFormat.JSON;

private static final long KIESERVER_CONNECTION_TIMEOUT = 6000l;

5.3. Add a method that builds the Kie Services Client based on the rest configuration:

private void buildKieServicesClient(){

final KieServicesConfiguration connectionConfig = KieServicesFactory.newRestConfiguration( KIESERVER_URL, KIESERVER_USER, KIESERVER_PASSWORD, KIESERVER_CONNECTION_TIMEOUT);

connectionConfig.setMarshallingFormat(KIESERVER_MARSHALLING);

// addExtraClasses(connectionConfig);

setKieServicesClient(KieServicesFactory.newKieServicesClient(connectionConfig));

}

5.4. Invoke this method on the onStart method:

void onStart(@Observes StartupEvent ev) {

LOGGER.info("The application is starting...");

buildKieClient();

}

6. Open the terminal and restart your quarkus application, so that it invokes this method during the initialization.

TIP: Since this is an example, you can use the user kieserver and password kieserver1! . In a real-world project, use a new user for the service. Also, make sure you have your jBPM instance up and running in another terminal tab. Our jBPM is running on localhost:8080. Our client service is running on 8081.

7. In your endpoint named HelloKieServerResource , inside the method hello , delete the return "hello"; code. Let's add some code that can list the existing KIE containers:

public String hello() { ServiceResponse<KieContainerResourceList> kieContainers = KieClientInitializer.getKieServicesClient().listContainers();

StringBuffer containersString = new StringBuffer();

containersString.append("Existing containers:

");

for (KieContainerResource kieContainer : kieContainers.getResult().getContainers()) {

containersString.append("

" + kieContainer.toString());

}

return containersString.toString();

}

8. Save your files.

INFO: If you try to start your client and jBPM is not up and running on the socket you configured, you’ll get this error: Caused by: org.kie.server.common.rest.NoEndpointFoundException: No available endpoints found .

That’s it! You have a java client application ready to consume whatever business assets deployed on your Kie Containers. Open your browser, point to http:/​/​localhost:8081/ hello-​kieserver and you will see a list of all the Kie Containers from the Kie Server. Validate your deployed projects and try to write an endpoint which starts a process and interacts with business tasks. This will make you feel familiar with the API which is intuitive and easy to use.

Last two important tips:

This blog post is part of the sixth section of the jBPM Getting started series:

Consuming Business Assets