Coder Social home page Coder Social logo

j-easy / easy-rules Goto Github PK

View Code? Open in Web Editor NEW
4.8K 225.0 1.0K 1.73 MB

The simple, stupid rules engine for Java

Home Page: https://github.com/j-easy/easy-rules/wiki

License: MIT License

Java 100.00%
java rules-engine rule-engine expression-language business-rules

easy-rules's Introduction


Easy Rules
The simple, stupid rules engine for Java™

MIT license Build Status Maven Central Javadoc Project status


Project status

As of December 2020, Easy Rules is in maintenance mode. This means only bug fixes will be addressed from now on. Version 4.1.x is the only supported version. Please consider upgrading to this version at your earliest convenience.

Latest news

  • 06/12/2020: Version 4.1 is out with a new module to support Apache JEXL as an additional supported expression language! You can find all details about other changes in the release notes.

What is Easy Rules?

Easy Rules is a Java rules engine inspired by an article called "Should I use a Rules Engine?" of Martin Fowler in which Martin says:

You can build a simple rules engine yourself. All you need is to create a bunch of objects with conditions and actions, store them in a collection, and run through them to evaluate the conditions and execute the actions.

This is exactly what Easy Rules does, it 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.

Core features

  • Lightweight library and easy to learn API
  • POJO based development with an annotation programming model
  • Useful abstractions to define business rules and apply them easily with Java
  • The ability to create composite rules from primitive ones
  • The ability to define rules using an Expression Language (Like MVEL, SpEL and JEXL)

Example

1. First, define your rule..

Either in a declarative way using annotations:

@Rule(name = "weather rule", description = "if it rains then take an umbrella")
public class WeatherRule {

    @Condition
    public boolean itRains(@Fact("rain") boolean rain) {
        return rain;
    }
    
    @Action
    public void takeAnUmbrella() {
        System.out.println("It rains, take an umbrella!");
    }
}

Or in a programmatic way with a fluent API:

Rule weatherRule = new RuleBuilder()
        .name("weather rule")
        .description("if it rains then take an umbrella")
        .when(facts -> facts.get("rain").equals(true))
        .then(facts -> System.out.println("It rains, take an umbrella!"))
        .build();

Or using an Expression Language:

Rule weatherRule = new MVELRule()
        .name("weather rule")
        .description("if it rains then take an umbrella")
        .when("rain == true")
        .then("System.out.println(\"It rains, take an umbrella!\");");

Or using a rule descriptor:

Like in the following weather-rule.yml example file:

name: "weather rule"
description: "if it rains then take an umbrella"
condition: "rain == true"
actions:
  - "System.out.println(\"It rains, take an umbrella!\");"
MVELRuleFactory ruleFactory = new MVELRuleFactory(new YamlRuleDefinitionReader());
Rule weatherRule = ruleFactory.createRule(new FileReader("weather-rule.yml"));

2. Then, fire it!

public class Test {
    public static void main(String[] args) {
        // define facts
        Facts facts = new Facts();
        facts.put("rain", true);

        // define rules
        Rule weatherRule = ...
        Rules rules = new Rules();
        rules.register(weatherRule);

        // fire rules on known facts
        RulesEngine rulesEngine = new DefaultRulesEngine();
        rulesEngine.fire(rules, facts);
    }
}

This is the hello world of Easy Rules. You can find other examples like the Shop, Airco or WebApp tutorials in the wiki.

Contribution

You are welcome to contribute to the project with pull requests on GitHub. Please note that Easy Rules is in maintenance mode, which means only pull requests for bug fixes will be considered.

If you believe you found a bug or have any question, please use the issue tracker.

Awesome contributors

Thank you all for your contributions!

Easy Rules in other languages

Who is using Easy Rules?

Credits

YourKit Java Profiler

Many thanks to YourKit, LLC for providing a free license of YourKit Java Profiler to support the development of Easy Rules.

License

Easy Rules is released under the terms of the MIT license:

The MIT License (MIT)

Copyright (c) 2021 Mahmoud Ben Hassine ([email protected])

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

easy-rules's People

Contributors

