Using the Drools Guvnor Repository to store your Rules

Guvnor is the business rules manager included with Drools to manage knowledge and to be a centralized repository for Drools knowledge bases. In this tutorial we will show how to upload and use some rules in its repository.

In order to get started you need at first to install the Guvnor repository into JBoss AS as shown in this tutorial. Once installed start the guvnor by opening your browser to http://localhost:8080/drools-guvnor/
Now in order to create some rules into our repository we will need to perform the following steps:

Create a package for your Model classes

From your Knowledge Bases left menu choose to Create New > Package and enter a name for it.

Upload your Model classes

Let’s compile and package the following class which will be used into our Rule. Package it in a file named Account.jar

package com.sample.model;
public class Account {
    private Integer balance;

    public Account() {}
    public Integer getBalance() {
        return balance;
    }
    public void setBalance(Integer balance) {
        this.balance = balance;
    }
    public Account(Integer balance) {
        super();
        this.balance = balance;
    }
    public void withdraw(int money) {
        balance -= money;
    }
}

Uploading your Facts requires at first selecting Create New > Upload POJO Model


From there enter your Model Name and select the package you have just created. In the next screen of the Wizard pickup the JAR file with the Model.

 

Note: If you don’t want to upload your Model, it is also possible to define your Model class by using the Declarative Model editor which will let you create your facts from the Class fields.

Create your Rules

Now it’s time to insert your first Rule into your Guvnor repository. From the left Menu select Create New > Rule.

In the next screen you can opt for the Business Rule (guided editor) or, if you already have coded your rule, just use the Technical editor and enter the following rule:

import com.sample.model.Account
rule "accountBalanceAtLeast"
  when
  $account : Account( balance < 100 )
  then
  System.out.println("Warning! money running out!");
end

Once you have a stable knowledge you can create a deployment snapshots which freezes the knowledge for when you need it, saving a state of the knowledge that cannot be modified. Of course, you can still modify the knowledge through the Knowledge Bases, but any change will not be reflected in the snapshots.

Select the Package from the Left and enter in the Edit Tab. From there at first build the binary package by clicking on the Build package button. Building a package will collect all the assets, validate and compile into a deployable package.

Next create a snapshot for deployment. Once you have clicked on the button, a pop-up, New snapshot, will appear on the screen. Select a package to generate a snapshot. Now from the Edit Menu, copy the URL location of your package source

The source will be used in the following Test class which loads the accountBalanceAtLeast from the Guvnor Repository:

public class GuvnorTest  {
    @Test
    public void testDroolsWithGuvnor() throws Exception {
        KnowledgeBase knowledgeBase = createKnowledgeBase();
        StatefulKnowledgeSession session = knowledgeBase.newStatefulKnowledgeSession();
        try {
            Account account = new Account();
            account.setBalance(10);
            session.insert(account);

            session.fireAllRules();

        }
        finally {
            session.dispose();
        }
    }

    private static KnowledgeBase createKnowledgeBase() {
        KnowledgeAgentConfiguration kaconf = KnowledgeAgentFactory.newKnowledgeAgentConfiguration();
        kaconf.setProperty( "drools.agent.scanDirectories", "false" );
        KnowledgeAgent kagent = KnowledgeAgentFactory.newKnowledgeAgent( "test agent", kaconf );
        kagent.applyChangeSet( ResourceFactory.newClassPathResource("guvnor-jboss.xml"));
        return kagent.getKnowledgeBase();
    }
}

And here’s the guvnor-jboss.xml file which contains the resource path and the basic authentication info:

<change-set xmlns='http://drools.org/drools-5.0/change-set'
    xmlns:xs='http://www.w3.org/2001/XMLSchema-instance'
    xs:schemaLocation='http://drools.org/drools-5.0/change-set
    http://anonsvn.jboss.org/repos/labs/labs/jbossrules/trunk/drools-api/src/main/resources/change-set-1.0.0.xsd' >
   <add>
      <resource
      source='http://localhost:8080/drools-guvnor/rest/packages/com.sample.model/source'
      type='DRL' basicAuthentication="enabled" username="admin" password="admin" />
   </add>
</change-set>

That’s all ! Enjoy coding your Rules into the Guvnor Repository.

