DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • The Battle of Data: Statistics vs Machine Learning
  • Demystifying Cloud Trends: Statistics and Strategies for Robust Security
  • SAS: Telling a Story With Data
  • Fun Statistics About JDK 20

Trending

  • Navigating Change Management: A Guide for Engineers
  • How to Introduce a New API Quickly Using Micronaut
  • Memory-Optimized Tables: Implementation Strategies for SQL Server
  • Simpler Data Transfer Objects With Java Records
  1. DZone
  2. Data Engineering
  3. Data
  4. Learn Drools (Part 6): Rules and Statistics

Learn Drools (Part 6): Rules and Statistics

So, you've got your Drools system running, but then you run into a bug. Fortunately, you can track your facts and rules with Java and Drools to see where it went wrong.

By 
Shamik Mitra user avatar
Shamik Mitra
·
Dec. 12, 16 · Tutorial
Likes (6)
Comment
Save
Tweet
Share
17.3K Views

Join the DZone community and get the full member experience.

Join For Free

In this article, we will learn how to find a few important statistics for backtracking. Consider a complex system where you have a lot of Drools rules present and firing on a huge number of facts. In that setup, you're going to see facts matched with a lot of rules. So:

  1. How many rules are fired for given fact?

  2. Which rules are activated?

Say for a live system that a bug has been raised for a few particular facts. Say you have an employee whose designation is Manager in the system but hasn't received a laptop, as per our original setup?

How can we analyze this bug?

We can replicate the same scenario in the dev environment and debug the Drools rules to check where it fails.

This is OK, but it's time-consuming. A developer should work on better stuff than this. So, if we maintain statistics on which rules are fired for each fact and show this is in a UI, then we can easily search for the given facts and see where it fails.

I will try to write a primer program to track these statistics. Of course, you can enhance this program according to your needs and fit it into your module with advanced capabilities. But I just want to show you how it could be done.

In Drools, there are two Listener interfaces:

  • WorkingMemoryEventListener

  • AgendaEventListener

Using these two interfaces, we can find different statistical information like:

  • When an object/fact is created, updated, or retracted by WorkingMemoryEventListener.

  • Before or after rule activation by AgendaEventListener.

Here, we will use AgendaEventListener and track which rules are activated or fired for a fact — then print them.

Drools uses skeletal implementation, so it has a class called DefaultAgendaEventListener, which provides the default implementation (left blank) of all methods defined in the AgendaEventListener interface.

So we will create our own Listener, which extends DefaultAgendaEventListener and overrides the afterActivationFired method.

Then, we'll register this listener in working memory so that whenever facts are compared with rules, this can be triggered.

Step 1: Creating the Listener

package com.example.drools.listener;


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


import org.drools.core.WorkingMemory;
import org.drools.core.event.AfterActivationFiredEvent;
import org.drools.core.event.DefaultAgendaEventListener;
import org.drools.core.rule.Rule;






public class TrackingRuleFiredEventListener extends DefaultAgendaEventListener{


private List<String> activationList = new ArrayList<String>();


@Override
public void afterActivationFired(AfterActivationFiredEvent event,final WorkingMemory workingMemory) {
    Rule rule = event.getActivation().getRule();
    String ruleName = rule.getName();
    activationList.add(ruleName);
    System.out.println("Rule fired: " + ruleName);
}


public boolean isRuleFired(String ruleName) {
    for (String rule : activationList) {
        if (ruleName.equalsIgnoreCase(rule)) {
            return true;
        }
    }
    return false;
}


public void reset() {
    activationList.clear();
}


public final List<String> getActivationList() {
    return activationList;
} 


}


Step 2: The Drools File (employeeTruthTable.drl)

package com.rules


import com.example.droolsExample.pojo.Employee
import com.example.droolsExample.pojo.Department
import com.example.droolsExample.pojo.ITManager
import com.example.droolsExample.pojo.ITEmployee


rule "IT Manager Inference1"
    when
    $dept: Department(name=="IT");
    $emp: Employee(dept == $dept,manager==true);
    then
    insertLogical(new ITManager($emp));
end
rule "IT Employee Inference1"
    when
    $dept: Department(name=="IT");
    $emp: Employee(dept == $dept,manager==false);
    then
    insertLogical(new ITEmployee($emp));
end
rule "give Manager Laptop"
    when
    $emp: Employee();
    $itManager: ITManager(emp == $emp);

    then
    $emp.setMessage("Give Laptop");
    System.out.println($emp.getName()+ ": "+$emp.getDept().getName()+ ":"+$emp.getMessage());
end
rule "give Employee Desktop"
    when
    $emp: Employee();
    $itEmployee: ITEmployee(emp == $emp);

    then
    $emp.setMessage("Give Desktop");
    System.out.println($emp.getName()+ ": "+$emp.getDept().getName()+ ":"+$emp.getMessage());    
end


