Introduction to Drools Rule Engine – DRL File


This is a complete tutorial for beginners on developing a Java project using Spring Boot, and Drools Rule Engine (DRL file) from scratch. This tutorial will help you understand basic concepts, configurations, tools required, and coding to execute a simple API application.

The Drools rule engine stores, processes, and evaluates data to execute the business rules or decision models that you define. The basic function of the Drools rule engine is to match incoming data, or facts, to the conditions of rules and determine whether and how to execute the rules.

https://www.drools.org/

KIE (Knowledge Is Everything) is an umbrella project introduced to bring all the related technologies together under one roof, and Drools is one among them.

In Drools, a KIE session stores and executes runtime data. The KIE session is created from a KIE base or directly from a KIE container.


1. Open VS Code

  • CTRL + SHIFT + p OR Type ‘>’ in the Search bar — Spring Initializr: Create a Maven project
  • Specify Spring Boot version — 3.2.2
  • Specify project language — Java
  • Group Id — com.drools
  • Artifact Id — drools-poc
  • Specify packaging type — Jar
  • Specify Java version — 17
  • Dependencies —
    • Spring Web
    • Lombok
  • Specify a folder to generate the boilerplate project with dependencies injected

2. Update pom.xml with Drools dependencies

<properties>
	<drools.version>8.44.0.Final</drools.version>
</properties>
<dependency>
	<groupId>org.drools</groupId>
	<artifactId>drools-mvel</artifactId>
	<version>${drools.version}</version>
</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>

3. Create folders as highlighted

4. Create OrderRequest.java model under the Model folder

package com.drools.droolspoc.Model;

public class OrderRequest {
    
    private String customerNumber;
    private Integer age;
    private Integer amount;
    private CustomerType customerType;

    public String getCustomerNumber() {
        return this.customerNumber;
    }

    public void setCustomerNumber(String customerNumber) {
        this.customerNumber = customerNumber;
    }

    public Integer getAge() {
        return this.age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getAmount() {
        return this.amount;
    }

    public void setAmount(Integer amount) {
        this.amount = amount;
    }

    public CustomerType getCustomerType() {
        return this.customerType;
    }

    public void setCustomerType(CustomerType customerType) {
        this.customerType = customerType;
    }

    @Override
    public String toString() {
        return "{" +
            " customerNumber='" + getCustomerNumber() + "'" +
            ", age='" + getAge() + "'" +
            ", amount='" + getAmount() + "'" +
            ", customerType='" + getCustomerType() + "'" +
            "}";
    }
}

5. Create CustomerType.java model under the Model folder

package com.drools.droolspoc.Model;

public enum CustomerType {
    LOYAL, NEW, DISSATISFIED;

    public String getValue() {
        return this.toString();
    }
}

6. Create OrderDiscount.java model under the Model folder

package com.drools.droolspoc.Model;

public class OrderDiscount {
    
    private int discount;

    public int getDiscount() {
        return this.discount;
    }

    public void setDiscount(int discount) {
        this.discount = discount;
    }

