j-easy / easy-rules

The simple, stupid rules engine for Java
https://github.com/j-easy/easy-rules/wiki
MIT License
4.86k stars 1.05k forks source link

setSkipOnFirstAppliedRule not working when set to true #341

Closed davidbzkm closed 3 years ago

davidbzkm commented 3 years ago

Hi, I'm trying to have the first rule executed and stop right after.

Source Files src.zip

Expected behavior RuleB gets fired(priority 0) and then the engine does not fire any other rule

Executed Result Both rules are fired

CODE

@Rule(name = "Rule A", description = "Always return true") public class RuleA {
private final int priority;

public RuleA(int priority) {
    this.priority = priority;
}

@Condition
public boolean when() {
    System.out.println("execute when RuleA");
    return true;
}

@Action
public void then() {
    System.out.println("execute then RuleA");
}

@Priority
public int getPriority() {
   return this.priority;

} }

public class RuleB {
private final int priority;

public RuleB(int priority) {
    this.priority = priority;
}

@Condition
public boolean when() {
    System.out.println("execute when RuleB");
    return true;
}

@Action
public void then() {
    System.out.println("execute then RuleB");
}

@Priority
public int getPriority() {
   return this.priority;

} }

public class Launcher { public void doLounch(){ // create a rule set Rules rules = new Rules();
rules.register(new RuleA(1)); rules.register(new RuleB(0));

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

    rulesEngine.fire(rules, new Facts());
}

}

Output execute when RuleB execute then RuleB execute when RuleA execute then RuleA

daidai21 commented 3 years ago

Launcher.java should like this:

public class Launcher {
    public static void main(String[] args) throws Exception {
        // create a rule set
        Rules rules = new Rules();
        rules.register(new RuleA(1));
        rules.register(new RuleB(0));

        //create a default rules engine and fire rules on known facts
        RulesEngineParameters rulesEngineParameters = new RulesEngineParameters();
        rulesEngineParameters.setSkipOnFirstAppliedRule(true);

        RulesEngine rulesEngine = new DefaultRulesEngine(rulesEngineParameters);

        rulesEngine.fire(rules, new Facts());
    }
}

run log:

/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/bin/java -Dfile.encoding=UTF-8 -classpath /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/lib/tools.jar:/Users/fwh/Documents/git-repo/easy-rules_issue_341/target/classes:/Users/fwh/Documents/mavenRepo/org/jeasy/easy-rules-core/4.1.0/easy-rules-core-4.1.0.jar:/Users/fwh/Documents/mavenRepo/org/slf4j/slf4j-api/1.7.5/slf4j-api-1.7.5.jar:/Users/fwh/Documents/mavenRepo/org/slf4j/slf4j-log4j12/1.7.5/slf4j-log4j12-1.7.5.jar:/Users/fwh/Documents/mavenRepo/log4j/log4j/1.2.17/log4j-1.2.17.jar com.issue.debug.Launcher
debug Engine parameters { skipOnFirstAppliedRule = true, skipOnFirstNonTriggeredRule = false, skipOnFirstFailedRule = false, priorityThreshold = 2147483647 }
0    [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine  - Engine parameters { skipOnFirstAppliedRule = true, skipOnFirstNonTriggeredRule = false, skipOnFirstFailedRule = false, priorityThreshold = 2147483647 }
0    [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine  - Registered rules:
1    [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine  - Rule { name = 'Rule B', description = 'when when then then', priority = '0'}
1    [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine  - Rule { name = 'Rule A', description = 'Always return true', priority = '1'}
1    [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine  - Known facts:
1    [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine  - Rules evaluation started
execute when RuleB
4    [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine  - Rule 'Rule B' triggered
execute then RuleB
5    [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine  - Rule 'Rule B' performed successfully
5    [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine  - Next rules will be skipped since parameter skipOnFirstAppliedRule is set

Process finished with exit code 0

rulesEngine.getParameters().setSkipOnFirstAppliedRule(true); can't set parameters of ruleEngine.

Your code run log:

image

You should first step is create RulesEngineParameters, then createRulesEngine.

daidai21 commented 3 years ago

https://github.com/j-easy/easy-rules/blob/6de08b45a9f39bb240b563e72ad58afa93400ee6/easy-rules-core/src/main/java/org/jeasy/rules/core/AbstractRulesEngine.java#L56-L68

The return value of the function is a copy value

davidbzkm commented 3 years ago

Thank you !!!!

shabir1 commented 2 years ago

@davidbzkm Can we set default action if none of the rules are triggered?