Drools 中的通用 类-WorkBench
Generic classes within Drools-WorkBench
我目前正在做一个项目,该项目要求输入 Drools-Workbench 进行验证,是通用的。
所以本质上应该发生以下情况;
- 从 RabbitMQ 通道接收对象。
- 使用 Drools-WB 验证对象。
- 将验证结果(从 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") < $param
、this.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);
}
}
我目前正在做一个项目,该项目要求输入 Drools-Workbench 进行验证,是通用的。
所以本质上应该发生以下情况;
- 从 RabbitMQ 通道接收对象。
- 使用 Drools-WB 验证对象。
- 将验证结果(从 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") < $param
、this.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);
}
}