Using the KIE (Drools) Workbench REST API to create a project

I was playing around with the KIE Workbench Docker image and came across an issue whereby the container would become unusable if the IP address of the host changed. My sandbox is VirtualBox, running Ubuntu 16.04, so this would happen all the time. I needed some way to be able to blow away an existing container and start up a new one with the project I had been working on.

This turned out to be a bit fiddly. For example, I couldn’t clone the Git repository for my project and push it into a new container. The new container didn’t have a repository to push to. Similarly, it wasn’t enough to copy the myproject.git file out of the original image and into the new one. It clearly takes more than that.

A process that I found, which did work was to start up a new container, go into the Workbench web application and create an organisation, repository and project, with the same names as in the previous container. I could then pull that repository into the project I had already cloned. Subsequent to a little bit of merging, I would then be able to push the repository back to the remote Workbench repository.

As you might imagine, creating the organisation, repository and project with the exact same names was a bit tedious and error prone, when done manually. I wasn’t happy. However, I spotted that Workbench provides a REST API for a small set of actions, such as creating an organisation, creating a repository and creating a project. There’s some documentation here:

https://docs.jboss.org/drools/release/6.5.0.Final/drools-docs/html/ch20.html

So I dived in and tried it out. Unfortunately things went a pear-shaped rather quickly. It would appear that the API might have changed a little bit without the documentation being updated. But a little dig through the Workbench API code showed me that it wasn’t massively out of sync. It’s actually quite easy. You just need to understand the order that things need to be done and a couple of undocumented properties.

First, create an organisation:

curl -X POST -H "Content-Type: application/json" --user admin:admin \
    127.0.0.1:8080/drools-wb/rest/organizationalunits \
    -d '{ "name": "com.sctrcd.kiewb", \
          "description": "Example Workbench Organisation", \
          "owner": "Scattercode", \
          "defaultGroupId": "com.sctrcd.kiewb" }'

Note that the defaultGroupId is not mentioned in the documentation. Without it, you will find that an organisation seems to be created and can be seen in the Workbench web interface. However, there will be a couple of problems with it. For one, if you try making a GET request for it, the API will not be able to find it. You will receive a 404 response. Similarly, if you try to create a repository associated with the organisation, the creation will fail with a 404, when the API tries to find the organisation. But if you include the defaultGroupId, all will be well.

Second, create a repository associated with that organisation:

curl -X POST -H "Content-Type: application/json" --user admin:admin \
    127.0.0.1:8080/drools-wb/rest/repositories \
    -d '{ "name": "rulesrepo", \
          "description": "Example rules repo", \
          "userName": null, "password": null, "gitURL": null, \
          "requestType": "new", \
          "organizationalUnitName": "com.sctrcd.kiewb" }'

Note here, that the documentation implies that you can create a repository without associating it with an organisation. This is something you can do in the Workbench web interface, but through the API, it fails. So you should include the organizationalUnitName in the call to create the repository. There’s not much point in a repository without an organisation, anyway.

Finally, create a project in the repository:

curl -X POST -H "Content-Type: application/json" --user admin:admin \
    127.0.0.1:8080/drools-wb/rest/repositories/rulesrepo/projects/ \
    -d '{ "name": "rulesproject", \
          "description": "Example rules project" }'

Now you’re done. If you have a local Git project, cloned from the original Workbench container, and you have started the new container on the same ports and host, then you can just run a Git pull.

At this point, the Git pull will leave merge issues on a handful of files. I’m currently trying to think of my preferred process to correct this. I may just script up taking a copy of the files (5 of them), copying them back after the pull, committing and pushing.

Now that you know the steps, I should mention that I created a script to perform all three steps. If you want to base a script of your own on it, feel free. Here it is:


