Skip to content
Mahmoud Ben Hassine edited this page Apr 10, 2018 · 13 revisions

This tutorial shows how to use MVEL with Easy Rules. MVEL support was added in v3.1 and is provided through the easy-rules-mvel module. This module contains APIs to define rules using MVEL. We will use these APIs here. The goal is to implement a simple shop application with the following requirement: deny children from buying alcohol. The minimum legal age to be considered as adult is 18. The shop customers are represented by the Person class:

public class Person {
    private String name;
    private int age;
    private boolean adult;
    //getters and setters omitted
}

We will define the following rules:

  • Rule 1: should operate an a Person instance, check if the person age is greater than 18 and set the adult flag.
  • Rule 2: should operate an a Person instance, check if the person is adult and deny children (ie, non adult) from buying alcohol.

Rule 1 should be fired before rule 2. We will set rule 1 priority to 1 and rule 2 priority to 2 so that Easy Rules engine fire them in this order.

First, let's create a MVELRule for rule 1:

Rule ageRule = new MVELRule()
        .name("age rule")
        .description("Check if person's age is > 18 and marks the person as adult")
        .priority(1)
        .when("person.age > 18")
        .then("person.setAdult(true);");

As required, this rule operates on a person that will be obtained from the set of facts. It will check if the person's age is greater than 18 and mark it as adult by setting the adult flag.

The ageRule is defined in a programmatic way through the MVELRule class. There is another way to define MVELRules in a more declarative way through a rule descriptor. We will use this approach to define the second rule:

name: "alcohol rule"
description: "children are not allowed to buy alcohol"
priority: 2
condition: "person.isAdult() == false"
actions:
  - "System.out.println(\"Shop: Sorry, you are not allowed to buy alcohol\");"

This alcohol-rule.yml file defines all information needed to create the second rule. We can now use the MVELRuleFactory to create a MVELRule from this file:

Rule alcoholRule = MVELRuleFactory.createRuleFrom(new FileReader("alcohol-rule.yml"));

As for rule 1, this rule operates on a person instance and prints the denial message for children.

To launch the tutorial, we will use the following class:

public class Launcher {

    public static void main(String[] args) throws FileNotFoundException {
        //create a person instance (fact)
        Person tom = new Person("Tom", 14);
        Facts facts = new Facts();
        facts.put("person", tom);

        // create rules
        Rule ageRule = new MVELRule()
                .name("age rule")
                .description("Check if person's age is > 18 and marks the person as adult")
                .priority(1)
                .when("person.age > 18")
                .then("person.setAdult(true);");
        Rule alcoholRule = MVELRuleFactory.createRuleFrom(new FileReader("alcohol-rule.yml"));

        // create a rule set
        Rules rules = new Rules();
        rules.register(ageRule);
        rules.register(alcoholRule);

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

        System.out.println("Tom: Hi! can I have some Vodka please?");
        rulesEngine.fire(rules, facts);
    }

}

To run the tutorial, please follow these instructions:

$ git clone https://github.com/j-easy/easy-rules.git
$ cd easy-rules
$ mvn install
$ cd easy-rules-tutorials
$ mvn exec:java -P runShopTutorial

You should get the following output:

Tom: Hi! can I have some Vodka please?
INFO: Engine parameters { skipOnFirstAppliedRule = false, skipOnFirstNonTriggeredRule = false, skipOnFirstFailedRule = false, priorityThreshold = 2147483647 }
INFO: Registered rules:
INFO: Rule { name = 'age rule', description = 'Check if person's age is > 18 and marks the person as adult', priority = '1'}
INFO: Rule { name = 'alcohol rule', description = 'children are not allowed to buy alcohol', priority = '2'}
INFO: Known facts:
INFO: Fact { person : Person{name='Tom', age=14, adult=false} }
INFO: Rules evaluation started
INFO: Rule 'age rule' has been evaluated to false, it has not been executed
INFO: Rule 'alcohol rule' triggered
Shop: Sorry, you are not allowed to buy alcohol
INFO: Rule 'alcohol rule' performed successfully

As expected, since Tom's age is under 18, he has not been allowed to buy alcohol.