agavrilov76 avatar andersonkyle avatar bpoussin avatar cgonc avatar danrivcap avatar desislav-petrov avatar drem-darios avatar fmbenhassine avatar gitter-badger avatar gs-spadmanabhan avatar jordanjennings avatar lranasingha avatar paritoshranjan avatar paulbrejla avatar richdouglasevans avatar ruanjiehui avatar sanmibuh avatar stefanbirkner avatar toudidel avatar vsr625 avatar waynecui avatar zhhaojie avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

easy-rules's Issues

Add @SpringRule meta annotation

When using Easy Rules with Spring, rules are usually declared as spring beans. This requires annotating each rule with 2 annotations:

  • @Rule to turn the object into a Easy Rules rule
  • @Component to declare the object as a Spring bean

The new @SpringRule is a meta-annotation that declares both annotations to DRY the code.

Rules annotated with @SpringRule are prototype-scoped spring beans.

Add RulesEngineParameters

As of version 2.1, the rules engine can be configured with 5 parameters which are not encapsulated.
The goal is to encapsulate these parameters in the new RulesEngineParameters class.

Separating data from rule

Hi,

I am really interested in using this library.
I think it would be good to separate the data on which rule execute. I mean if we can pass the data to rule when we fire the rule engine i.e. fireRules(data) which subsequently calls execute(data) on each rule.

This will allow composition of rule engine separately from the data it needs at runtime.

If it's OK I can make a branch make the appropriate changes.

Thanks
Nimit Shah

Add working memory abstraction

In the real world :

  • A rule condition is evaluated against a set of known facts
  • A rule action acts on these facts and may add/remove/modify facts

The set of known facts is the working memory of a rules engine. It allows rules to add/remove/modify facts. This is a key concept to implement backward/forward chaining.

Moreover, having a separate working memory decouples a rule from data it operates on. This was the major drawback in Easy Rules v2 which caused a lot of issues regarding thread safety.

So having the following signature of evaluate and execute methods in the Rule API should make sense:

/**
 * Rule condition : return true if the rule should be applied given the known facts, false otherwise
 */
boolean evaluate(Facts facts);

/**
 * Rule action : may add/remove/modify facts
 */
void execute(Facts facts) throws Exception;

The goal is to add a Facts abstraction to represent a set of named facts and a @Fact annotation to mark a parameter as a fact when using a POJO as a rule. Any java object can be used as a fact (Facts is a Map<String, Object>).

Here is an example of a rule:

@Rule
class WeatherRule {
    @Condition
    public boolean itRains(@Fact("rain") boolean rain) {
        return rain;
    }

    @Action
    public void takeAnUmbrella(Facts facts) {
        System.out.println("It rains, take an umbrella!");
        // can add/remove/modify facts
    }
}

And how to use it:

@Test
public void test() throws Exception {
    // define facts
    Facts facts = new Facts();
    facts.add("rain", true);

    // define rules
    Rules rules = new Rules(new WeatherRule());

    // fire rules on known facts
    RulesEngine rulesEngine = new DefaultRulesEngine();
    rulesEngine.fire(rules, facts);
}

Easy Rules should make sure to inject the facts (by name) in the parameters of condition and action methods. If a parameter is of type Facts, the engine will inject all facts (by type).

This new API design should address the major thread safety issue of v2:

  • The rules are stateless and separated from the working memory
  • The rules engine is stateless and can be safely shared between threads
  • The working memory acts as a session for the fire method and should be created for each thread (each thread has its own set of data to operate on but the rules and the engine can be reused)

Unable to add annotated rule to a composite rule

hello,
Could you help me please?
I dont understand about compositeRule, when using the method addRule, problems with cast argument.

Ex:
CompositeRule compositeRule =new CompositeRule("compositeRule","",1);
compositeRule.add(new ItemRule());

My ItemRule, I'm using Annotation @rule.

Thanks

Add method to get registered rules

As of version 2.1, it is not possible to get registered rules in a rules engine.

The RulesEngine interface should contain a method that returns registered rules.

Spring / Rules contexts

Thank you for this promising project.

The interest of Spring is very limited with the actual implementation.

Perhaps it could be interesting to set a context to a RulesEngine like this:
rulesEngine.addContext("age", 18);
or
rulesEngine.fireRules("age", 18, "gender", "Male");

And to set dynamically the context to the rule during the execution:
In the pojo:
@rule(...)
public class AgeRule {
@context("age") //injected by the ruleEngine
private Long age;
}

Problem with executing all the rules in the easy-rules-2.0.0

