9

I'm starting a project whith Drools and Drools Guvnor.

My rules are deployed in drools guvnor. My rule engine instance can access those rules via the pkg file exposed by drools Guvnor when you do a package release build and release.

This is all working fine, what I'm looking for is a solution for disabling a rule at runtime.

The only solution I have right now is to go to guvnor, archive the rule and do a build + release of the package containing that rule.

Isn't there another strategy ?

fastcodejava
  • 35,219
  • 24
  • 124
  • 181
Frederic Close
  • 8,715
  • 5
  • 52
  • 64

2 Answers2

7

There are a few ways of solving this, depending on your requirements and architecture.

  • One way is to define each subset of your rules in different guvnor packages. When building your kbase, you can load only the packages with the rules you want for that kbase in particular.

  • Another way is to always load all the rules, but use an "enabled" expression do dynamically enable/disable rules. Please note that the rules in this case are still evaluated, but they can be prevented from activating. This is a useful technique for cases where you want to enable/disable rules based on the facts you insert into your session. E.g.:

    rule X enabled( ) then ...

    The boolean expression above has access to the variable bindings from the condition of your rule, as well as rule attributes, annotations and obviously you can also access static methods in helper classes if you want to define the conditions to activate the rule external to the DRL file.

  • A third way of doing it is by using agenda filters. In this case you load all your rules, create the session with the facts and when executing the rules you use an agenda filter. An agenda filter is an interface that you can implement yourself or you can use some of the filters that ship with Drools. The filter is called before firing each rule and can then veto or allow the engine to execute the rule. Please note that in this case all rules are evaluated and activated, but only the rules that the filter allows to fire will be fired. E.g., if you want to fire only the rules which have a name that start with "X", you can use the following line of code:

    ksession.fireAllRules( new RuleNameStartsWithAgendaFilter("x") );

    For more info, here is the interface:

    https://github.com/droolsjbpm/droolsjbpm-knowledge/blob/master/knowledge-api/src/main/java/org/drools/runtime/rule/AgendaFilter.java

    Here is the documentation (Scroll down to topic 3.3.3.4.1):

    http://docs.jboss.org/drools/release/5.4.0.Final/drools-expert-docs/html_single/index.html#d0e2792

Edson Tirelli
  • 3,776
  • 17
  • 22
  • Thanks, actually I tried the second way you proposed like explained on this blog post : http://fusionspan.blogspot.com/2012/02/jboss-drools-disabling-certain-rules.html. It worked fine when my rules were loaded from the file system, but not when the rule were deployed in Guvnor. In that case I had a NPE: java.lang.NullPointerException at org.drools.base.mvel.MVELCompilationUnit.createFactory(MVELCompilationUnit.java:262) at org.drools.base.mvel.MVELCompilationUnit.getFactory(MVELCompilationUnit.java:276) – Frederic Close Jun 01 '12 at 16:45
  • That is a bug. It should work the same not matter where it is loaded from. It would be great if you can open a ticket with your problem so that it can be fixed. – Edson Tirelli Jun 01 '12 at 18:17
  • Can provide an example of using rule's own annotations in enabled() function? – Infeligo Oct 26 '14 at 15:07
  • I got an example from Drools source (test_enabledExpressions.drl):`enabled ( rule.metaData["ruleID"] == "1234" )` – Infeligo Dec 22 '14 at 19:44
1

You may add condition to existence of some fact in working memory. Something like:

rule "RuleA"
when
  not( RuleADisabled() )
  ....
then
  ....
end

and disable the rule in java code:

ksession.insert( new RuleADisabled() );
Cyril Sochor
  • 652
  • 6
  • 9
  • Thanks, but this means that for each new rule I have to create a new type of fact RuleNameDisabled. Each time I will execute my rules I'll first have to insert the disabled rule facts. – Frederic Close Jun 01 '12 at 10:35
  • You may create only one type of fact e.g. RuleDisabled with attribute ruleName or multiple rules may depend on same fact e.g. not(RuleDisabled( group=="groupX")) – Cyril Sochor Jun 01 '12 at 13:44