Drools在运行时禁用规则

Drools在运行时禁用规则,drools,rule-engine,Drools,Rule Engine,我要开始一个让古夫诺流口水的项目 我的规则部署在drools guvnor中。我的规则引擎实例可以通过drools Guvnor公开的pkg文件访问这些规则,当您执行包发布构建和发布时 这一切都很好,我要寻找的是一个在运行时禁用规则的解决方案 我现在唯一的解决方案是转到guvnor,归档规则,并对包含该规则的包进行构建+发布 难道没有其他策略吗?你可以在工作记忆中添加一些事实存在的条件。 比如: rule "RuleA" when not( RuleADisabled() ) ....

我要开始一个让古夫诺流口水的项目

我的规则部署在drools guvnor中。我的规则引擎实例可以通过drools Guvnor公开的pkg文件访问这些规则,当您执行包发布构建和发布时

这一切都很好,我要寻找的是一个在运行时禁用规则的解决方案

我现在唯一的解决方案是转到guvnor,归档规则,并对包含该规则的包进行构建+发布


难道没有其他策略吗?

你可以在工作记忆中添加一些事实存在的条件。 比如:

rule "RuleA"
when
  not( RuleADisabled() )
  ....
then
  ....
end
并禁用java代码中的规则:

ksession.insert( new RuleADisabled() );

有几种方法可以解决这个问题,具体取决于您的需求和体系结构

  • 一种方法是在不同的guvnor包中定义规则的每个子集。在构建kbase时,您只能加载具有特定kbase规则的包

  • 另一种方法是始终加载所有规则,但使用“enabled”表达式动态启用/禁用规则。请注意,本例中的规则仍在评估中,但可以阻止其激活。对于希望根据插入会话的事实启用/禁用规则的情况,这是一种有用的技术。例如:

    规则十 启用() 然后

    上面的布尔表达式可以从规则的条件以及规则属性、注释中访问变量绑定,如果要定义条件以激活DRL文件外部的规则,显然还可以访问帮助器类中的静态方法

  • 第三种方法是使用议程过滤器。在这种情况下,加载所有规则,使用事实创建会话,执行规则时使用议程过滤器。议程过滤器是一个接口,您可以自己实现,也可以使用Drools附带的一些过滤器。在触发每个规则之前调用过滤器,然后可以否决或允许引擎执行规则。请注意,在这种情况下,所有规则都会被评估和激活,但只有筛选器允许触发的规则才会被触发。例如,如果您只想触发名称以“X”开头的规则,可以使用以下代码行:

    ksSession.fireAllRules(新规则名称开始SwitchGendaFilter(“x”))

    有关更多信息,请参见以下界面:

    以下是文档(向下滚动至主题3.3.3.4.1):


谢谢,但这意味着对于每个新规则,我必须创建一个新类型的事实规则名称Disabled。每次我执行我的规则时,我首先必须插入禁用的规则事实。您可以只创建一种类型的事实,例如,RuleDisabled带有属性ruleName,或者多个规则可能依赖于同一事实,例如,not(RuleDisabled(group==“groupX”))谢谢,实际上我尝试了您建议的第二种方法,如本文所述:。当我的规则从文件系统加载时,它工作得很好,但当规则部署在Guvnor中时就不行了。在这种情况下,我在org.drools.base.mvel.MVELCompilationUnit.createFactory(MVELCompilationUnit.java:262)的org.drools.base.mvel.MVELCompilationUnit.getFactory(MVELCompilationUnit.java:276)中有一个NPE:java.lang.NullPointerException,这是一个bug。无论从何处加载,它都应该工作相同。如果您可以打开一个问题单来解决问题,那就太好了。您可以提供一个在enabled()函数中使用规则自身注释的示例吗?我从Drools源代码(test_enabledExpressions.drl)获得了一个示例:
enabled(rule.metaData[“ruleID”]=“1234”)