Spring Boot + Drools Decision Table Example
Overview
In this article, we'll explore how to integrate Spring Boot with Drools Decision Table.
Drools is a BRMS (Business Rules Management System). It includes a Business Rules Engine (BRE), a web authoring and rules management framework (Drools Workbench), complete runtime support for Decision Model and Notation (DMN) models at Conformance level 3, and a core development Eclipse IDE plugin.
It is written in 100% pure Java, runs on any JVM and is available in the Maven Central repository too.
The Drools assists you in separating and reasoning over logic and data in business processes. It has a forward and backward chaining inference-based drools rules engine that supports forward and backward chaining.
Drools Tutorial :
- Drools Overview - Architecture
- Spring Boot + Drools Example
- Spring Boot + Drools Decision Table Example
- Drools Interview Questions and Answers
What is Drools Decision Table?
Drools Decision Table is a simple way of presenting conditional logic that may be used to create business rules in Drools. A Drool Decision Table is a new way for generating rules from the data entered into a spreadsheet. The spreadsheet might be in the form of an Excel (XLS) or a CSV file.
We will consider the Fixed Deposit example by providing the rate of interest depending on bank name and duration in year.
Project Structure
Maven dependency
Define the pom.xml as follows- Add the drools-core ,drools-compiler and drools-decisiontables dependency.<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.techgeeknext.examples</groupId>
<artifactId>drools-decision-table-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>drools-decision-table-demo</name>
<description>Demo project for Spring Boot Drools Decision Table</description>
<properties>
<java.version>1.8</java.version>
<drools.version>7.49.0.Final</drools.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>${drools.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Take a look at our suggested posts:
Model Object
Create FDRequest.java as below to map the object from FDInterestRate.xls (Decision Table) rule file.package com.techgeeknext.examples.drools.domain;
public class FDRequest {
private String bankName;
private Integer durationInYear;
private String fdInterestRate;
public FDRequest(String bankName, Integer durationInYear) {
this.bankName = bankName;
this.durationInYear = durationInYear;
}
public String getBankName() {
return bankName;
}
public void setBankName(String bankName) {
this.bankName = bankName;
}
public Integer getDurationInYear() {
return durationInYear;
}
public void setDurationInYear(Integer durationInYear) {
this.durationInYear = durationInYear;
}
public String getFdInterestRate() {
return fdInterestRate;
}
public void setFdInterestRate(String fdInterestRate) {
this.fdInterestRate = fdInterestRate;
}
}
Drools Configuration
To fire rules on a given set of data, we must instantiate the framework's provided classes, which contain details about the location of rule files (FDInterestRate.xls) and the Facts.
First, we must initialize the KieFileSystem bean, this is an in-memory file system provided by the framework. Following code provides the container to define the Drools resources such as rules files, decision tables, programmatically:
package com.techgeeknext.examples.drools.config;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieModule;
import org.kie.api.runtime.KieContainer;
import org.kie.internal.io.ResourceFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DroolsConfiguration {
private final KieServices kieServices = KieServices.Factory.get();
@Bean
public KieContainer getKieContainer() {
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
kieFileSystem.write(ResourceFactory.newClassPathResource("rules/FDInterestRate.xls"));
KieBuilder kb = kieServices.newKieBuilder(kieFileSystem);
kb.buildAll();
KieModule kieModule = kb.getKieModule();
return kieServices.newKieContainer(kieModule.getReleaseId());
}
}
The buildAll()
method invoked on KieBuilder builds all the resources and bind them to KieBase. It only executes successfully if it is able to find and validate all of the rule files.
Next, we must initialize the KieContainer, which is a placeholder for all the KieBases for particular KieModule. KieContainer is built with the help of other beans including KieFileSystem, KieModule, and KieBuilder.
Controller
Now, write a controller that takes Fixed Deposit parameters as an input and evaluates the rule entries.
KieSession
The rules are fired by opening a KieSession bean, which can be retrieved from KieContainer.package com.techgeeknext.examples.drools.controller;
import com.techgeeknext.examples.drools.domain.FDRequest;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class FixedDepositRateController {
private final KieContainer kieContainer;
public FixedDepositRateController(KieContainer kieContainer) {
this.kieContainer = kieContainer;
}
@RequestMapping(value = "/getFDInterestRate", method = RequestMethod.GET, produces = "application/json")
public FDRequest getQuestions(@RequestParam(required = true) String bank, @RequestParam(required = true) Integer durationInYear) {
KieSession kieSession = kieContainer.newKieSession();
FDRequest fdRequest = new FDRequest(bank,durationInYear);
kieSession.insert(fdRequest);
kieSession.fireAllRules();
kieSession.dispose();
return fdRequest;
}
}
Implementing Rules using Decision Table
Drools Rule File (FDInterestRate.xls)
The Drools rule file kept under resources/rules folder, contains all business rules.
This FDInterestRate.xls spreadsheet execute all rule based on the condition given.
Testing Drools Rules
Now, run the application and verify drools decision table rules.
- Open the browser and go to http://localhost:8080/getFDInterestRate?bank=Citi&durationInYear=1 url, which will evaluate first rule that we have specified in the drools FDInterestRate.xls file.
- Now, will evaluate second rule, go to http://localhost:8080/getFDInterestRate?bank=Citi&durationInYear=2 url.
- And as per third rule, pass the parameter as given in this link http://localhost:8080/getFDInterestRate?bank=JP&durationInYear=2.
Download Source Code
The full source code for this article can be found on below.Download it here - Spring Boot + Drools Decision Table Example