You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
easy-rules/site/user-guide/defining-rules.md

175 lines
5.2 KiB
Markdown

---
layout: docs
title: Defining rules
header: Defining rules
prev_section: user-guide/introduction
next_section: user-guide/rules-engine
doc: true
---
The key API in Easy Rules is the `Rule` interface:
```java
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 the `BasicRule` 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:
```java
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:
```java
@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.
<div class="note info">
<h5>Actions can be executed in a specified order</h5>
<p>You can also define the execution order of actions with the
<em>order</em> attribute: <em>@Action(order = 1)</em>. By default, the order of an action is 0.</p>
</div>
## 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 <a href="http://en.wikipedia.org/wiki/Composite_pattern" target="_blank">composite design pattern</a>.
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:
```java
//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
the `getPriority()` 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:
```java
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:
```java
RulesEngine rulesEngine = aNewRulesEngine()
.withRuleListener(myRuleListener)
.build();
```
You can register as many listeners as you want, they will be executed in their registration order.