I tried out the new version 2.0.0. All the registered rules does not seem to be triggered.
I'm pasting the code I have written, and I'm expecting all the rules to be executed, but it's not working this way. Let me know if I'm missing something.

  @Rule
  public class RuleA {
    @Condition
    public boolean when(){
        System.out.println("A is called");
        return true;
    }
    @Action
    public void then(){
        System.out.println("A is executed");
    }
}
@Rule
public class RuleB {
    @Condition
    public boolean when(){
        System.out.println("B is called");
        return true;
    }

    @Action
    public void then(){
        System.out.println("B is executed");
    }
}
@Rule
public class RuleC {
    @Condition
    public boolean when(){
        System.out.println("C is called");
        return true;
    }

    @Action
    public void then(){
        System.out.println("C is executed");
    }
}

The Main method for calling these rules:

public class Main {
    public static void main(String[] args) {
          RuleA a = new RuleA();
          RuleB b = new RuleB();
          RuleC c = new RuleC();

           RulesEngine rulesEngine = RulesEngineBuilder.aNewRulesEngine().build();
          rulesEngine.registerRule(a);
          rulesEngine.registerRule(b);
          rulesEngine.registerRule(c);

             rulesEngine.fireRules();
    }
}

Output printed in the console-------------------

May 21, 2015 10:18:26 AM org.easyrules.core.DefaultRulesEngine logEngineParameters
INFO: Rule priority threshold: 2,147,483,647
May 21, 2015 10:18:26 AM org.easyrules.core.DefaultRulesEngine logEngineParameters
INFO: Skip on first applied rule: false
May 21, 2015 10:18:26 AM org.easyrules.core.DefaultRulesEngine logEngineParameters
INFO: Skip on first failed rule: false
May 21, 2015 10:18:26 AM org.easyrules.core.DefaultRulesEngine applyRules
INFO: Rule 'rule' triggered.
A is called
A is executed
May 21, 2015 10:18:26 AM org.easyrules.core.DefaultRulesEngine applyRules
INFO: Rule 'rule' performed successfully.

Question:

Why aren't RuleB and RuleC executed in this case ?

Rules DSL

I was going to write my own Rules engine but came across this lovely project. I would like to contribute to it and add a feature that would enable writing a DSL on top of the existing engine. Sample psuedo code as follows:

RulesEngine engine = new RulesEngine()

engine.rules()
    .rule(new MyRule1())
    .rule(new MyRule2())
    .choice()
        .when(new MyCondition())
              .to("path:rulepath1")
        .when(new MyCondition())
              .to(new MyRulePath())
        .otherwise()
             .to("path:rulepath2")
       .end();

The syntax is similar to Apache Camel. The DSL simply defines the order of execution for the rules, and provides smart routing to additional rules.

Android and EasyRules

Since JMX is not supported in android, the dynamic configuration will not work. Do you have any plans for having a different way for dynamic configuration?

Can we store rules in a property file or Database?

Hi,

I am new to rule engines. I found easyrules interesting.

I checked docs and found 3 ways to define rules-

  1. implements Rule interface
  2. Extends BasicRule class
  3. Annotations in POJO

Is there any way to store rules in a property file or Database?

JMX rules should be deprecated

One of the motivation of JMX feature is to be able to reconfigure rules at runtime. Unfortunately, it turns out that this feature has introduced a couple of issues in Easy Rules:

  • Since the core module should be android compatible (and since android does not support JMX), it's impossible to add this feature in the core module in a consistent and transparent way
  • Adding JMX feature in a separate module leads to an inconsistency in rules engines: DeafultRulesEngine and DefaultJmxRulesEngine (see issue #31).

As a result, until finding a clean way to add this feature in a consistent way that is android compatible, JMX rules should be deprecated in v2.3 and removed in v2.4

@Autowired class is null inside Rule class

Hi,

Thanks for this awesome feature. It made my life easier, when I was thinking how to implement multiple rules in my project.
I have a scenario where I update my database based on conditions. I am using EasyRules for the same.

I am autowiring my DAO class inside the spring rule engine class.
When I run the code, my Dao class which is autowired inside my SpringRule class is null. Hence I am getting nullpointerexception.
My code is as below

@SpringRule
public class Rule1 {

@Autowired
private MyDAO myDAO;   --> (is null during runtime)

public Rule1 () {
    super();
}

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

@Action(order = 1)
public void then() throws Exception {
    myDAO.update("test");
    System.out.println("Waiting state success");
}

}

My DAO interface is:

public interface MyDAO {
   public void update(String value);
}

My DAO impl calss is:

@Repository
public class MyDAOImpl implements MyDAO{

@Override
public void update(String value){
//update in DB
}
}

Rule types?

It seems like different types of rules require different processors to fire them. Is there a reason for this or am I missing something?

Multiple conditions for Rule execution

Hi,

I am really interested by using EasyRules, nice lib :-)

