Core Java

How to Find Matched Rules in Drools

In Drools-based applications, it is often necessary to know which rules were executed for a given set of facts. This is useful for auditing, debugging, and explaining business decisions. Let us delve into understanding how to retrieve the list of matched rules during Drools rule execution.

1. Introduction to Drools

Drools is a powerful open-source Business Rule Management System (BRMS) written in Java that enables developers to separate business logic from application code. Instead of hardcoding complex if–else conditions, Drools allows rules to be defined declaratively using a rule language (DRL), making the system easier to maintain, extend, and understand.

At its core, Drools uses a forward-chaining inference engine to evaluate facts against a set of rules and determine which rules should be executed. During runtime, multiple rules may match the same set of facts, making it important to track and understand which rules were actually triggered. This capability is especially useful for debugging, auditing, and explaining business decisions in rule-driven applications.

2. Code Example

2.1 Maven Dependency

The following Maven dependencies are required to set up Drools in a Java application.

<dependencies>
    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-core</artifactId>
        <version>stable__jar__version</version>
    </dependency>
    <dependency>
        <groupId>org.drools</groupId>
        <artifactId>drools-compiler</artifactId>
        <version>stable__jar__version</version>
    </dependency>
    <dependency>
        <groupId>org.kie</groupId>
        <artifactId>kie-api</artifactId>
        <version>stable__jar__version</version>
    </dependency>
</dependencies>

The drools-core dependency provides the core rule engine and runtime execution capabilities, while drools-compiler is responsible for parsing and compiling DRL (rule) files into executable rule packages. The kie-api dependency supplies the public APIs required to create and manage KIE services such as KieContainer and KieSession, which are essential for loading rules and firing them at runtime.

2.2 Domain Model

The following domain model represents the business data evaluated by Drools rules.

package com.example.model;

public class Customer {

    private String type;
    private int age;
    private double purchaseAmount;

    public Customer(String type, int age, double purchaseAmount) {
        this.type = type;
        this.age = age;
        this.purchaseAmount = purchaseAmount;
    }

    public String getType() {
        return type;
    }

    public int getAge() {
        return age;
    }

    public double getPurchaseAmount() {
        return purchaseAmount;
    }
}

The Customer class acts as a fact in the Drools working memory and encapsulates key attributes such as customer type, age, and purchase amount, which are used by rules to evaluate conditions and determine eligibility for discounts. Getter methods expose these properties to the Drools engine, allowing rule constraints to match facts efficiently without modifying the domain object during rule execution.

2.3 Drools Rule File (customer-rules.drl)

The following DRL file defines business rules that evaluate customer attributes to apply discounts.

package rules

import com.example.model.Customer

rule "Gold Customer Discount"
when
    Customer(type == "GOLD", purchaseAmount > 5000)
then
    System.out.println("Gold discount applied");
end

rule "Senior Citizen Discount"
when
    Customer(age >= 60)
then
    System.out.println("Senior citizen discount applied");
end

rule "High Value Purchase Discount"
when
    Customer(purchaseAmount > 10000)
then
    System.out.println("High value purchase discount applied");
end

Each rule in this DRL file follows the when-then pattern, where the when section specifies conditions that must be satisfied by a Customer fact in the working memory, and the then section defines the action executed when the rule fires. Multiple rules can match the same fact simultaneously, allowing Drools to evaluate and execute all applicable business policies such as customer type-based, age-based, and purchase amount-based discounts during a single rule execution cycle.

2.4 Java Code

The following Java code executes Drools rules and captures the list of matched rules at runtime.

package com.example;

import com.example.model.Customer;
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.api.event.rule.*;

import java.util.ArrayList;
import java.util.List;

public class DroolsMatchedRulesExample {

    public static void main(String[] args) {

        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieContainer.newKieSession();

        List<String> firedRules = new ArrayList<>();

        kieSession.addEventListener(new AgendaEventListener() {

            @Override
            public void afterMatchFired(AfterMatchFiredEvent event) {
                firedRules.add(event.getMatch().getRule().getName());
            }

            @Override public void matchCreated(MatchCreatedEvent event) {}
            @Override public void matchCancelled(MatchCancelledEvent event) {}
            @Override public void beforeMatchFired(BeforeMatchFiredEvent event) {}
            @Override public void agendaGroupPushed(AgendaGroupPushedEvent event) {}
            @Override public void agendaGroupPopped(AgendaGroupPoppedEvent event) {}
        });

        Customer customer = new Customer("GOLD", 65, 12000);
        kieSession.insert(customer);

        kieSession.fireAllRules();
        kieSession.dispose();

        System.out.println("Fired Rules: " + firedRules);
    }
}

This program initializes a KieSession to load Drools rules from the classpath and registers an AgendaEventListener to intercept rule execution events, specifically capturing rule names after they are fired. A Customer fact is inserted into the working memory, causing multiple rules to match and execute based on its attributes, while the listener collects all fired rule names into a list that is printed after rule execution completes.

2.5 Code Run and Output

When the application is executed, the inserted customer fact satisfies multiple rule conditions.

Gold discount applied
Senior citizen discount applied
High value purchase discount applied
Fired Rules: [Gold Customer Discount, Senior Citizen Discount, High Value Purchase Discount]

The output confirms that all applicable rules were successfully matched and fired for the given customer data, with each rule printing its execution message to the console. The final line displays the collected list of fired rule names, demonstrating how Drools can be used to track and audit rule execution in a single rule evaluation cycle.

3. Conclusion

We explored how to identify matched rules during Drools rule execution using a practical, end-to-end example. By leveraging AgendaEventListener, applications can track which rules were fired without modifying existing rule definitions, making this approach clean, maintainable, and production-friendly. Understanding how to capture matched rules improves debugging, auditing, and transparency in rule-driven systems, and is a recommended best practice when working with Drools in real-world enterprise applications.

Yatin Batra

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Back to top button