#!/bin/bash
# ——————————————————————————–
#
# Script to demonstrate using the KIE (Drools) Workbench REST API to:
#
# create an organistion.
# create a repository associated with the organisation.
# create a project in the repository.
#
# Based on the documentation here:
# https://docs.jboss.org/drools/release/6.5.0.Final/drools-docs/html/ch20.html
#
# At time of writing, the official documentation seems to be a little bit behind
# the current state of the API. Therefore, if you use the example entities provided
# in the documentation, the API calls will not work.
#
# Some of the values hardcoded below (URL, username, password), are based
# on those defined in the Drools Workbench Showcase Docker image:
# https://hub.docker.com/r/jboss/drools-workbench-showcase/
# I would recommend turning those into arguments or environment variables if you
# intend to make use of this script. I have done that here, just to keep everything
# for the example in one place. Please, don't keep the hardcoded password!
#
# ——————————————————————————–
# ——————————————————————————–
# First, we create an organisation
# ——————————————————————————–
API_RESPONSE=`curl -X POST -H "Content-Type: application/json" –user admin:admin \
127.0.0.1:8080/drools-wb/rest/organizationalunits \
-d '{ "name": "com.sctrcd.kiewb", \
"description": "Example Workbench Organisation", \
"owner": "Scattercode", \
"defaultGroupId": "com.sctrcd.kiewb" }'`
echo "API_RESPONSE: "
echo "$API_RESPONSE"
echo ""
JOB_STATE=`echo $API_RESPONSE | jq -c '. | {status}'`
JOB_ID=`echo $API_RESPONSE | jq -c '. | {jobId}'`
JOB_ID=${JOB_ID#'{"jobId":"'}
JOB_ID=${JOB_ID%'"}'}
echo "JOB_STATE: $JOB_STATE"
echo "JOB_ID: $JOB_ID"
if [ "$JOB_STATE" != '{"status":"APPROVED"}' ]
then
echo "Request rejected. Request state: $JOB_STATE"
exit 1
fi
# All jobs are async. We need to keep checking the state of the job until it is flagged as SUCCESS or fails.
while [[ $JOB_STATE == '{"status":"APPROVED"}' || $JOB_STATE == '{"status":"ACCEPTED"}' ]]; do
JOB_STATE=`curl 127.0.0.1:8080/drools-wb/rest/jobs/$JOB_ID –user admin:admin | jq -c '. | { status }'`
echo "JOB_STATE: $JOB_STATE"
sleep 1s
done
if [ "$JOB_STATE" != '{"status":"SUCCESS"}' ]
then
echo "Request accepted, but failed. Job state: $JOB_STATE"
if [ "$JOB_STATE" != '{"status":"BAD_REQUEST"}' ]
then
# A BAD_REQUEST state indicates that the resource is already there.
exit 1
fi
fi
echo "Request succeeded. Job state: $JOB_STATE"
# ——————————————————————————–
# Now that we have an organisation, we can create a repository.
# ——————————————————————————–
API_RESPONSE=`curl -X POST -H "Content-Type: application/json" –user admin:admin \
127.0.0.1:8080/drools-wb/rest/repositories \
-d '{ "name": "rulesrepo", \
"description": "Example rules repo", \
"userName": null, "password": null, "gitURL": null, \
"requestType": "new", \
"organizationalUnitName": "com.sctrcd.kiewb" }'`
echo ""
echo "API_RESPONSE: "
echo "$API_RESPONSE"
echo ""
JOB_STATE=`echo $API_RESPONSE | jq -c '. | {status}'`
JOB_STATE=`echo $API_RESPONSE | jq -c '. | {status}'`
JOB_ID=`echo $API_RESPONSE | jq -c '. | {jobId}'`
JOB_ID=${JOB_ID#'{"jobId":"'}
JOB_ID=${JOB_ID%'"}'}
echo "JOB_STATE: $JOB_STATE"
echo "JOB_ID: $JOB_ID"
if [ "$JOB_STATE" != '{"status":"APPROVED"}' ]
then
echo "Request rejected. Request state: $JOB_STATE"
exit 1
fi
# All jobs are async. We need to keep checking the state of the job until it is flagged as SUCCESS or fails.
while [[ $JOB_STATE == '{"status":"APPROVED"}' || $JOB_STATE == '{"status":"ACCEPTED"}' ]]; do
JOB_STATE=`curl metis:8080/drools-wb/rest/jobs/$JOB_ID –user admin:admin | jq -c '. | { status }'`
echo "JOB_STATE: $JOB_STATE"
sleep 1s
done
if [ "$JOB_STATE" != '{"status":"SUCCESS"}' ]
then
echo "Request accepted, but failed. Job state: $JOB_STATE"
if [ "$JOB_STATE" != '{"status":"BAD_REQUEST"}' ]
then
# A BAD_REQUEST state indicates that the resource is already there.
exit 1
fi
fi
echo "Request succeeded. Job state: $JOB_STATE"
# ——————————————————————————–
# Now that we have a repository, lets create a project in it.
# ——————————————————————————–
API_RESPONSE=`curl -X POST -H "Content-Type: application/json" –user admin:admin \
127.0.0.1:8080/drools-wb/rest/repositories/rulesrepo/projects/ \
-d '{ "name": "rulesproject", \
"description": "Example rules project" }'`
echo ""
echo "API_RESPONSE: "
echo "$API_RESPONSE"
echo ""
JOB_STATE=`echo $API_RESPONSE | jq -c '. | {status}'`
JOB_STATE=`echo $API_RESPONSE | jq -c '. | {status}'`
JOB_ID=`echo $API_RESPONSE | jq -c '. | {jobId}'`
JOB_ID=${JOB_ID#'{"jobId":"'}
JOB_ID=${JOB_ID%'"}'}
echo "JOB_STATE: $JOB_STATE"
echo "JOB_ID: $JOB_ID"
if [ "$JOB_STATE" != '{"status":"APPROVED"}' ]
then
echo "Request rejected. Request state: $JOB_STATE"
exit 1
fi
# All jobs are async. We need to keep checking the state of the job until it is flagged as SUCCESS or fails.
while [[ $JOB_STATE == '{"status":"APPROVED"}' || $JOB_STATE == '{"status":"ACCEPTED"}' ]]; do
JOB_STATE=`curl metis:8080/drools-wb/rest/jobs/$JOB_ID –user admin:admin | jq -c '. | { status }'`
echo "JOB_STATE: $JOB_STATE"
sleep 1s
done
if [ "$JOB_STATE" != '{"status":"SUCCESS"}' ]
then
echo "Request accepted, but failed. Job state: $JOB_STATE"
if [ "$JOB_STATE" != '{"status":"BAD_REQUEST"}' ]
then
# A BAD_REQUEST state indicates that the resource is already there.
exit 1
fi
fi
echo "Request succeeded. Job state: $JOB_STATE"

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.