Instant Drools Starter book review

Today I’ve gone through the Drools Instant starter book and I’ll add a short review of it. 

This pocket book has been created to provide you with all the information that you need to get started with Drools. You can read it in one day
and at the end you will learn the basics of Drools, get started with building your first rule system, and learn some core functions and helpful tips and tricks when it comes to using Drools in your applications. Basically the book is made up of just 52 pages and well divided into the following sections:

1) What is Drools? this will tell you what Drools actually is, what a Business Rule Management System such as Drools can do for you, when you should and shouldn’t choose a rule engine, and why Drools is a great choice.

2) Installation will teach you how to integrate Drools into a new or existing Java project with minimum hassle in order to get you writing and evaluating rules as soon as possible.

3) Quick start will kick start you with Drools Expert and your simple rule file using the Drools Rule Language.

4) Top 5 features you need to know about: this will teach the essentials for reading and writing basic rules in Drools Rule Language syntax, work with facts (objects fed to the rule engine), test your rules and debug the rule evaluation process

5) People and places you should get to know: provides many useful links to project documentation and mailing lists, as well as a number of helpful articles, tutorials, blogs, and the Twitter feeds of Drools.

This book is an extremely enjoyable reading at a convenient price (7.99€) which leaves me wishing to learn more about this great Rules engine. I’ll be glad to share with my readers all my on-going progress in this area

 

 

 

 

 

 

How to create time based rules

In this tutorial we will learn how to create time based rules using Drools rules engine. When combined with a timer, a Drools rule can be an useful option, to monitor some attributes and perform some actions accordingly. 

Let’s see at first an example of Drools rules  which can be activated on a timer configuration:

rule "Send SMS every 15 minutes"
    timer (cron:* 0/15 * * * ?)
when
    $a : Alarm( on == true )