Step 3: Create Domain Objects

Employee.java

package com.example.droolsExample.pojo;


public class Employee {

    String name;
    boolean manager;
    String message;
    Department dept;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public boolean isManager() {
        return manager;
    }
    public void setManager(boolean manager) {
        this.manager = manager;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public Department getDept() {
        return dept;
    }
    public void setDept(Department dept) {
        this.dept = dept;
    }
    @Override
    public String toString() {
        return "Employee [name=" + name + ", manager=" + manager + ", message="
        + message + ", dept=" + dept + "]";
    }    
}


Department.java

package com.example.droolsExample.pojo;


public class Department {

    String name;


    public String getName() {
    return name;
    }


    public void setName(String name) {
    this.name = name;
    }   


}


ITManager.java

package com.example.droolsExample.pojo;

public class ITManager {

        private Employee emp;
        public ITManager(Employee emp)
    {
        this.emp=emp;
    }

    public Employee getEmp() {
        return emp;
    }

    public void setEmp(Employee emp) {
        this.emp = emp;
    } 

}


ITEmployee.java

package com.example.droolsExample.pojo;


public class ITEmployee {

    private Employee emp;
    public ITEmployee(Employee emp)
    {
    this.emp=emp;
    }



    public Employee getEmp() {
    return emp;
    }


    public void setEmp(Employee emp) {
    this.emp = emp;
    }


}


Step 4: Registering the Listener

DroolTest.java

package com.example.droolsExample;


import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.List;


import org.drools.compiler.compiler.DroolsParserException;
import org.drools.compiler.compiler.PackageBuilder;
import org.drools.core.RuleBase;
import org.drools.core.RuleBaseFactory;
import org.drools.core.WorkingMemory;
import org.drools.core.event.AgendaEventListener;
import com.example.drools.listener.TrackingRuleFiredEventListener;
import com.example.droolsExample.pojo.Department;
import com.example.droolsExample.pojo.Employee;






public class DroolsTest {


    public static void main(String[] args) throws DroolsParserException,
    IOException {
        DroolsTest droolsTest = new DroolsTest();
        //droolsTest.executeDrools();
        droolsTest.executeDroolsEmployee("/com/rules/employeeTruthTable.drl");
    }


    public void executeDroolsEmployee(String ruleFile) throws DroolsParserException, IOException {


        PackageBuilder packageBuilder = new PackageBuilder();
        InputStream resourceAsStream = getClass().getResourceAsStream(ruleFile);
        Reader reader = new InputStreamReader(resourceAsStream);
        packageBuilder.addPackageFromDrl(reader);
        org.drools.core.rule.Package rulesPackage = packageBuilder.getPackage();
        RuleBase ruleBase = RuleBaseFactory.newRuleBase();
        ruleBase.addPackage(rulesPackage);


        WorkingMemory workingMemory = ruleBase.newStatefulSession();
        AgendaEventListener employeeRuleTracktListener = new TrackingRuleFiredEventListener();
        workingMemory.addEventListener(employeeRuleTracktListener);

        Department dep = new Department();
        dep.setName("Civil");

        Department dep1 = new Department();
        dep1.setName("IT");

        Employee emp = new Employee();
        emp.setName("Shamik Mitra");
        emp.setManager(true);
        emp.setDept(dep1);

        Employee emp2 = new Employee();
        emp2.setName("Swastika Mitra");
        emp2.setManager(false);
        emp2.setDept(dep1);

        Employee emp1 = new Employee();
        emp1.setName("Samir Mitra");
        emp1.setManager(true);
        emp1.setDept(dep);

        workingMemory.insert(dep);
        workingMemory.insert(dep1);
        workingMemory.insert(emp);
        workingMemory.insert(emp1);
        workingMemory.insert(emp2);
        workingMemory.fireAllRules();
        System.out.println("===================================");
        System.out.println("No of Activated Rule for all facts");
        System.out.println("===================================");
        List<String> activations = ((TrackingRuleFiredEventListener)employeeRuleTracktListener).getActivationList();
        for(String rule : activations)
        {
            System.out.println(rule);
        }

    }
}

Step 5: Output

Rule fired: IT Manager Inference1
Rule fired: IT Employee Inference1
Shamik Mitra: IT:Give Laptop
Rule fired: give Manager Laptop
Swastika Mitra: IT:Give Desktop
Rule fired: give Employee Desktop
===================================
No of Activated Rule for all facts
===================================
IT Manager Inference1
IT Employee Inference1
give Manager Laptop
give Employee Desktop


And here's your data of the rules that were fired and the facts involved.

Drools Statistics

Published at DZone with permission of Shamik Mitra, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • The Battle of Data: Statistics vs Machine Learning
  • Demystifying Cloud Trends: Statistics and Strategies for Robust Security
  • SAS: Telling a Story With Data
  • Fun Statistics About JDK 20

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!