It would be helpful to be able to use several separated conditions for executing a Rule at runtime. Sometimes the same Rules should be used but at different conditions, depending on which scenario is used.

My idea is to create an interface with a single method (this way Java 1.8 users like me can use lambdas) and an aggregated BasicRule, here is a suggestion (not tested) :

Note: I called it Evaluable in this example for avoid potential conflict with annotation homonym.

public interface Evaluable {
    boolean evaluate();
}

public interface Rule extends Evaluable {
    // This is original interface, just evaluate() has been moved
}


public class MulticonditionalRule extends BasicRule {
    protected Set<Evaluable> conditions = new TreeSet<>();

    @Override
    public boolean evaluate() {
        if (conditions.isEmpty()) {
            return false;
        }
        for (Evaluable condition : conditions) {
            if (!condition.evaluate()) {
                return false;
            }
        }
        return true;
    }

    public MulticonditionalRule addCondition(Evaluable condition) {
        conditions.add(condition);
        return this; // chain
    }

    public void removeCondition(Evaluable condition) {
        conditions.remove(condition);
    }
}

Example of usage :

MulticonditionalRule rule = new MulticonditionalRule() {
    public void execute() {
        something();
    }
};

rule
    .addCondition( () -> blabla.isEnabled() )
    .addCondition( () -> something.isAccessible() )
    .addCondition( () -> otherThing.isRegistered() );

// "Combitional" usage of conditions, this is the point
if (bibiFeatureDisponible()) {
    rule.addCondition( () -> bibi.hasThing() );
}

