5.2 KiB
layout | title | header | prev_section | next_section | doc |
---|---|---|---|---|---|
docs | Defining rules | Defining rules | user-guide/introduction | user-guide/rules-engine | true |
The key API in Easy Rules is the Rule
interface:
public interface Rule {
/**
* This method encapsulates the rule's conditions.
* @return true if the rule should be applied, false else
*/
boolean evaluate();
/**
* This method encapsulates the rule's actions.
* @throws Exception thrown if an exception occurs
* during actions performing
*/
void execute() throws Exception;
//Getters and setters for rule name,
//description and priority omitted.
}
The evaluate
method encapsulates conditions that must evaluate to TRUE to trigger the rule.
The execute
method encapsulates actions that should be performed when rule's conditions are satisfied.
You can define rules in two ways:
- By implementing the
Rule
interface or extending theBasicRule
class - Adding annotations on a POJO
Defining rules by extending BasicRule
Easy Rules provides a simple implementation of the Rule
interface named BasicRule
. This class implements most of methods
defined in the Rule
interface. You can extends this class and override evaluate
and
execute
methods to provide your conditions and actions logic. Here is an example:
public class MyRule extends BasicRule {
private BusinessData myBusinessData; //data to operate on
@Override
public boolean evaluate() {
//my rule conditions
return true;
}
@Override
public void execute() throws Exception {
//my actions
}
}
Defining rules using annotations
Easy Rules provides the @Rule
annotation that can turn a POJO into a rule. Here is an example:
@Rule(name = "my rule", description = "my rule description")
public class MyRule {
private BusinessData myBusinessData; //data to operate on
@Condition
public boolean when() {
//my rule conditions
return true;
}
@Action(order = 1)
public void then() throws Exception {
//my actions
}
@Action(order = 2)
public void finally() throws Exception {
//my final actions
}
}
The @Condition
annotation marks the method to execute to evaluate the rule conditions.
This method must be public, have no parameters and return a boolean type. Only one method can be annotated with @Condition
annotation.
The @Action
annotation marks methods to execute to perform rule actions. Rules can have multiple actions.
Actions can be executed in a specified order
You can also define the execution order of actions with the order attribute: @Action(order = 1). By default, the order of an action is 0.
Composite rules
Easy Rules allows you to create complex rules from primitive ones. A CompositeRule
is composed of a set of rules.
This is typically an implementation of the composite design pattern.
A composite rule is triggered if all conditions of its composing rules are satisfied. When a composite rule is applied, actions of all composing rules are performed in the natural order of rules which is rules priorities by default.
To create a composite rule from two primitive rules, you can use the following snippet:
//Create a composite rule from two primitive rules
CompositeRule myCompositeRule =
new CompositeRule("myCompositeRule", "a composite rule");
myCompositeRule.addRule(myRule1);
myCompositeRule.addRule(myRule2);
//Register the composite rule as a regular rule
RulesEngine rulesEngine = aNewRulesEngine().build();
rulesEngine.registerRule(myCompositeRule);
Rules priorities
Each rule in Easy Rules has a priority. This represents the default order in which registered rules are fired.
By default, lower values represent higher priorities.
To override this behavior, you should override the compareTo
method to provide a custom priority strategy.
-
If you decided to extend the
BasicRule
class, you can specify rule priority at construction time or by overriding thegetPriority()
method -
If your rule is a annotated POJO, you should annotate the method that provides priority with
@Priority
annotation. This method must be public, have no arguments and return an Integer type
Rule listener
You can listen to rule execution events through the RuleListener
API:
public interface RuleListener {
/**
* Triggered before a rule is executed.
*/
void beforeExecute(Rule rule);
/**
* Triggered after a rule is executed successfully.
*/
void onSuccess(Rule rule);
/**
* Triggered after a rule is executed with error.
*/
void onFailure(Rule rule, Exception exception);
}
You can implement this interface to provide custom behavior to execute before/after each rule. To register your listener, use the following snippet:
RulesEngine rulesEngine = aNewRulesEngine()
.withRuleListener(myRuleListener)
.build();
You can register as many listeners as you want, they will be executed in their registration order.