简体   繁体   English

流口水总是真正的规则只触发一次

[英]drools always true rule fires only once

I have these 2 rules :我有这两条规则:

rule "challenge 1" salience 10
    when
        ClientTransaction(amount < 30)
    then
        challenge.setChallenge("challenge1");
end

rule "challenge 2" salience 0
    when
        eval( true )
    then
        challenge.setChallenge("challenge2");
end

and this java code :和这个java代码:


public class ComputeChallengeDroolsRulesImplementation implements IComputeChallenge {
    private KieServices kieServices = KieServices.Factory.get();
    private KieSession kieSession = getKieSession();
    private static final String RULES_PATH = "rules/";

    public KieFileSystem getKieFileSystem() throws IOException {
        KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
        String[] rules = new File(getClass().getClassLoader().getResource(RULES_PATH).getFile()).list();
        for (String rule : rules) {
            kieFileSystem.write(ResourceFactory.newClassPathResource(RULES_PATH + rule));
        }
        return kieFileSystem;
    }

    public KieContainer getKieContainer() throws IOException {
        getKieRepository();

        KieBuilder kb = kieServices.newKieBuilder(getKieFileSystem());
        kb.buildAll();

        KieModule kieModule = kb.getKieModule();
        KieContainer kContainer = kieServices.newKieContainer(kieModule.getReleaseId());

        return kContainer;
    }

    public void getKieRepository() {
        final KieRepository kieRepository = kieServices.getRepository();
        kieRepository.addKieModule(
                new KieModule() {
                    public ReleaseId getReleaseId() {
                        return kieRepository.getDefaultReleaseId();
                    }
                });
    }

    @Bean
    public KieSession getKieSession() {
        try {
            return getKieContainer().newKieSession();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Challenge2 computeChallenge(ClientTransaction clientTransaction) {
        kieSession.insert(clientTransaction);
        Challenge2 challenge = new Challenge2();
        kieSession.setGlobal("challenge", challenge);
        kieSession.fireAllRules();
        return challenge;
    }

}

here is the ClientTransation class :这是 ClientTransation 类:


public class ClientTransaction {
  private String id;
  private String merchant;
  private double amount;

  public ClientTransaction() {
  }

  public ClientTransaction(String id, String merchant, double amount) {
    this.id = id;
    this.merchant = merchant;
    this.amount = amount;
  }

  public String getId() {
    return id;
  }

  public void setId(String id) {
    this.id = id;
  }

  public String getMerchant() {
    return merchant;
  }

  public void setMerchant(String merchant) {
    this.merchant = merchant;
  }

  public double getAmount() {
    return amount;
  }

  public void setAmount(double amount) {
    this.amount = amount;
  }
}

And here is the Challenge2 class :这是 Challenge2 类:


public class Challenge2 {
  private String challenge;

  public Challenge2() {
  }

  public Challenge2(String challenge) {
    this.challenge = challenge;
  }

  public String getChallenge() {
    return challenge;
  }

  public void setChallenge(String challenge) {
    this.challenge = challenge;
  }
}


when i call ComputeChallengeDroolsRulesImplementation.computeChallenge with an amount < 30 multiple times, it does return a challence object with a "challenge1" value multiple times as expected.当我多次调用 ComputeChallengeDroolsRulesImplementation.computeChallenge 并且数量 < 30 时,它确实按预期多次返回具有“challenge1”值的挑战对象。

But when i call ComputeChallengeDroolsRulesImplementation.computeChallenge with an amount >= 30 multiple times, the first time it does return a "challenge2" value, but every subsequent time it return a Challenge2 object with a null value ?但是当我多次调用 ComputeChallengeDroolsRulesImplementation.computeChallenge >= 30 时,它第一次确实返回“challenge2”值,但随后每次它返回一个带有空值的 Challenge2 对象?

Am i doing something wrong ?难道我做错了什么 ?

Thank you谢谢

I am assuming you want to fire challenge 2 rule only when ClientTransaction event occurs.我假设您只想在ClientTransaction事件发生时触发挑战 2规则。 You can add a no condition check on a rule based on the occurrence of an event by just calling default constructor in the when part of a drool rule.您可以通过在 drool 规则的 when 部分调用默认构造函数,根据事件的发生对规则添加无条件检查。 Try changing you challenge 2 rule as below:尝试改变你的挑战 2规则如下:

rule "challenge 2" salience 0
    when
        ClientTransaction()
    then
        challenge.setChallenge("challenge2");
end

Also, it is not recommended to use eval so much in the drools rule.另外,不建议在drools规则中过多使用eval To more about best practices, check here有关最佳实践的更多信息,请查看此处

As the following documentation states: https://docs.jboss.org/drools/release/5.2.0.Final/drools-expert-docs/html/ch05.html#d0e3313如以下文档所述: https : //docs.jboss.org/drools/release/5.2.0.Final/drools-expert-docs/html/ch05.html#d0e3313

The engine cannot be notified about value changes of globals and does not track their changes.引擎无法收到有关全局变量值更改的通知,也不会跟踪它们的更改。 Incorrect use of globals in constraints may yield surprising results - surprising in a bad way.在约束中不正确使用全局变量可能会产生令人惊讶的结果 - 以一种糟糕的方式令人惊讶。

[…] […]

Globals are not designed to share data between rules and they should never be used for that purpose.全局变量不是为了在规则之间共享数据而设计的,它们永远不应该用于该目的。 Rules always reason and react to the working memory state, so if you want to pass data from rule to rule, assert the data as facts into the working memory.规则总是对工作记忆状态进行推理和反应,因此如果您想从规则到规则传递数据,请将数据作为事实断言到工作记忆中。

It is strongly discouraged to set or change a global value from inside your rules .强烈建议不要从规则内部设置或更改全局值 We recommend to you always set the value from your application using the working memory interface.我们建议您始终使用工作内存接口从您的应用程序中设置值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM