Scope of this post
The aim is to demonstrate how simple it is to deploy a cloud native application in microservice architecture on OpenShift built with processes and rules using the Kogito and Quarkus frameworks.
To maintain the open source spirit in this post and demonstrate that IBM has always been involved in OSS initiatives and that the recent take-over of Red Hat PAM and DM software will continue to be fully supported and continuously improved, it will be demonstrated how to deploy the same application both in Kie server image-based container with KieGroup source (OSS community support) and in IBM Process Automation Manager Open Editions (vendor support) image-based container.
Prerequisites
A linux box
The tools Quarkus, Kogito, Maven, Java JDK 11, VSCode or your preferred IDE, jq
An OpenShift environment, even a simple OpenShift Dev Spaces (formerly Red Hat CodeReady)
A Red Hat Developer account (free)
Contents
The first section describes the demo application, the development environment, the project configuration for Quarkus extensions, the local build and test operations to your laptop.
The second section describes two build and deployment scenarios in OpenShift environment, for the build operations we will use the 'source' mode with the S2I builder.
The first scenario uses the KieGroup image (kogito-s2i-builder), the second scenario uses the IBM image (bamoe-kogito-builder-rhel8).
First section, the application
Description of the demo application that will be used
The application used is available on my github site at the link https://github.com/marcoantonioni/my-process-quarkus-example
It is a simple application consisting of a single process, a business rule, a human task and a service implemented in Java; it has a flow navigation logic which is determined by the combination of the values of the input variables at the start of the process; for example the human task is activated only if the value of a boolean variable is set to 'true' (long running process) otherwise the process navigates directly towards the end (straight through process).
Description of the development environment used to build the application
For the development of the application I used a Red Hat 8.x linux box (easily downloadable from the Red Hat site with account developer), the tools Quarkus, Kogito, Maven, Java JDK 11 and VSCode.
For the installation and configuration of the various tools see the References section of this post.
The application was developed and tested on my laptop.
In the final part of the post the operation of the S2I build of a new runtime image is described in detail when updates are made to the sources on git, if you also want to perform this step you will have to fork the application on your git site before running the deployment in the OpenShift environment.
Application creation and configuration
Note: To use your work environment and subsequently modify the sources, fork the application from the GitHub website to your account and then execute the clone on your laptop.
For the creation of the application I used Quarkus with the following command
MY_PKG=marco.test.app
MY_APP_NAME=my-process-quarkus-example
quarkus create app ${MY_PKG}:${MY_APP_NAME} --extension=kogito,resteasy-reactive-jackson,openshift --no-code
cd ${MY_APP_NAME}
in the creation command I defined the various extensions necessary to use Kogito, OpenShift and the REST API to interact remotely with process instances.
Then I created the 'my-process-quarkus-example' application on GitHub (https://github.com/marcoantonioni/my-process-quarkus-example)
and then initialized and configured my workspace with the following commands executed within the application root folder (eg: ~ / quarkus / apps / my-process-quarkus-example):
git init
git remote add origin https://github.com/marcoantonioni/my-process-quarkus-example.git
git add .
git commit -m "first release"
git push -u origin master
Development, build and test in a local desktop environment
For local build and testing on my laptop I used the following commands
quarkus build -Dquarkus.package.type=uber-jar
java -jar ./target/my-process-quarkus-example-1.0.0-SNAPSHOT-runner.jar
For testing locally from a different shell I used the following commands
Setting environment variables
URL=http://localhost:8080
Starting a new instance (scenario with Human Task, variable showResult = true)
Let's create two instances with different key
curl -w"\n" -sX POST ${URL}/MyRequest -H 'content-type: application/json' -H 'accept: application/json' -d '{"requestData": {"key":"1", "useRules": true, "showResult": true}}' | jq .
curl -w"\n" -sX POST ${URL}/MyRequest -H 'content-type: application/json' -H 'accept: application/json' -d '{"requestData": {"key":"2", "useRules": true, "showResult": true}}' | jq .
Starting a new instance (scenario without Human Task, variable showResult = false, the process instance completes immediately)
curl -w"\n" -sX POST ${URL}/MyRequest -H 'content-type: application/json' -H 'accept: application/json' -d '{"requestData": {"key":"1", "useRules": true, "showResult": false}}' | jq .
Request list of active processes, only process id
curl -sX GET ${URL}/MyRequest -H 'accept: application/json' | jq .[].id | sed 's/\"//g'
Request list of active processes and their details
curl -w"\n" -sX GET ${URL}/MyRequest -H 'accept: application/json' | jq .
Request details of a process instance
PROCESS_ID=<set-your-process-id-here>
curl -sX GET ${URL}/MyRequest/${PROCESS_ID} -H 'accept: application/json' | jq .
Request the list of Human Tasks of a process instance
PROCESS_ID=<set-your-process-id-here>
curl -sX GET ${URL}/MyRequest/${PROCESS_ID}/tasks -H 'accept: application/json' | jq .
Request the details of a Human Task of a process instance
PROCESS_ID=<set-your-process-id-here>
TASK_NAME=ShowResult
TASK_ID=<set-your-task-id-here>
curl -sX GET ${URL}/MyRequest/${PROCESS_ID}/${TASK_NAME}/${TASK_ID} -H 'accept: application/json' | jq .
Completion of a Human Task (ShowResult is the name of the task in BPMN model)
PROCESS_ID=<set-your-process-id-here>
TASK_NAME=ShowResult
TASK_ID=<set-your-task-id-here>
curl -sX POST ${URL}/MyRequest/${PROCESS_ID}/${TASK_NAME}/${TASK_ID} -H 'content-type: application/json' -H 'accept: application/json' -d '{}' | jq .
Now that we've finished testing locally, let's commit to git with commands
git add .
git commit -m "version 1.0"
git push -u origin master
Second section, build and deployment on OpenShift
In this second section we will create two namespaces within the OpenShift cluster within which we will deploy the same application but using two different build and runtime images, the first in KieGroup full OSS mode, the second always OSS but with paid support by IBM.
Each scenario consists of 6 successive steps with minimal differences regarding the installation of the ImageStreams (KieGroup in the first scenario and IBM in the second scenario) and for the name of the docker image used as S2I builder and base runtime (KieGroup in the first scenario and IBM in the second scenario).
Deployment scenario with KieGroup container images
# --------------------------------
# STEP: 1
# --------------------------------
# create project
PRJ_SUFFIX=1
K_I_PRJ=my-process-quarkus-example-kie-images${PRJ_SUFFIX}
oc new-project ${K_I_PRJ}
oc project ${K_I_PRJ}
# --------------------------------
# STEP: 2
# --------------------------------
# use KieGroup OSS images
# create ImageStream from kogito site (pay attention to the replacement of the '2.0.0-snapshot' tag, at the time of writing this post was the latest version available)
# Before running the following command check the current tag in https://raw.githubusercontent.com/kiegroup/kogito-images/main/kogito-imagestream.yaml
curl -s https://raw.githubusercontent.com/kiegroup/kogito-images/main/kogito-imagestream.yaml | sed 's/2.0.0-snapshot/latest/g' | oc apply -f -
oc get is -n ${K_I_PRJ}
# --------------------------------
# STEP: 3
# --------------------------------
# prepare variable names
# builder name
BUILDER_NAME=kogito-s2i-builder
# read IS tag
TAG=$(oc get -n ${K_I_PRJ} is | grep -v NAME | head -n 1 | awk '{print $3}')
BUILD_CFG_NAME=my-process-quarkus-example
APP_NAME=my-process-quarkus-example
# PAY ATTENTION: change the value with your git site if you want to make changes to the sources
SRC_URL=https://github.com/marcoantonioni/my-process-quarkus-example
# --------------------------------
# STEP: 4
# --------------------------------
# build build config
# create BuildConfig
oc new-build -n ${K_I_PRJ} --name=${BUILD_CFG_NAME} --image-stream=${BUILDER_NAME}:${TAG} ${SRC_URL}
oc get bc -n ${K_I_PRJ}
sleep 30
oc logs -f $(oc get pods --sort-by='.metadata.name' | tac | grep -v NAME | grep ${APP_NAME} | grep build | grep Running | awk '{print $1}')
# --------------------------------
# STEP: 5
# --------------------------------
# create application and then route
oc new-app -n ${K_I_PRJ} ${BUILD_CFG_NAME} --name=${APP_NAME} --allow-missing-imagestream-tags
SHORT_NAME=shortname
oc expose service ${APP_NAME} --name ${SHORT_NAME}
oc get routes | grep ${APP_NAME}
URL=$(oc get route ${SHORT_NAME} | grep -v NAME | awk '{print "http://"$2}')
echo ${URL}
# pod log, filter pods looking for last created, exclude build pods
# wait for pod to get to Running state
sleep 20
oc logs -f $(oc get pods --sort-by='.metadata.name' | tac | grep -v NAME | grep -v "\-build" | grep ${APP_NAME} | grep Running | awk '{print $1}')
# --------------------------------
# STEP: 6
# --------------------------------
# test application
curl -w"\n" -sX POST ${URL}/MyRequest -H 'content-type: application/json' -H 'accept: application/json' -d '{"requestData": {"key":"1", "useRules": true, "showResult": true}}' | jq .
curl -w"\n" -sX GET ${URL}/MyRequest -H 'accept: application/json' | jq .
You can also reuse the other 'curl' commands already seen when running tests locally on your laptop.
Deployment scenario with IBM BAM OE container images
# --------------------------------
# STEP: 1
# --------------------------------
# create project
PRJ_SUFFIX=1
K_I_PRJ=my-ibamoe-images${PRJ_SUFFIX}
oc new-project ${K_I_PRJ}
oc project ${K_I_PRJ}
# --------------------------------
# STEP: 2
# --------------------------------
# use IBM images
# create secret for image registry access
REGISTRY_URL=registry.redhat.io
REGISTRY_USER=<your-redhat-user-id>
REGISTRY_PWD=<your-redhat-password>
oc create -n ${K_I_PRJ} secret docker-registry my-pull-secret --docker-server=${REGISTRY_URL} --docker-username=${REGISTRY_USER} --docker-password=${REGISTRY_PWD}
oc secrets link default my-pull-secret --for=pull
oc secrets link builder my-pull-secret --for=pull
# import image builder
oc import-image -n ${K_I_PRJ} ibm-bamoe/bamoe-kogito-builder-rhel8:8.0.0-4 --from=registry.redhat.io/ibm-bamoe/bamoe-kogito-builder-rhel8:8.0.0-4 --confirm
# --------------------------------
# STEP: 3
# --------------------------------
BUILDER_NAME=bamoe-kogito-builder-rhel8
# read IS tag
TAG=$(oc get -n ${K_I_PRJ} is | grep -v NAME | head -n 1 | awk '{print $3}')
BUILD_CFG_NAME=my-process-quarkus-example
APP_NAME=my-process-quarkus-example
# PAY ATTENTION: change the value with your git site if you want to make changes to the sources
SRC_URL=https://github.com/marcoantonioni/my-process-quarkus-example
# --------------------------------
# STEP: 4
# --------------------------------
# build build config
# create BuildConfig
oc new-build -n ${K_I_PRJ} --name=${BUILD_CFG_NAME} --image-stream=${BUILDER_NAME}:${TAG} ${SRC_URL}
oc get bc -n ${K_I_PRJ}
sleep 30
oc logs -f $(oc get pods --sort-by='.metadata.name' | tac | grep -v NAME | grep ${APP_NAME} | grep build | grep Running | awk '{print $1}')
# --------------------------------
# STEP: 5
# --------------------------------
# create application and then route
oc new-app -n ${K_I_PRJ} ${BUILD_CFG_NAME} --name=${APP_NAME} --allow-missing-imagestream-tags
SHORT_NAME=shortname
oc expose service ${APP_NAME} --name ${SHORT_NAME}
oc get routes | grep ${APP_NAME}
URL=$(oc get route ${SHORT_NAME} | grep -v NAME | awk '{print "http://"$2}')
echo ${URL}
# pod log, filter pods looking for last created, exclude build pods
# wait for pod to get to Running state
sleep 20
oc logs -f $(oc get pods --sort-by='.metadata.name' | tac | grep -v NAME | grep -v "\-build" | grep ${APP_NAME} | grep Running | awk '{print $1}')
# --------------------------------
# STEP: 6
# --------------------------------
# test application
curl -w"\n" -sX POST ${URL}/MyRequest -H 'content-type: application/json' -H 'accept: application/json' -d '{"requestData": {"key":"1", "useRules": true, "showResult": true}}' | jq .
curl -w"\n" -sX GET ${URL}/MyRequest -H 'accept: application/json' | jq .
You can also reuse the other 'curl' commands already seen when running tests locally on your laptop.
Example of updating the sources on GIT and subsequent rebuild of the application
For example, modify the Java class org.kie.kogito.marco.utils.MyUtils on your Git project
with for example the value of the new version (version 1.1)
package org.kie.kogito.marco.utils;
public class MyUtils {
public static String getAppInfos() {
StringBuffer sb = new StringBuffer();
sb.append("MyProcess example\n");
sb.append("version 1.1");
return sb.toString();
}
}
Then perform the commit and push operation to update the project on the GitHub site.
Remaining positioned in the namespace with IBM images (but you can also do it in our with images based on KieGroup distribution) run the following commands
# start a new build
oc start-build my-process-quarkus-example
# retry the logs command until build pod started
oc logs -f $(oc get pods --sort-by='.metadata.name' | tac | grep -v NAME | grep ${APP_NAME} | grep build | grep Running | awk '{print $1}')
A new pod containing the modified application will be created to replace the old one, this in automatic mode because Red Hat OpenShift offers powerful development tools.
When using the BuildConfig and Build configurations based on source code, the container image tag that is built in the OpenShift internal registry is dynamically updated with each new build and the Deployments are dynamically updated with the consequent renewal of the pods.
BuildConfig type CR snippet example
kind: BuildConfig
apiVersion: build.openshift.io/v1
metadata:
annotations:
openshift.io/generated-by: OpenShiftNewBuild
resourceVersion: '3329440'
name: my-process-quarkus-example
....
status:
lastVersion: 1
imageChangeTriggers:
- lastTriggeredImageID:> -
registry.redhat.io/ibm-bamoe/bamoe-kogito-builder-rhel8@sha256:09617130f2f4a4a48f4235c86bb392adce4b2c6873157c45dd2a97040c4c35e4
from:
namespace: my-ibamoe-images1
name: 'bamoe-kogito-builder-rhel8: 8.0.0-4'
lastTriggerTime: '2022-10-15T13: 45: 37Z'
Build type CR snippet example
kind: Build
apiVersion: build.openshift.io/v1
metadata:
annotations:
openshift.io/build-config.name: my-process-quarkus-example
openshift.io/build.number: '1'
openshift.io/build.pod-name: my-process-quarkus-example-1-build
resourceVersion: '3334851'
name: my-process-quarkus-example-1
...
triggeredBy:
- message: Image change
imageChangeBuild:
imageID:> -
registry.redhat.io/ibm-bamoe/bamoe-kogito-builder-rhel8@sha256:09617130f2f4a4a48f4235c86bb392adce4b2c6873157c45dd2a97040c4c35e4
fromRef:
kind: ImageStreamTag
namespace: my-ibamoe-images1
name: 'bamoe-kogito-builder-rhel8: 8.0.0-4'
POD example (container image on OpenShift internal registry)
kind: Pod
apiVersion: v1
metadata:
generateName: my-process-quarkus-example-79bdd57788-
annotations:
...
openshift.io/generated-by: OpenShiftNewApp
openshift.io/scc: restricted
name: my-process-quarkus-example-79bdd57788-hb9gs
spec:
...
image:> -
image-registry.openshift-image-registry.svc: 5000 / my-ibamoe-images1 / my-process-quarkus-example @ sha256: d669322cb82335c4836a7c48a3c716bcd2f81c82ff55a5378d1b4584c87e5c22
For further information on S2I build themes within the cluster, refer to the official OpenShift documentation.
Conclusions
As you have seen, the development philosophy and workflow based on OSS tools is fully compatible and supported by IBM Process Automation Manager Open Editions.
You can then develop and test your Kogito based applications anywhere and then bring them to the OpenShift environment with automatic build thanks to S2I features.
For production environments and also for those where you will need professional support and with guaranteed SLAs you can use the images in docker format offered by IBM.
References
IBM Process Automation Manager Open Editions Documentation
https://www.ibm.com/docs/en/ibamoe
IBM Business Automation Manager Open Editions Software Support Lifecycle Addendum
https://www.ibm.com/support/pages/node/6596913
KieGroup
https://github.com/kiegroup/kogito-operator/releases
https://raw.githubusercontent.com/kiegroup/kogito-images/main/kogito-imagestream.yaml
Kogito
https://kogito.kie.org/
https://kogito.kie.org/get-started/
Quarkus
https://quarkus.io
https://quarkus.io/get-started/
Maven
https://maven.apache.org/
Java JDK
https://adoptopenjdk.net/
VSCode
https://code.visualstudio.com/Download
Red Hat Developer Program
https://developers.redhat.com/about
Red Hat OpenShift Dev Spaces (formerly CodeReady)
https://developers.redhat.com/products/openshift-dev-spaces/getting-started
jq tool
https://www.cyberithub.com/how-to-install-jq-json-processor-on-rhel-centos-7-8/
Previous posts related to this topic
Setup IBM Process Automation Manager Open Edition (PAM/DM) using docker images
https://community.ibm.com/community/user/automation/blogs/marco-antonioni/2022/09/24/setup-ibm-process-automation-manager-open-edition
Setup IBM Process Automation Manager Open Edition (PAM/DM) in OpenShift
https://community.ibm.com/community/user/automation/blogs/marco-antonioni/2022/09/28/setup-ibm-process-automation-manager-open-edition
Use OpenShift CLI to setup IBM PAM Open Editions
https://community.ibm.com/community/user/automation/blogs/marco-antonioni/2022/10/09/use-openshift-cli-to-setup-ibm-pam-open-editions