1

I need to enable / disable certain rules from drl file based on data from the backend . i.e enable Rule 1,2,3 for Dubai , Enable 1,3 for Singapore So , I pass drools.getRule().getName() as below.

rule "Apply 50% discount to VIP customers"
    enabled (checkenabled(drools.getRule().getName()))
when
    $s : Sale( customer.type == CustomerType.VIP )  
then
$s.setDiscount(0.50);
    System.out.println("VIP discount applied1" + drools.getRule().getName());
end

I am getting below error on this .

Exception in thread "main" [Error: null pointer: drools.rule.name]
[Near : {... checkenabled(drools.rule.name) ....}]
                          ^
[Line: 1, Column: 14]
    at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:427)
    at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeAccessor(ReflectiveAccessorOptimizer.java:140)
    at org.mvel2.ast.ASTNode.optimize(ASTNode.java:159)
    at org.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:115)
    at org.mvel2.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:38)
    at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getMethod(ReflectiveAccessorOptimizer.java:948)
    at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:373)
    at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeAccessor(ReflectiveAccessorOptimizer.java:140)
    at org.mvel2.ast.ASTNode.optimize(ASTNode.java:159)
    at org.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:115)
    at org.mvel2.MVELRuntime.execute(MVELRuntime.java:86)
    at org.mvel2.compiler.CompiledExpression.getDirectValue(CompiledExpression.java:123)
    at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:119)
    at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:113)
    at org.mvel2.MVEL.executeExpression(MVEL.java:930)
    at org.drools.core.base.mvel.MVELEnabledExpression.getValue(MVELEnabledExpression.java:92)
    at org.drools.core.definitions.rule.impl.RuleImpl.isEffective(RuleImpl.java:384)
    at org.drools.core.phreak.RuleExecutor.cancelAndContinue(RuleExecutor.java:326)
    at org.drools.core.phreak.RuleExecutor.fire(RuleExecutor.java:142)
    at org.drools.core.phreak.RuleExecutor.evaluateNetworkAndFire(RuleExecutor.java:94)
    at org.drools.core.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:964)
    at org.drools.core.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1234)
    at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1239)
    at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1212)
    at com.emirates.App.testGoodCustomer(App.java:95)
    at com.emirates.App.main(App.java:74)
Caused by: java.lang.NullPointerException
    at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:393)
    ... 25 more
Werner Kvalem Vesterås
  • 10,226
  • 5
  • 43
  • 50
Hardik Amlani
  • 11
  • 1
  • 2
  • Please format your code. – shauryachats Jan 27 '15 at 08:01
  • Creating application logic based on the name of the rule is extremely fragile. You should really be building such logic into your rules. That's what they're for! Therefore, I suspect that any answer to this specific question is highly unlikely to be a good solution to the actual problem. – Steve Jan 27 '15 at 09:20
  • Note for the folks who seem to be voting to close this question as "Unclear what you're asking". For anyone familiar with Drools, it's completely clear what the OP is asking. – Steve Jan 27 '15 at 09:23
  • Can I pass drools.getName().getRule() as a parameter to the java method handling enabled attribute as seen in code above . If yes , please help on it . Dats where i am stuck. – Hardik Amlani Jan 27 '15 at 10:26

2 Answers2

0

Why aren't you using the AgendaFilter ?

Quite easy to use, can be done in the Java part like this :

AgendaFilter myFilter = new RuleNameStartsWithAgendaFilter("DUBAI");
mySession.fireAllRules(filter);

myFilter = new RuleNameStartsWithAgendaFilter("SINGAPORE");
mySession.fireAllRules(filter);

There are multiple variants of the AgendaFilter :

  • StartsWith
  • EndsWith
  • Contains
  • Matches

My not be exactly what you need but it might be a hint ;-)

Ethenyl
  • 666
  • 11
  • 20
  • Hey Etenyl, Thanks for the solution . It is 70% near to my requirement . I need to pass rule -name to the java file from enabled(checkenabled(drools.getRule().getName()). Checkenabled is java function that enables/disables rule based on the rulename passed to it as parameter.But while passing drools.getRule().getName() as parameter it gives above error. while same works good in RHS. – Hardik Amlani Jan 27 '15 at 08:24
0

It looks like a good case for the "declarative agenda" feature. This is based on rules being used to block rules. Here is a simple example:

import org.kie.api.runtime.rule.Match;
rule "Apply 50% discount"
  @Eager                     // required for each rule to be blocked
  @Category("Singapore")
when
  $s : Sale( article matches ".*PX" ) // anything
then
  System.out.println("VIP: " + drools.getRule().getName());
end

rule "CheckBlock"
  @Direct @Eager // required for each rule that blocks
when
  Location( $country: country )
  // $m: Match( Category == "Singapore" )
  $m: Match( rule.name == "Apply 50% discount" )
then
  kcontext.blockMatch( $m );
end

Location is a simple bean. As shown, the blocking rule may access the "Match" object which (magically) lets you match against metadata or the rule name. Of course, evaluation may access some method in Location for more sophisticated checks of the rule name.

Note that you need to set an option:

 KieBaseConfiguration config = ks.newKieBaseConfiguration();
 config.setOption( DeclarativeAgendaOption.ENABLED );

or use the kmodule XML (see the documentation).

laune
  • 31,114
  • 3
  • 29
  • 42