Drools 中的通用 类-WorkBench

Generic classes within Drools-WorkBench

我目前正在做一个项目,该项目要求输入 Drools-Workbench 进行验证,是通用的。

所以本质上应该发生以下情况;

  1. 从 RabbitMQ 通道接收对象。
  2. 使用 Drools-WB 验证对象。
  3. 将验证结果(从 Drools-WB 获得)上传到 RabbitMQ 通道。

我有以下class,其中input是“通用部分”,ruleSet应该指定应该使用哪个规则sheet Drools-WB实例。

public class InputObject {


    private Integer primaryKey;

    private Integer sessionId;

    private Integer transactionId;

    private String ruleSet;

    private Map<String, Object> input;

    private List<ValidationResult> validationResults;
    public void addValidationResult(ValidationResult validationResult) {
        this.validationResults.add(validationResult);
    }
    // [...]
}

这是使用 KieServicesClient 为 JAVA 提交到我的 Drools-WB 实例,使用以下命令:

KieCommands commandFactory = kieServices.getCommands();
commands.add(commandFactory.newInsert(inputObject, "ValRes"));
commands.add(commandFactory.newFireAllRules());

BatchExecutionCommand batchExecutionCommand = commandFactory.newBatchExecution(commands, conf.getKieSession());

ServiceResponse<ExecutionResults> response = this.createRulesClient()
        .executeCommandsWithResults(inputObject.getRuleSet(), batchExecutionCommand);
ExecutionResults singleRes = response.getResult();

规则在 .xlsx 文件中指定,这样“非技术”人员应该可以“更容易”地提交规则。 目前应用以下规则; 尽管使用此配置总是抛出空异常,无论我如何为 input 变量赋值。

除此之外,我尝试简单地让一个新对象继承自 LinkedHashMap,就像这样;

public class DroolsObject extends LinkedHashMap<String, Object> {


    public void addValidationResult(ValidationResult validationResult) {
        if (!this.containsKey("validationResult"))
            this.put("validationResult", new LinkedList<ValidationResult>());
        ((List<ValidationResult>) this.get("validationResult")).add(validationResult);
    }
}

其中 input 只是此 DroolsObject class 的一个实例。 使用此配置,可以在 Drools .xlsx sheet 中使用关键字 this,如下所示;

但是使用这种配置,规则只是被执行,无论 DyrAlder 的值是多少,规则都不会被触发。

我知道函数 addValidationResult 在这种情况下工作,因为我已经设法收到结果,当我创建一个 class 时,在其中测试的变量被赋予 pr。默认。

所以我的问题是这样的; 我还没有真正找到任何与推广 Drools class 相关的内容,所以如果我对这种方法很满意,或者是否有另一种方法,我希望得到一些答案? 也许有一个我发送到 Drools-WB 的 HashMap,然后覆盖 class,以便它可以使用 Drools-WB 存储库中指定的特定 class。

无论如何,节日快乐,提前感谢您花时间回答这个问题!

只有当我在没有正确初始化的情况下插入对象时,我才能够为第一个示例重现 NullPointerException。对于第二种情况,确实,this["DyrAlder"] < $param 不起作用,但 this.get("DyrAlder") < $paramthis.DyrAlder < $param 甚至 DyrAlder < $param 对我都有效。

根据您的描述,我使用所需的 ruleSet 参数使您的规则复杂化,以获得符合您要求的工作 POC。在插入的 10 个对象中,只有 5 个符合条件 DyrAlder < 5,只有 1 个符合 ruseSet == "set3",因此您只触发了一次规则。

测试 1 (InputObject)

@DroolsSession(resources = "draft/inputObjectExample.xlsx",
        builderProperties = "drools.dump.dir = target/dump",
        showStateTransitionPopup = true)
public class PlaygroundTest extends DroolsAssert {
    
    @RegisterExtension
    public DroolsAssert droolsAssert = this;
    
    @Test
    @TestRules(expectedCount = { "1", "Check_DyrAlder" })
    public void testInputObjectExample() {
        KieCommands commandFactory = KieServices.get().getCommands();
        List<Command<?>> commands = new ArrayList<>();
        
        for (int i = 0; i < 10; i++) {
            InputObject inputObject = new InputObject();
            inputObject.setTransactionId(i);
            inputObject.setRuleSet("set" + i);
            inputObject.setInput(ImmutableMap.of("DyrAlder", i));
            inputObject.setValidationResults(new ArrayList<>());
            
            commands.add(commandFactory.newInsert(inputObject, "ValRes"));
            commands.add(commandFactory.newFireAllRules());
        }
        
        commands.forEach(c -> getSession().execute(c));
    }
}

决定table

生成的规则

package draft;
//generated from Decision Table
import draft.InputObject;
import draft.ValidationResult;
// rule values at A9, header at A4
rule "Check_DyrAlder"
    when
        animal:InputObject(ruleSet == "set3", input["DyrAlder"] < 5)
    then
        animal.addValidationResult(new ValidationResult("HDY-08277", "message"));
end

型号

public class InputObject {
    private Integer primaryKey;
    private Integer sessionId;
    private Integer transactionId;
    private String ruleSet;
    private Map<String, Object> input;
    private List<ValidationResult> validationResults;
    // getters/setters

测试 2 (DroolsObject)

@DroolsSession(resources = "draft/droolsObjectExample.xlsx",
        builderProperties = "drools.dump.dir = target/dump",
        showStateTransitionPopup = true)
public class PlaygroundTest extends DroolsAssert {
    
    @RegisterExtension
    public DroolsAssert droolsAssert = this;
    
    @Test
    @TestRules(expectedCount = { "1", "Check_DyrAlder" })
    public void testDroolsObjectExample() {
        KieCommands commandFactory = KieServices.get().getCommands();
        List<Command<?>> commands = new ArrayList<>();
        
        for (int i = 0; i < 10; i++) {
            DroolsObject inputObject = new DroolsObject();
            inputObject.put("ruleSet", "set" + i);
            inputObject.put("DyrAlder", i);
            
            commands.add(commandFactory.newInsert(inputObject, "ValRes"));
            commands.add(commandFactory.newFireAllRules());
        }
        
        commands.forEach(c -> getSession().execute(c));
    }
}

决定table

生成的规则

package draft;
//generated from Decision Table
import draft.DroolsObject;
import draft.ValidationResult;
// rule values at A9, header at A4
rule "Check_DyrAlder"
    when
        animal:DroolsObject(ruleSet == "set3", DyrAlder < 5)
    then
        animal.addValidationResult(new ValidationResult("HDY-08277", "message"));
end

型号

public class DroolsObject extends LinkedHashMap<String, Object> {
    public void addValidationResult(ValidationResult validationResult) {
        if (!this.containsKey("validationResult"))
            this.put("validationResult", new LinkedList<ValidationResult>());
        ((List<ValidationResult>) this.get("validationResult")).add(validationResult);
    }
}