In a previous blog post, we explained how to deploy an existing JBoss BRMS/Drools rules project onto an OpenShift DecisionServer. We created a decision/business-rules microservice on OpenShift Container Platform that was implemented by a BRMS application. The polyglot nature of a microservice architecture allowed us to use the best implementation (a rules engine) for this given functionality (business rules execution) in our architecture.
The project we used was an existing rules project that was available on GitHub. We did however not explain how one can create a project from scratch in the JBoss BRMS Business Central environment and deploy it on OpenShift Container Platform. That is what we will explore in this article.
Building the rules project
Red Hat JBoss BRMS provides a workbench, authoring environment and project & rules repository called "Business Central". We will use Business Central to create our rules project, define our data model, and create our rules.
We provide a Red Hat JBoss BRMS Installation Demo that provides an easy installation of the BRMS platform. Please follow this demo to install and start the platform. Once the platform is started, we can create our project. The project will be a simple "Loan Application" demo (in fact, it will be based on one of our existing demo's, which can be found here).
Open "Business Central" at "http://localhost:8080/business-central" and provide the username (brmsAdmin) and password (jbossbrms1!) (if you've installed the platform in a Docker container, use the URL of your Docker host as explained in the README of the Install Demo). We first need to create a so-called Organizational Unit (OU) in the "Business Central" interface:
- Click on "Authoring -> Administration"
- Click on "Organizational Units -> Manage Organizational Units"
- Click on "Add" and create a new Organizational Unit with name "Demos" (you can leave the other fields in the screen empty).
Now we're going to create a new repository in which we can store our project:
- Click on "Repositories -> New repository"
- Give it the name "loan" and assign it to the "Demos" OU we created earlier (leave "Managed Repository" unchecked).
Our next task is to create the project:
- Click on "Authoring -> Project Authoring"
- Click on "New Item -> Project"
- Provide the following details:
- Project Name: loandemo
- Group ID: com.redhat.demos
- Artifact ID: loandemo
- Version: 1.0
Creating the Data Model
Now that we have a project, we can create our data model. In this example, we will create a simple data model consisting of 2 classes: Applicant and Loan.
- Click on "New Item -> Data Object"
- Give the object the name "Applicant"
- Set the package to "com.redhat.demos.loandemo"
- Give the object two fields:
- creditScore: int (Label: CreditScore)
- name: String (Label: Name)
Next, create a data object with name "Loan" in package "com.redhat.demos.loandemo" with the following fields:
- Amount: int (Label: Amount)
- approved: boolean (Label: Approved)
- Duration: int (Label: Duration)
- InterestRate: double (Label: InterestRate)
Make sure to save the objects using the "save" button (upper right corner) of the editor. We can now create our rules.
Writing the rules
We will create our rules in the form of a decision table:
- Click on "New Item -> Guided Decision Table"
- Give it the name "LoanApproval"
- Set the package to "com.redhat.demos.loan"
- Make sure to select "Extended entry, values defined in table body"
Our decision table will consist of 4 Constraint columns and one Action column. Our Constraint columns define the so-called Left-Hand-Side of our rules, the "when" part. The Action column defines the Right-Hand-Side or "then" part.
To add a Condition column:
- Click on the "+" sign next to the word "Decision Table"
- Click on "New Column"
- Select "Add a Simple Condition" and define the following settings:
- Pattern: Applicant (set "a" for binding)
- Calculation Type: Literal Value
- Field: creditScore
- Operator: greater than or equal to
- Column Header: Minimum Credit Score
Define 3 additional Condition columns with the following values:
- Pattern: Applicant (set "a" for binding)
- Calculation Type: Literal Value
- Field: creditScore
- Operator: less than or equal to
- Column Header: Maximum Credit Score
- Pattern: Loan (set "l" for binding)
- Calculation Type: Literal Value
- Field: amount
- Operator: greater than or equal to
- Column Header: Minimum Amount
- Pattern: Loan (set "l" for binding)
- Calculation Type: Literal Value
- Field: amountOperator: less than or equal to
- Column Header: Maximum Amount
Finally, we need to configure our Action column:
- Click again on "New Column"
- Select "Set the value of a field"
- Provide the following values:
- Fact: l (this is our Loan fact that we defined in our Condition columns)
- Field: approved
- Column header: Approved?
Save the Decision Table. We can now set the values in our decision table. Each row in our table defines a rule. When complete, the table should look like this:
Configuring the project for OpenShift S2I builds
The Red Hat JBoss BRMS Decision Server in OpenShift Container Platform uses the so-called S2I, or Source-to-Image, concept to build its OpenShift (Docker) container images. In essence, you provide S2I the source code of your rules project, and the build system will use Maven to build the KJAR (Knowledge JAR) containing the data model and rules, deploy this KJAR onto the Decision Server and create the container image.
Because S2I uses Maven, we first need to make sure that our project is buildable by Maven. To verify this, we clone the project onto our local filesystem. Business Central uses a Git repository for storage under the covers, so we can simply use our favorite Git tool to clone the BRMS repository:
> git clone ssh://brmsAdmin@localhost:8001/loan
Note that the Git implementation of Business Central uses an older public key algorithm (DAS), which might require you to add the following settings to your SSH configuration file (on Linux and macOS this file is located at "~/.ssh/config").
Host localhost HostKeyAlgorithms +ssh-dss
After the project has been successfully cloned, go to the "loan/loandemo" directory and run "mvn clean install" to start the Maven build. If all his correct, this will produce a build failure:
[INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 7.982 s [INFO] Finished at: 2017-06-07T23:26:18+02:00 [INFO] Final Memory: 34M/396M [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.5.1-jboss-2:compile (default-compile) on project loandemo: Compilation failure: Compilation failure: [ERROR] /Users/ddoyle/Development/github/jbossdemocentral/bla/loan/loandemo/src/main/java/com/redhat/demos/loandemo/Applicant.java:[12,32] package org.kie.api.definition.type does not exist [ERROR] /Users/ddoyle/Development/github/jbossdemocentral/bla/loan/loandemo/src/main/java/com/redhat/demos/loandemo/Applicant.java:[14,32] package org.kie.api.definition.type does not exist [ERROR] /Users/ddoyle/Development/github/jbossdemocentral/bla/loan/loandemo/src/main/java/com/redhat/demos/loandemo/Loan.java:[12,32] package org.kie.api.definition.type does not exist [ERROR] /Users/ddoyle/Development/github/jbossdemocentral/bla/loan/loandemo/src/main/java/com/redhat/demos/loandemo/Loan.java:[14,32] package org.kie.api.definition.type does not exist [ERROR] /Users/ddoyle/Development/github/jbossdemocentral/bla/loan/loandemo/src/main/java/com/redhat/demos/loandemo/Loan.java:[16,32] package org.kie.api.definition.type does not exist [ERROR] /Users/ddoyle/Development/github/jbossdemocentral/bla/loan/loandemo/src/main/java/com/redhat/demos/loandemo/Loan.java:[18,32] package org.kie.api.definition.type does not exist
This is because our domain model contains Java annotations from the "kie-api" library, however, that dependency is not defined in the "pom.xml" project descriptor of our project. This dependency is not required for builds done in Business Central, as Business Central provides this JAR on the build path implicitly. However, we need to explicitly define this dependency in our "pom.xml" file for our local and Decision Server S2I Maven builds to succeed.
Add the following dependency to the "pom.xml" file of the project:
<dependencies> <dependency> <groupId>org.kie</groupId> <artifactId>kie-api</artifactId> <version>6.4.0.Final-redhat-13</version> <scope>provided</scope> </dependency> </dependencies>
Note the "provided" scope, as we only require this dependency at compile time. At runtime, this dependency is provided by the Decision Server platform.
Run the build again: "mvn clean install". The build should now succeed. We can commit these changes and push them back to our Git repository in Business Central with the following commands:
> git add pom.xml > git commit -m "Added kie-api dependency to POM." > git push
Making the project accessible to OpenShift S2I
As explained earlier, the BRMS Decision Server S2I build takes the source code of your project, for example from a Git repository, compiles the sources into a KJAR, deploys the KJAR onto the Decision Server and builds the OpenShift image (detailed information about the xPaaS BRMS image for OpenShift can be found in the manual). Therefore, the S2I build needs to have access to our project's source code.
In our demo, we have 2 options to make our project available to the S2I build image:
- If we can access our Business Central environment from our OpenShift instance, we can point the S2I image directly to our Git repository in Business Central. This repository is located at "git://localhost:9418/loan".
- Make the Git repo available at a location that the OpenShift can access, for example, GitHub.
In this example, we will use the second option and make our Git repository accessible via GitHub (other platforms, like Gitlab, Bitbucket or an internal Gogs instance can, of course, be used as well). To accomplish this we need to create an empty repository on Github, for example at https://www.github.com/DuncanDoyle/loan".
Next, we add this new repository as the "upstream" repository to the local clone of our BRMS Business Central git repository:
> git remote add upstream git@github.com:DuncanDoyle/loan.git > git push upstream master
Our BRMS Loan Demo project is now available on and accessible via, GitHub.
Deploying our Business Rules on OpenShift
In the previous Micro-rules on OpenShift blog post, we explained how to setup an OpenShift environment so that we can deploy a rules micro-service on the Decision Server. We will not repeat the setup documentation in this article, so please consult that post to learn how to quickly setup a local OpenShift environment.
Once we have access to an OpenShift environment that has the correct ImageStreams (jboss-decisionserver63-openshift) and templates (decisionserver63-basic-s2i) deployed, we can create a new project and our new application using the following command:
> oc new-project loan-demo --display-name="Loan Demo" --description="Red Hat JBoss BRMS Decision Server Loan Demo" > oc new-app --template=decisionserver63-basic-s2i -p APPLICATION_NAME="loan-demo" -p KIE_SERVER_USER="brmsAdmin" -p KIE_SERVER_PASSWORD="jbossbrms@01" -p SOURCE_REPOSITORY_URL="https://github.com/DuncanDoyle/loan.git" -p SOURCE_REPOSITORY_REF=master -p KIE_CONTAINER_DEPLOYMENT="container-loan10=com.redhat.demos:loandemo:1.0" -p CONTEXT_DIR="loandemo"
Note that the syntax of this "new-app" command is a bit different from the syntax of the same command in our Micro-rules on OpenShift blog post. In newer versions of OpenShift, all parameters provided to the command need to be prefixed with "-p".
We can check the status of the S2I build and deployment via the OpenShift CLI tool or the OpenShift Console.
Once the DecisionServer with our project has been deployed, we can send it a Loan Application request. We can use the following cURL command to fire a request:
curl -u brmsAdmin:jbossbrms@01 -X POST -H "Accept: application/json" -H "Content-Type: application/json" -H "X-KIE-ContentType: JSON" -d '{ "commands":[ { "insert":{ "object":{ "com.redhat.demos.loandemo.Applicant":{ "creditScore":230, "name":"Jim Whitehurst" }}, "out-identifier":"applicant" }}, { "insert":{ "object":{ "com.redhat.demos.loandemo.Loan":{ "amount":2500, "approved":false, "duration":24, "interestRate":1.5 }}, "out-identifier":"loan" }}, { "fire-all-rules":{ }}]}' http://loan-demo-loan-demo.127.0.0.1.xip.io/kie-server/services/rest/server/containers/instances/container-loan10
Because the inline JSON in the cUrl command is a bit hard to read, we have printed the formatted JSON request below:
{ "commands":[ { "insert":{ "object":{ "com.redhat.demos.loandemo.Applicant":{ "creditScore":230, "name":"Jim Whitehurst" } }, "out-identifier":"applicant" } }, { "insert":{ "object":{ "com.redhat.demos.loandemo.Loan":{ "amount":2500, "approved":false, "duration":24, "interestRate":1.5 } }, "out-identifier":"loan" } }, { "fire-all-rules":{ } } ] }
This JSON request is the representation of a BRMS "BatchExecutionCommand" in which we insert 2 objects (facts) into the rules engine, Applicant and Loan, after which we give the command to fire the rules. The response will look like this:
{ "type":"SUCCESS", "msg":"Container 166d7802fc076eb3d6eda22cf186071c successfully called.", "result":{ "execution-results":{ "results":[ { "key":"loan", "value":{ "com.redhat.demos.loandemo.Loan":{ "amount":2500, "approved":true, "duration":24, "interestRate":1.5 } } }, { "key":"applicant", "value":{ "com.redhat.demos.loandemo.Applicant":{ "creditScore":230, "name":"Jim Whitehurst" } } } ], "facts":[ { "key":"loan", "value":{ "org.drools.core.common.DefaultFactHandle":{ "external-form":"0:6:1508714685:1508714685:6:DEFAULT:NON_TRAIT:com.redhat.demos.loandemo.Loan" } } }, { "key":"applicant", "value":{ "org.drools.core.common.DefaultFactHandle":{ "external-form":"0:5:576291744:576291744:5:DEFAULT:NON_TRAIT:com.redhat.demos.loandemo.Applicant" } } } ] } } }
Note that the application has been approved, as the "approved" field of our Loan object has been set to "true".
Conclusion
In this article, we have shown how to get from a clean installation of Red Hat JBoss BRMS to a running Business Rules microservice on the Decision Server in OpenShift. We've shown how we can build a simple BRMS project, domain model and decision table for a Loan Application service, how this project can be shared with the OpenShift S2I build system via Git, and how a new rules application on OpenShift can be created. We concluded with an example that shows how to insert data into the rules and engine, fire the rules and receive a response using the BRMS DecisionServer's RESTful API.
Red Hat JBoss BRMS provides a lightweight Decision Server engine that is extremely suitable for cloud deployments. In combination with Red Hat OpenShift Container Platform, it provides the perfect runtime for business-rules micro-services implementations, providing the power of a business rules engine in modern enterprise architectures.
About the author:
Duncan Doyle is the Technical Marketing Manager for the JBoss BRMS and BPMSuite platforms at Red Hat. With a background in Red Hat Consulting and Services, Duncan has worked extensively with large Red Hat customers to build advanced, open-source, business rules and business process management solutions.
He has a strong background in technologies and concepts like Service Oriented Architecture, Continuous Integration & Delivery, rules engines and BPM platforms and is a subject matter expert (SME) on multiple JBoss Middleware technologies, including, but not limited to, JBoss EAP, HornetQ, Fuse, DataGrid, BRMS, and BPMSuite. When he’s not working on open-source solutions and technology, he is building Legos with his son and daughter or jamming along with some 90’s rock music on his Fender Stratocaster.
Click here to download and quickly get started with Red Hat JBoss BRMS.