Spring Boot + Drools Example
Overview
In this article, we'll explore how to integrate Spring Boot with Drools.
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
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 and drools-compiler 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-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>drools-demo</name>
<description>Demo project for Drools Spring Boot</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-compiler</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</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
CreateFDRequest.java
as below to map the object from drl 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 run rules on a set of data, we have to initialize the framework's classes with details about the
rule files (FDInterestRate.drl)
location and the Facts.
We need to initialize the KieFileSystem
bean (in-memory file
system). The following code offers a container for programmatically defining Drools resources such
as rules files and decision tables.
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("FDInterestRate.drl"));
KieBuilder kb = kieServices.newKieBuilder(kieFileSystem);
kb.buildAll();
KieModule kieModule = kb.getKieModule();
return kieServices.newKieContainer(kieModule.getReleaseId());
}
}
KieBuilder's buildAll()
method creates all of the resources and connects them to
KieBase. It only
succeeds when it is able to locate and validate all of the rule files.
We must first create the KieContainer
, which serves as a container for all of the KieBases
for a
certain KieModule
. Various beans, such as KieFileSystem, KieModule, and
KieBuilder
are used to
construct KieContainer
.
Controller
Now, write a controller that takes Fixed Deposit parameters as an input and evaluates the rule entries.
KieSession
Open aKieSession
bean which may be retrieved from
KieContainer
to execute the rules.
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
Drools Rule File (.drl)
DRL (Drools Rule Language) rules are business rules that are written in.drl text files. A DRL file can have one or more rules that determine the rule conditions (when) and actions at a minimum (then).
import com.techgeeknext.examples.drools.domain.FDRequest;
rule "FD Interest Rate for Citi Bank duration more than 1 year and below 2 years"
when
fdObject : FDRequest( bankName=="Citi" && durationInYear >= 1 && durationInYear < 2);
then
fdObject.setFdInterestRate("3%");
end;
rule "FD Interest Rate for Citi Bank for duration more than or equal to 2 years"
when
fdObject : FDRequest( bankName=="Citi" && durationInYear >= 2);
then
fdObject.setFdInterestRate("6%");
end;
rule "FD Interest Rate for JP Bank for duration more than or equal to 1 year"
when
fdObject : FDRequest( bankName=="JP" && durationInYear >= 1);
then
fdObject.setFdInterestRate("3%");
end;
Testing Drools Rules
Now, run the application and verify drools 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 rule .drl 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 integration with Drools Example