// And for Java 1.6
rule.addCondition(new Evaluable() {
    @Override
    public boolean evaluate() {
        return foo.enabled();
    }
}

Best regards !
Gabriel

Improve JUL log record format

The default log record format is not very convenient. Use the following format: %1$tF %tT.%1$tL %4$s [%2$s] - %5$s %6$s%n

Using @Rule in a meta annotation

Thanks so much for the quick turn around on the rule name modification.

Now annotating a rule class with just @rule without a rule name automatically defaults the rule name to the class name, however, the rule class does not like a meta-annotation that has @rule embedded in it. For example, I have defined my meta-annotation @BasicRule in the following manner. My tests throw an exception while parsing the class, complaining that it cannot find the @rule annotation, even though I have annotated my rule class with @BasicRule.

@retention(RetentionPolicy.RUNTIME)
@target(ElementType.TYPE)
@component
@scope("prototype")
@rule
public @interface BaseRule
{

}

Sample Stack Trace:
java.lang.IllegalArgumentException: Rule ‘XYZ' is not annotated with 'org.easyrules.annotation.Rule'
at org.easyrules.core.RuleDefinitionValidator.checkRuleClass(RuleDefinitionValidator.java:34)
at org.easyrules.core.RuleDefinitionValidator.validateRuleDefinition(RuleDefinitionValidator.java:26)
at org.easyrules.core.RuleProxy.asRule(RuleProxy.java:34)
at org.easyrules.core.DefaultRulesEngine.asRule(DefaultRulesEngine.java:209)
at org.easyrules.core.DefaultRulesEngine.registerRule(DefaultRulesEngine.java:101)

Log registered rules at engine startup

It would be great if the engine logs registered rules at startup. This makes it easier to debug engine behaviour at runtime. Here is an example for the shop tutorial:

Tom: Hi! can I have some Vodka please?
[Sun Dec 06 21:11:47 CET 2015] INFO: Engine name: shop rules engine
[Sun Dec 06 21:11:47 CET 2015] INFO: Rule priority threshold: 2,147,483,647
[Sun Dec 06 21:11:47 CET 2015] INFO: Skip on first applied rule: false
[Sun Dec 06 21:11:47 CET 2015] INFO: Skip on first failed rule: false
[Sun Dec 06 21:11:47 CET 2015] INFO: Registered rules:
[Sun Dec 06 21:11:47 CET 2015] INFO: Rule { name = 'AgeRule', description = 'Check if person's age is > 18 and marks the person as adult', priority = '1'}
[Sun Dec 06 21:11:47 CET 2015] INFO: Rule { name = 'AlcoholRule', description = 'Children are not allowed to buy alcohol', priority = '2'}
[Sun Dec 06 21:11:47 CET 2015] INFO: Rule 'AgeRule' has been evaluated to false, it has not been executed
[Sun Dec 06 21:11:47 CET 2015] INFO: Rule 'AlcoholRule' triggered
Shop: Sorry Tom, you are not allowed to buy alcohol
[Sun Dec 06 21:11:47 CET 2015] INFO: Rule 'AlcoholRule' performed successfully

Question on skipping rules

Hi,
There is an option skipOnFirstAppliedRule, through which, you can disable the subsequent rules, if one rule is executed.
For example, if there are rules A, B and C, if rule A executes to true, then B and C won't be applied. Is my understanding correct ?

I am trying to achieve the below functionality, is there any way to do it ?

I have three rules A, B and C and it has to be executed like this

if(A && B && C) {//then do something}

This means that, if A fails, I should not execute B and C, since there is no point. Is there any way to do this thing ?

Improve rule name/description default values

As of version 2.1, the default rule name is "rule". It would be better to make the rule class name as the default name.

The same idea can be applied to description. Currently the default is "rule description", it could be improved to be when 'conditionMethodName' then 'actionMethod(s)Name'.

Here is an example:

@Rule
class DummyRule {

 private Person person;

 public DummyRule(Person person) {
     this.person = person;
 }

 @Condition
 public boolean ageGreaterThan18() {
     return person.getAge() >= 18;
 }

 @Action
 public void markAsAdult() {
    person.setAdult(true);
 }

}
  • The default rule name would be "DummyRule"
  • The default rule description would be "when 'ageGreaterThan18' then 'markAsAdult' "

If the class defines multiple actions, then names of all action methods should be added in order to the desription.

Adding rules at Runtime

Hi,

If I understood correctly, it is only possible to modify certain rules at runtime (like the example on changing the adult age). But it is not possible to add new rules whithout recompiling, right?

In my case, I need to inject new rules (java files in this case) to clients without them recompiling java code. Any other solution you can think of?

Thanks

I have a class and in that i have different conditions..based on each condition i have to call a separate method.so how do i configure rule in this case.since we dont have any if then else in easyrule. also i dont want to use one rule for each if condition.

I have a class and in that i have different conditions..based on each condition i have to call a separate method.so how do i configure rule in this case.since we dont have any if then else in easyrule. also i dont want to use one rule for each if condition.Suggest me how to proceed in this case.
Also i have a small question that will it support jdk1.6 or not??

Thank you in advance.

Rule-Priority (Problem with sort sequence by overwriting the getPriority()-method)

Hi,
you wrote in your documentation:

If you decided to extend the BasicRule class, you can specify rule priority at construction time or by overriding the getPriority() method

Setting the priority via constructor achieves a correct order of my rules. great!
if I extend from BasicRule.class and overwrite the getPriority()-method only and using the default-constructor fo the concrete class, in case of sorting the value that is returned by this method is always compared against DEFAULT_RULE_PRIORITY-value. So the order doesn't depend on the specified priority.
I think the problem is the compareTo-implementation in the BasicRule.class

maybe
if (priority < rule.getPriority()) {
should better be
if (getPriority() < rule.getPriority()) {

} else if (priority > rule.getPriority()) {
should better be
} else if (getPriority() > rule.getPriority()) {

for me extending the BasicRule.class with the current implementation and overwriting the getPriority()-method in the concrete class doesn't achieve a correct sort sequence?!

Good job!

just stumbled on this library, this is really good work!

under Android throws MXBean not found

I've been trying to use Easy Rules in my Android app. Version 2.2.0 causes a MXBean not found error to be thrown during compilation. I am using org.easyrules:easyrules-core:2.2.0 in my gradle build. As far as I can tell this is caused by BasicRule requiring mxbean, which is not defined in Android SDK.

I'll be looking for a workaround while developing the app.

Easy Rules logging issue

I am using easy rules extensively for my tomcat based web application . In my eclipse console I am seeing this logs . How do I disable these logs

INFO: Rule 'FloodCertLinkPermissionRule' triggered.
Jul 29, 2015 4:38:34 PM org.easyrules.core.AnnotatedRulesEngine fireRules

Can't register multiple rules with the same priority to DefaultRulesEngine

I noticed that if you register multiple rules with the same priority to the DefaultRulesEngine, only the first rule will be added to the set and fired. Looks like this is due to the behavior of TreeSet which uses compareTo for all element comparison. Maybe DefaultRulesEngine should use ArrayList like AnnotatedRulesEngine so they have the same behavior?

SimpleRule rule1 = new SimpleRule("rule 1", "description 1", 0);
SimpleRule rule2 = new SimpleRule("rule 2", "description 2", 0);
SimpleRule rule3 = new SimpleRule("rule 3", "description 3", 1);

RulesEngine<Rule> engine = new DefaultRulesEngine();
engine.registerRule(rule1);
engine.registerRule(rule2);
engine.registerRule(rule3);
engine.fireRules();

assertTrue(rule1.isExecuted());
assertTrue(rule2.isExecuted()); //fails
assertTrue(rule3.isExecuted());

Really like the library - great lightweight alternative to drools :)

How to handle multiple data using rules

When there is a lot of data, how to deal with?Use clearRules() ?

public class Launcher {

    public static void main(String[] args) {

        //create a person instance
        Person tom = new Person("Tom", 16);
        System.out.println("Tom: Hi! can I have some Vodka please?");

        //create a rules engine
        RulesEngine rulesEngine = aNewRulesEngine().build();
        rule(rulesEngine,tom);
        Person devid = new Person("Devid", 18);
        rule(rulesEngine,devid);
    }

    public static void rule( RulesEngine rulesEngine,Person person){
        //register rules
        rulesEngine.registerRule(new AgeRule(person));
        rulesEngine.registerRule(new AlcoholRule(person));
        //fire rules
        rulesEngine.fireRules();
        rulesEngine.clearRules();
    }

}

Check Rules feature

Hi guys,

I found yours project very interesting for me, but I have some suggestions for you.

  1. Sometimes it may be useful to not fire rules, but only check them like:
    boolean allRulesApplicable = ruleEngine.checkRules();
    Or return some rules result which can contain simple map (String, Boolean), where key is a Rule name and values is a "evaluate" method result. "fireRules" should return boolean or rules status.
  2. Also it may be useful in conjunction with feature above to have rules evaluator to be able check rules like:
    (RuleA and RuleB) or RuleC
  3. Maybe it will be a good idea to separate execute method from Rule itself to give additional level of abstraction. For example, if I use a CompositeRule it is possible that I want to execute a single "Job" for all contained rules. It can possibly give more flexibility with features 1 and 2.

P.S. It is possible that I understand project use cases wrong :)

Thanks in advance.

Feature Request: skipOnFirstFailedRule

Like we already have skipOnFirstAppliedRule, It would be nice to have an option skipOnFirstFailedRule .
For now, if there are three rules A, B and C, and if we need A, B and C to pass to evaluate a condition, then we can stop B and C being evaluated if A fails.

We can achieve this right now, using skipOnFirstAppliedRule, but it doesn't feel elegant and natural. Having skipOnFirstFailedRule would be nice.

Rules working, but STDERR getting printed to console.

I wrote some rules in an EJB 3.0(running on Jboss 4.0.5) and triggered it. The rules are getting triggered fine, but I get these error messages to console. Any idea what it is ?

2015-04-10 10:17:29,292 ERROR [STDERR] Apr 10, 2015 10:17:29 AM org.easyrules.core.AbstractRulesEngine logEngineParameters
INFO: Skip on first applied rule: false
2015-04-10 10:17:29,292 ERROR [STDERR] Apr 10, 2015 10:17:29 AM org.easyrules.core.AbstractRulesEngine logEngineParameters
INFO: Rule priority threshold: 2,147,483,647
2015-04-10 10:17:29,292 ERROR [STDERR] Apr 10, 2015 10:17:29 AM org.easyrules.core.AnnotatedRulesEngine fireRules
INFO: Rule 'LoginRule' triggered.
2015-04-10 10:17:29,292 ERROR [STDERR] Apr 10, 2015 10:17:29 AM org.easyrules.core.AnnotatedRulesEngine fireRules
INFO: Rule 'LoginRule' performed successfully.

How do i register rules once in a loop

I have stream of data coming but rules remains the same how can i register them once and use it on the data set why do i need to send the rule with the data every time.

newbie - however API feels inconsistent - would some refactoring improve consistency?

I have been having a play with easyRules for a project - i like the simplicity of the model (havnet volume tested for performance - this is more about the API

I've been looking at easyRules and springboot. however i cant quite reconcile the model differences between jmxRuleEngine and ordinary ruleEngine. Why are there tow class types, in my head they better as configuration -RuleEngine (jmxEnabled true/false)

also the BasicRule class (evaluate & execute) is defferent from using @rule to convert a pojo into spring bean (condition/action/action etc )

when i tried to add a Spring @rule class to ruleEngine.addRule it wouldn't accept it, i had to get a rulesEngine from the spring context (after config ) and added spring rule to that engine and that worked - but that meant i had two engines to play with

as a new user of easyRules i found this a little perplexing and inconsistent, and forced you make choices for one mode or the other (extend BasicRule, or go for the Spring bean model, or jmx, not jmx ) .

I managed to get various samples up and running but the usage was inconsistent and I felt could be simplified and harmonised to remove these differences and make the developer 'experience' easier and more consistent.

I admit that i haven't coded as a developer 'for real' for many years now - so apologies if i have not got the best way to use this, but just wanted to plant a seed of thought for consideration. I'll have another little play - i'm using groovy so it maybe i can see if its possible to 'hide' some of the mechanical differences and see what that looks like

Add RulesEvaluator API

As discussed in #40 with @thecederick , it may be useful to have a rules evaluator API to be able check rules like: (RuleA and RuleB) or RuleC

You can already do this: ( ruleA.evaluate() && ruleB.evaluate() ) || ruleC.evaluate() . Do you believe Easy Rules should provide a RuleEvaluator API?

It is not always possible do it like you described, for example @condition annotation and you do it outside of Engine.

problem with The method aNewRulesEngine()

I'am just trying to execute the Hello World Example, I imported the Core Jar 2.1, annotations and everything else is fine but not this function,
here is the error message in Eclipse :
The method aNewRulesEngine() is undefined for the type Launcher
and thank you in advance

Composite Rules

While using composite rules to add my rules, i don't have the flexibility of using annotations. In this case, i realised the system expects Basic rule to be extended. Is there any specific reason for this?

Why bother with Spring

Hi,

Considering as a new RulesEngine instance is needed + a new Rule instance for every Rule which needs to be set on the RulesEngine to maintain state I am not clear what value Spring brings to any of this......

Take for example a REST request which hits the server and trigger a bunch of Rules.

For every request we will need at least one or more Rules on which we set some sort of Object for the State. Then we need a fresh RulesEngine to which set the Rules. We probably have to pass in the HttpReponse object as well so that the Last rule to be fired can respond back.....

I dont see any value in using @SpringRule or the RulesEngineFactoryBean.... what am I missing?

Thanks

Why doesn't AnnotatedRulesEngine convert beans to a Rule?

I am working on capturing business rule events in order to record their execution for debugging purposes. I am wrapping a Rule in order to capture the execution. This works well for the DefaultRulesEngine but won't work for the AnnotatedRulesEngine. It will be tricker to do this with that.

If the AnnotatedRulesEngine had converted the annotated object into a Rule at registration then this would have been considerably easier to. Does this sound too crazy?

Is there a better way to record the execution (or not) then delegation? We are recording more then just logging. We need to record into a custom reporting library.

Use Expression Language to define rules

It should be possible to define rules with an Expression Language (like OGNL, MVEL, JBoss EL, Spring EL).

Conditions are easy to express using an expression language.
The challenge here is how to define actions, their order, on which facts do they act, etc...

Still need to investigate and find a clean (and easy!) way to express actions.

Any suggestions or ideas are welcome!

Is easy rules capable of providing fact feedback while analyzing rules?

Hi. My apologies if the question is not specific enough. However, I think that when Drools evaluates a rule codebase with existing facts, whenever a rule is triggered, said rule could insert or retract facts from the working memory; thus triggering other rules.

Does easyrules have this capability? Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.