then
    channels[ "sms" ].insert( new Sms( $a.mobileNumber, "The alarm is still on" );
end

As you can see the timer configuration is equivalent to the well-known cron expression and will re-evaluate the  this rule every 15 minutes. Now let’s build an example application which will show how you can monitor an attribute (f.e. the amount of memory of a Server) using a Drool rule,

The following rule, will be evaluated every 5 seconds and will monitor the “memory” attribute of the Server fact. If the value drops below a certain amount (f.e. 1000 MB) a warning is printed, and the event is added to the “global” Event class:


package com.sample
import java.util.Date
import java.util.List
import com.sample.app.Server

global com.sample.app.Event event


rule "Server memory"
dialect "mvel"
timer (cron:0/5 * * * * ?)


when
$server : Server(memory < 1000)
then
System.out.println("Warning low memory detected!");
event.add(new java.util.Date() + " - WARNING: Server " + $server.name + " has low memory " + $server.memory);


end

And hereâ€s the JUnit test class which is going to execute this rule:


package com.sample.app;

import java.util.Date;

import org.drools.KnowledgeBase;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.impl.ClassPathResource;
import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.rule.FactHandle;
import org.junit.Test;
 
public class DBRulesTest {

    private FactHandle serverHandle;

    @Test
    public void memoryTest() throws InterruptedException {

        final StatefulKnowledgeSession ksession = createKnowledgeSession();
        Event myevent = new Event();
        ksession.setGlobal("event", myevent);

        final Server node1 = new Server(1500,"server1");
         

        new Thread(new Runnable() {
            public void run() {
                ksession.fireUntilHalt();
            }
        }).start();

        serverHandle = ksession.insert(node1);
        
        int memory = 1500;
        for (int i=0;i<5;i++){
            Thread.sleep(6000);
            memory = memory - 200;
       
            node1.setMemory(memory);
            ksession.update(serverHandle, node1);
            
        }

        ksession.halt();
        System.out.println(myevent.getEvents());
    }

    private StatefulKnowledgeSession createKnowledgeSession() {
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        kbuilder.add(new ClassPathResource("myrule.drl", getClass()), ResourceType.DRL);

        if (kbuilder.hasErrors()) {
            if (kbuilder.getErrors().size() > 0) {
                for (KnowledgeBuilderError kerror : kbuilder.getErrors()) {
                    System.err.println(kerror);
                }
            }
        }

        KnowledgeBase kbase = kbuilder.newKnowledgeBase();
        StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
        return ksession;
    }

}

As you can see, this example uses the org.drools.runtime.StatefulKnowledgeSession which is the main interface for interacting with the Drools engine. It has methods for inserting, updating, and retracting facts. StatefulKnowledgeSession is also used to set the session’s global variables. Probably, the most interesting part of its API is the fireAllRules method, which is used to execute all rules. In our example, since we want to complete the cron timer’s functionality, it is necessary to maintain the working memory continually checking if there are activations created to automatically fire them. To implement it we have used the fireUntilHalt() method, which will keep firing the activations created until none remains in the agenda.

Hereâ€s the expected output on the console, which should be triggered, once the memory of the server is set to a value under 1000:

Warning low memory detected!
Warning low memory detected!
Warning low memory detected!

And hereâ€s what has been recorded into the Event class:
[Wed May 01 22:36:15 CEST 2013> WARNING: Server server1 has low memory 900, Wed May 01 22:36:20 CEST 2013> WARNING: Server server1 has low memory 900, Wed May 01 22:36:25 CEST 2013> WARNING: Server server1 has low memory 700]

The Event class contains barely a static ArrayList where we record events:


package com.sample.app;

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

public class Event {

    static List<String> events = new ArrayList();

    public static List<String> getEvents() {
        return events;
    }

    public static void add(String log) {
        events.add(log);
    }
}

What is a rule engine ?

What is a rule engine ?

A rule engine is a piece of software that executes rules according to some algorithm. A rule engine combines a set of facts that are inserted in to the system with its own Rule Set to reach a conclusion of triggering one or several actions. These rules typically describe in a declarative manner the business logic which needs to be implemented in our environment (which we assume rarely changes). The facts, on the other had, describe the conditions of the system that is to be operated on; they may change frequently.

Logic, or rules in our case, are pieces of knowledge often expressed as, “When some conditions are evaluated to true, then do some tasks“.

A system with a large number of rules and facts may result in many rules being true for the same facts; in this case, we say that rules are said to be in conflict. A rule engine can use different conflict resolver strategies to determine the order of execution of the conflict rules.  In a rule engine, there are two execution methods:

  • Forward Chaining: is a “data-driven” method. Upon facts being inserted or updated, the rule engine uses available facts and inference rules to extract more facts until a goal is reached, where one or more matching rules will be concurrently true and scheduled for execution. Hence the rule engine starts with facts and ends with conclusion.
  • Backward chaining is a “goal-driven” or inference method, which is reversed with forward chaining. Backward chaining starts with a conclusion or a list of goals that the engine tries to satisfy. If it cannot satisfy these goals, then it searches for sub-goals that it can satisfy that will help satisfy some part of the current goals. The engine continues this process until either the initial conclusion is proven or there are no more sub-goa

What is the difference between a Rule engine and a process?

A rule differs from a process mainly because:

A business processes represent what the business does
A business rules represent decisions that the business does

A rule engine may be viewed as a sophisticated if/then statement interpreter. The if/then statements that are interpreted are called rules.

The if portions of rules contain conditions such as account.getMoney() < 0. The then portions of rules contain actions such as sendWarning(account).

if (account.getMoney() < 0)
sendWarning(account);

The inputs to a rule engine are a rule execution set and some data objects. The outputs from a rule engine are determined by the inputs and may include the original input data objects with possible modifications, new data objects, and side effects such as sendMail(‘Thank you for shopping’).


Rules are stored in a forward-chaining rule engine, i.e. the engine implements an execution cycle that allows the action of one rule to cause the condition of other rules to become met. In this way, a cascade of rules may become activated and each rule action executed. Forward-chaining rule engines are suitable for problems that require drawing higher-level conclusions from simple input facts.

So, here’s how you could rewrite the above check as a rule:

global AccountManager manager;

rule "checkMoney"
when
$account : Account( money < 0 )
then
  manager.warn($account);
end

As you can see, a Rule file is based on two basic concepts:
Rules: declarative statements that govern the conduct of business processes. A rule consists of a condition and actions. The condition is evaluated, and if it evaluates to true, the rule engine initiates one or more actions.

Facts: are the data upon which rules operate. In our example, the available money are facts.

Advantages of Rule Engines

Turning to rules adds a set of advantages to your applications:

Greater flexibility: keeping your rules into a Knowledge base let you adapt easily your decisions when they are changing.

Easier to grasp: Rules are easier to understand than procedural code so they can be effectively used to bridge the gap between business analyst and developers.

Reduced complexity: When embedding lots of decision points to your procedural codes it can easily turn your application into a nightmare. On the other hand rules can handle much better increasing complexity because they use a consistent representation of business rules.

Reusability: By keeping rules are kept in one place leads to a greater reusability of your business rules. Also, traditional procedural code often impose unnecessary variations of base rules which are therefore more difficult to reuse in other contexts.

On the other hand, using a rule engine might prove to be unnecessary if your business logic is static and the number of business rules are pretty simple and limited in number. 

Open source rule engines

The Drools engine (https://drools.org/) is the rules engine in Drools project. The Drools engine stores, processes, and evaluates data to execute the business rules or decision models that you define. The basic function of the Drools engine is to match incoming data, or facts, to the conditions of rules and determine whether and how to execute the rules.

The Drools engine operates using the following basic components:

  • Rules: Business rules or DMN decisions that you define. All rules must contain at a minimum the conditions that trigger the rule and the actions that the rule dictates.
  • Facts: Data that enters or changes in the Drools engine that the Drools engine matches to rule conditions to execute applicable rules.
  • Production memory: Location where rules are stored in the Drools engine.
  • Working memory: Location where facts are stored in the Drools engine.
  • Agenda: Location where activated rules are registered and sorted (if applicable) in preparation for execution.

When a business user or an automated system adds or updates rule-related information in Drools, that information is inserted into the working memory of the Drools engine in the form of one or more facts. The Drools engine matches those facts to the conditions of the rules that are stored in the production memory to determine eligible rule executions. When rule conditions are met, the Drools engine activates and registers rules in the agenda, where the Drools engine then sorts prioritized or conflicting rules in preparation for execution.

The following picture, summarizes the concept:

The Drools engine in turn is part of the KIE (Knowledge Is Everything) umbrella project which includes, besides Drools also:

  • jBPM is a flexible Business Process Management suite allowing you to model your business goals by describing the steps that need to be executed to achieve those goals.
  • OptaPlanner is a constraint solver that optimizes use cases such as employee rostering, vehicle routing, task assignment and cloud optimization.
  • Business Central is a full featured web application for the visual composition of custom business rules and processes.
  • UberFire is a web-based workbench framework inspired by Eclipse Rich Client Platform.

As an example of Drool Rule, consider the following Java Bean model and sample DRL rule:

public class Applicant {
  private String name;
  private int age;
  private boolean valid;
  // Getter and setter methods
}

And here is a sample DRL rule for to check the Applicant model:

package com.company.license

rule "Is of valid age"
when
  $a : Applicant(age < 18)
then
  $a.setValid(false);
end

The “Is of valid age” rule disqualifies any applicant younger than 18 years old.

//Create the KIE container
KieServices kieServices = KieServices.Factory.get();

KieContainer kContainer = kieServices.getKieClasspathContainer();

//Instantiate the stateless KIE session and enter data
StatelessKieSession kSession = kContainer.newStatelessKieSession();

Applicant applicant = new Applicant("Mr John Smith", 16);

assertTrue(applicant.isValid());

ksession.execute(applicant);

assertFalse(applicant.isValid());

OpenL Tablets

OpenL Tablets (http://openl-tablets.org/) is a business rules management system and business rules engine based on tables presented in Excel documents. Using unique concepts, OpenL Tablets facilitates treating business documents containing business logic specifications as executable source code. Since the format of tables used by OpenL Tablets is familiar to business users, OpenL Tablets bridges a gap between business users and developers, thus reducing costly enterprise software development errors and dramatically shortening the software development cycle. In a very simplified overview, OpenL Tablets can be considered as a table processor that extracts tables from Excel documents and makes them accessible from the application.

The major advantages of using OpenL Tablets are as follows:

  • OpenL Tablets removes the gap between software implementation and business documents, rules, and policies.
  • Business rules become transparent to developers.
  • OpenL Tablets verifies syntax and type errors in all project document data, providing convenient anddetailed error reporting. OpenL Tablets can directly point to a problem in an Excel document.
  • OpenL Tablets provides calculation explanation capabilities, enabling expansion of any calculation result by pointing to source arguments in the original documents.
  • OpenL Tablets enables users to create and maintain tests to insure reliable work of all rules.
  • OpenL Tablets provides cross-indexing and search capabilities within all project documents.
  • OpenL Tablets provides full rules lifecycle support through its business rules management applications.
  • OpenL Tablets supports the .xls and .xlsx file formats.

For access to rules and data in Excel tables, OpenL Tablets API is used. OpenL Tablets provides a wrapper to facilitate easier usage.

For example consider the following rule coded in an Excel document:

There is only one rule hello1:

public interface Simple {
void hello1(int i);
}

Here is the wrapper which runs the rule::

import static java.lang.System.out;
import org.openl.rules.runtime.RulesEngineFactory;
public class Example {
    public static void main(String[] args) {
        //define the interface
        RulesEngineFactory < Simple > rulesFactory =
            new RulesEngineFactory < Simple > ("TemplateRules.xls",
                Simple.class);
        Simple rules = (Simple) rulesFactory.newInstance();
        rules.hello1(12);
    }
}

In order to use OpenL Tablets, the following dependency needs to be included:

<dependency>
    <groupId>com.deliveredtechnologies</groupId>
    <artifactId>rulebook-core</artifactId>
    <version>0.11</version>
</dependency>

Easy Rules

Easy Rules (https://github.com/j-easy/easy-rules) is a simple yet powerful Java rules engine providing the following features:

  • Lightweight framework and easy to learn API
  • POJO based development
  • Useful abstractions to define business rules and apply them easily
  • The ability to create composite rules from primitive ones
  • The ability to define rules using an Expression Language (Like MVEL and SpEL)

In a nutshell, Easy Rules provides the Rule abstraction to create rules with conditions and actions, and the RulesEngine API that runs through a set of rules to evaluate conditions and execute actions.

To use Easy Rules, you have to add the following dependency to your pom.xml :

<dependency>
    <groupId>org.jeasy</groupId>
    <artifactId>easy-rules-core</artifactId>
    <version>3.4.0</version>
</dependency>

We will create a rule that is always triggered and that will print “hello world” to the console when executed. Here is the rule:

@Rule(name = "Hello World rule", description = "Always say hello world")
public class HelloWorldRule {

    @Condition
    public boolean when() {
        return true;
    }

    @Action
    public void then() throws Exception {
        System.out.println("hello world");
    }

}

Now let’s create a rules engine and fire this rule:

public class Launcher {

    public static void main(String[] args) {

        // create facts
        Facts facts = new Facts();

        // create rules
        Rules rules = new Rules();
        rules.register(new HelloWorldRule());

        // create a rules engine and fire rules on known facts
        RulesEngine rulesEngine = new DefaultRulesEngine();
        rulesEngine.fire(rules, facts);

    }
}

RuleBook Rules Engine

Tired of classes filled with if/then/else statements? Need a nice abstraction that allows rules to be easily specified in a way that decouples them from each other? Want to write rules the same way that you write the rest of your code? RuleBook just might be the rules abstraction you’ve been waiting for!

Rule book is a rule engine built to create rules in a way familiar to Java developers. RuleBook also allows you to specify rules using an easy to use Lambda enabled Domain Specific Language or using POJOs that you define!

To build projects with RuleBook, add the code below to your pom.xml

<dependency>
    <groupId>com.deliveredtechnologies</groupId>
    <artifactId>rulebook-core</artifactId>
    <version>0.11</version>
</dependency>

Here is an example:

public class ExampleRule {
    public RuleBook<Object> defineHelloWorldRules() {
        return RuleBookBuilder
          .create()
            .addRule(rule -> rule.withNoSpecifiedFactType()
              .then(f -> System.out.print("Hello ")))
            .addRule(rule -> rule.withNoSpecifiedFactType()
              .then(f -> System.out.println("World")))
            .build();
    }
}

You can run the ExampleRule as follows:

public static void main(String[] args) {
    ExampleRule ruleBook = new ExampleRule();
    ruleBook
      .defineHelloWorldRules()
      .run(new FactMap<>());
}