How did I create a DB-driven dynamic Drools-based rules engine?

Bipin Thite
5 min readOct 5, 2020
Photo by Alexander Schimmeck on Unsplash

What is Drools?

From the website,

Drools is a business-rule management system with a forward-chaining and backward-chaining inference-based rules engine, allowing fast and reliable evaluation of business rules and complex event processing. A rules engine is also a fundamental building block to create an expert system which, in artificial intelligence, is a computer system that emulates the decision-making ability of a human expert.

Using Drools, you can define your business rules in Drools Rule Language (DRL), decision tables, or in other supported formats. A rule contains a condition and an action. At runtime, you pass the facts to the Drools engine, which then evaluates the rules based on conditions. One or more matching rules are picked and the associated actions are executed which is nothing but the decision-making.

An example rule in DRL for loan application age limit,

rule "Underage"

when
$application : LoanApplication()
Applicant( age < 21 )
then
$application.setApproved( false );
$application.setExplanation( "Underage" );
end

Another example showing the spreadsheet decision table for shipping charges,

A Drools decision table for shipping charges
Source: Drools documentation

You can also group your relevant business rules together in a knowledge base. This is especially useful when you have hundreds of rules of different types and you don’t want Drools to evaluate them all. For better organization and faster rules execution, you can ask Drools to fire rules of a specific knowledge base.

Some of the challenges with Drools

While Drools enables you to define and manage the business rules outside of your code, it presents some challenges too.

Rules artifacts management

Generally, a Drools-based Java application requires all the rules artifacts such as DRLs, decision table excels, etc., to be part of the application binary itself. That means, artifacts have to be either with the source code repository or you include them during the application build process. This becomes cumbersome especially if you have frequently changed rules. In this case, you would need to add or modify the rules artifacts, build the application code, and deploy to your servers.

Data objects

In DRL rule, you can use Java data objects to retrieve facts or set results. Usually, you write and use data objects as per the use case. To use new data objects, obviously, they need to be coded and used in the rules. Like the previous challenge, this also requires code modification and deployment.

With these, the process of introducing new rules or changing the existing ones is not an easy ride. In the end, this impacts your productivity and business as you can’t quickly roll out the changes.

What did I want?

To overcome these challenges, I was looking for a way by which,

  • I could store all the rules not with the application binary but in an external system such as a database,
  • I could define and group the rules in different knowledge bases,
  • I could roll out new changes quickly without an application deployment or a restart,
  • I could have a lightweight and a generic service which can work with a common data object, eliminating the need to modify the code,
  • I could have an API endpoint which accepts facts in a common format, a name of the knowledge base, and responds with any data generated by the rules execution,

The solution I went with

In order to achieve my goals, I needed a way to,

  • get the rules from the external system
  • build the Drools internal objects (like KieContainer, KieModule, KieBase, etc.)
  • compile the rules to check for any syntax errors,
  • make KieContainer instance available throughout the lifecycle of microservice,
  • re-build the Drools objects when rules are updated in the external system

For storing the rules, I simply went with the database approach as I get tight control over the rules management, versioning, backups, security, etc. I can put rules in the Git repository and have a build pipeline to push them to the database. We have several approaches here, like storing rules in NFS, Git repository, and pull them directly from the service. I have a very simple database schema containing two tables, “rules” and “knowledgeBases”.

Simple Database schema to store rules

Here, I can put either DRL contents as text in a “ResourceContents” column or store rules file (e.g. decision table spreadsheet) in the “ResourceData” column as a BLOB.

Now, the next hurdle was to programmatically build Drools objects. Thankfully, Drools has the documentation on defining KieModule programmatically. I also got help from this GitHub repository where a similar approach is adopted. After spending a good amount of time understanding from both the references, I could be able to finalize the way to define all those required objects programmatically.

With this, I could be able to store rules in SQL database and build all required Drools objects ready to fire rules. Now, having completed the most difficult part, rebuilding KieContainer on rule-change, creating RESTful API to fire rules was straight-forward. Currently, I have defined an admin API that triggers the rebuilding of KieContainer on-demand. This may not be the ideal way, especially if you’ve multiple copies of microservice running. I would need to go and hit reload API for each service instance. I can think of improving this in the future.

I defined a simple RESTful API endpoint which accepts facts as key-value pairs (JSON) and the name of the knowledge base.

To return the output from the rules execution, I iterate over all the facts handle from the KieSession and collect all the fact objects.

I hope that you find this article useful. You can find the sample code repository here. Cheers!

References:

https://github.com/ityouknow/drools-examples/tree/master/spring-boot-drools-db

--

--

Bipin Thite

A software professional working with Java, Node.js, DevSecOps, Azure