    @Override
    public String toString() {
        return "{" +
            " discount='" + getDiscount() + "'" +
            "}";
    }
}

7. Create discount-rules.drl under resources/rules folder

Drools Rule Language (DRL) is a notation established by the Drools open source business automation project for defining and describing business rules. DRL rules are defined in .drl text files. A DRL file can contain one or more rules that define at a minimum the rule conditions (when) and actions (then).

https://docs.drools.org/8.39.0.Final/drools-docs/docs-website/drools/language-reference/index.html
import com.drools.droolspoc.Model.OrderRequest;
import com.drools.droolspoc.Model.CustomerType;
global com.drools.droolspoc.Model.OrderDiscount orderDiscount;

rule "Age based discount"
    when
        OrderRequest(age < 20 || age > 50)
    then
        System.out.println("==========Adding 10% discount for Kids/ senior customer=============");
        orderDiscount.setDiscount(orderDiscount.getDiscount() + 10);
end

rule "Customer type based discount - Loyal customer"
    when
        OrderRequest(customerType.getValue == "LOYAL")
    then
        System.out.println("==========Adding 5% discount for LOYAL customer=============");
        orderDiscount.setDiscount(orderDiscount.getDiscount() + 5);
end

rule "Customer type based discount - others"
    when
        OrderRequest(customerType.getValue != "LOYAL")
    then
        System.out.println("==========Adding 3% discount for NEW or DISSATISFIED customer=============");
        orderDiscount.setDiscount(orderDiscount.getDiscount() + 3);
end

rule "Amount based discount"
    when
        OrderRequest(amount > 1000)
    then
        System.out.println("==========Adding 5% discount for amount more than 1000$=============");
        orderDiscount.setDiscount(orderDiscount.getDiscount() + 5);
end

8. Create DroolsConfig.java under Config folder

KieContainer and KieModule are a little harder to differentiate, but they’re basically the same thing in practice (container being the runtime implementation, module being the specification.)

The KieServices is a thread-safe singleton acting as a hub giving access to the other Services provided by Kie.

KieBuilder is a builder for the resources contained in a KieModule. KieBuilder. buildAll() builds all the KieBases contained in the KieModule for which this KieBuilder has been created.

package com.drools.droolspoc.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 DroolsConfig {
    
    private static final String drl_file_path = "rules/discount-rules.drl";

    private static final KieServices kieServices = KieServices.Factory.get();

    @Bean
    public KieContainer kieContainer() {
        KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
        kieFileSystem.write(ResourceFactory.newClassPathResource(drl_file_path));
        KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
        kieBuilder.buildAll();
        KieModule kieModule = kieBuilder.getKieModule();
        KieContainer kieContainer = kieServices.newKieContainer(kieModule.getReleaseId());
        return kieContainer;
    }
}

9. Create DroolsController.java under the Controller folder

package com.drools.droolspoc.Controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.drools.droolspoc.Model.OrderDiscount;
import com.drools.droolspoc.Model.OrderRequest;
import com.drools.droolspoc.Service.DroolsService;

@RestController
@RequestMapping("api/v1/drools")
public class DroolsController {
    
    @Autowired
    private DroolsService droolsService;

    @PostMapping(path = "/getOrderDiscount")
    public OrderDiscount getOrderDiscount(@RequestBody OrderRequest orderRequest){
        return droolsService.getOrderDiscount(orderRequest);
    }
}

10. Create DroolsService.java under the Service folder

package com.drools.droolspoc.Service;

import com.drools.droolspoc.Model.OrderDiscount;
import com.drools.droolspoc.Model.OrderRequest;

public interface DroolsService {
    
    OrderDiscount getOrderDiscount(OrderRequest orderRequest);
}

11. Create DroolsServiceImpl.java under the ServiceImpl folder

package com.drools.droolspoc.ServiceImpl;

import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.drools.droolspoc.Model.OrderDiscount;
import com.drools.droolspoc.Model.OrderRequest;
import com.drools.droolspoc.Service.DroolsService;

@Service
public class DroolsServiceImpl implements DroolsService{

    @Autowired
    private KieContainer kieContainer;

    @Override
    public OrderDiscount getOrderDiscount(OrderRequest orderRequest) {
        OrderDiscount orderDiscount = new OrderDiscount();
        KieSession kieSession = kieContainer.newKieSession();
        kieSession.setGlobal("orderDiscount", orderDiscount);
        kieSession.insert(orderRequest);
        kieSession.fireAllRules();
        kieSession.dispose();
        return orderDiscount;
    }
}

12. Run the project in VS Code

13. Open SoapUI

The reason behind the discount: 20 –


Thus, we come to the end of the project using Spring Boot, and Drools Rule Engine😊

Thank you for reading! I hope you’re able to understand and proceed with the development of this explanation and if so, please share to help others too. 😊

Well, there are a lot of areas for improvement in this project and, for any new suggestions or comments, I’m all ears.

Download project from: https://github.com/sharuroy16/drools-poc

Leave a Comment

Your email address will not be published. Required fields are marked *