Drools 决定 table - 规则不匹配

Drools decision table - rules not matching

我有一个 hello-world 类型 spring/drools 设置。问题是理论上应该触发的规则没有触发。

决定Table:

控制台输出 - 服务器启动:

package com.example.drools;
//generated from Decision Table
import com.example.drools.TestRules;
// rule values at B9, header at B4
rule "_9"
    when
        $test:TestRules(number1 == 10)
    then
        $test.add("10");
end

Drools 配置:

@Configuration
public class DroolsConfiguration
{
  private final static String VALIDATION_RULES = "validation-rules.xls";
                                                   

  @Bean
  public KieContainer validationRulesKieContainer() {
    KieServices kieServices = KieServices.Factory.get();
    Resource rules = ResourceFactory.newClassPathResource(VALIDATION_RULES);
    
    compileXlsToDrl(rules);
    
    KieFileSystem kieFileSystem = kieServices.newKieFileSystem().write(rules);
    KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
    KieBuilder builder = kieBuilder.buildAll();
    
    KieModule kieModule = kieBuilder.getKieModule();
    return kieServices.newKieContainer(kieModule.getReleaseId());        
  }

  private static void compileXlsToDrl(Resource resource) {
    try {
        InputStream is = resource.getInputStream();
        SpreadsheetCompiler compiler = new SpreadsheetCompiler();
        String drl = compiler.compile(is, InputType.XLS);
        System.out.println(drl);            
    } catch (Exception e) {
        e.printStackTrace();
    }
  }
}

服务:

@Service
public class ValidationRulesEngine
{
    @Autowired
    @Qualifier("validationRulesKieContainer")
    private KieContainer validationKieContainer;
    
    public void validate() {
        KieSession kieSession = validationKieContainer.newKieSession();
        
        kieSession.addEventListener(new DebugAgendaEventListener());
        kieSession.addEventListener(new DebugRuleRuntimeEventListener());
        
        TestRules tr = new TestRules(10, 20, 30);
        
        kieSession.insert(tr);
        int noOfRulesFired = kieSession.fireAllRules();
        
        System.out.println("noOfRulesFired: " + noOfRulesFired);
        System.out.println(tr);
        System.out.println(tr.getRule());                
    }
}

测试规则 - 事实:

public class TestRules
{    
    public int number1;
    public int number2;
    public int number3;
    public List<String> rules = new ArrayList<String>();
    
    public TestRules() {}
    
    public TestRules(int number1, int number2, int number3)
    {
        super();
        this.number1 = number1;
        this.number2 = number2;
        this.number3 = number3;
    }

    public void add(String rule) {  
        rules.add(rule);
    }
    
    public String getRule() {
        return this.rules.size() > 0 ? this.rules.get(0) : "";
    }
    
    @Override
    public String toString()
    {
        return "TestRules [number1=" + number1 + ", number2=" + number2 + ", number3=" + number3 + ", rules=" + 
                rules.stream().map(s -> s.toString()).collect(Collectors.joining(",")) + "]";
    }          
}

控制台输出 - 结果:

2021-07-20 17:02:27.549 ERROR 20212 --- [nio-9016-exec-1] c.g.i.e.p.c.OfficeController             : --> Rules Engine
==>[ObjectInsertedEventImpl: getFactHandle()=[fact 0:1:1539328290:1539328290:1:DEFAULT:NON_TRAIT:com.example.drools.TestRules:TestRules [number1=10, number2=20, number3=30, rules=]], getObject()=TestRules [number1=10, number2=20, number3=30, rules=], getKnowledgeRuntime()=KieSession[0], getPropagationContext()=PhreakPropagationContext [entryPoint=EntryPoint::DEFAULT, factHandle=[fact 0:1:1539328290:1539328290:1:DEFAULT:NON_TRAIT:com.example.drools.TestRules:TestRules [number1=10, number2=20, number3=30, rules=]], leftTuple=null, originOffset=-1, propagationNumber=2, rule=null, type=INSERTION]]
noOfRulesFired: 0
TestRules [number1=10, number2=20, number3=30, rules=]

2021-07-20 17:02:28.454 ERROR 20212 --- [nio-9016-exec-1] c.g.i.e.p.c.OfficeController             : <-- Rules Engine

我错过了什么?

这不行:

$test:TestRules($test.number1 == 10, $test.number2 == 20)

声明前不能引用$test。正确的语法是:

$test: TestRules( number1 == 10, number2 == 20 )

将您的决定 table 从 $test.number1 == $param 改为 number1 == $param。 (对相邻的 number2 执行相同的操作。)

其余的看起来不错,但我建议在您的 XLSX 解析方法中使用 try-with-resources 而不是 try-catch。