{{announcement.body}}
{{announcement.title}}

Advanced Process Integration Tips - Quarkus Applications

DZone 's Guide to

Advanced Process Integration Tips - Quarkus Applications

The common way to integrate with your process engine is through the use of the Kie Server REST API. In this article we'll explore how...

· Integration Zone ·
Free Resource

Using advanced process integration techniques becomes essential as you evolve your developer skills while integrating more and more of your business workflows. The common way to integrate with your process engine is through the use of the Kie Server REST API. In this article we'll explore how to use it and provide an example of integration with a Quarkus application.

Integrating a client through the Kie Server using REST is no guarantee for delivery or retry of the sent messages. 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.

A 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 client's 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). Considering that we've got a 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.

Using a Quarkus Application

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

  1. Create the folder below or choose a folder where we will create a new project.
$ 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 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

  1. In pom.xml, add the maven dependency for the kie-server-client according to your jBPM version. In this example, jbpm.version is a property configured with value 7.38.0.Final.
<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: 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: \n");

    for (KieContainerResource kieContainer : kieContainers.getResult().getContainers()) {
        containersString.append("\n " + kieContainer.toString());
    }

    return containersString.toString();
}

8. Save your files.


INFO: If you try to start your client and the Kie Server is not running, you'll get this error: Caused by: org.kie.server.common.rest.NoEndpointFoundException: 

No available endpoints found.


That's it! 

You've got 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.

End notes:

Topics:
integration, jboss, jbpm, process, process automation, process integration, quarkus, red hat, redhat, tutorial

Published at DZone with permission of Karina Varela . See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}