正在尝试在运行时切换到一组新规则。是否可以使用规则单元 API 而不使用 KIE API 来实现?
当前文档指出“本章前面的部分解释了使用 Drools 规则引擎的传统 KIE API。但是,正如 First Rule Project 中所介绍的,规则单元是在 Drools 8 中实现规则的一种新的推荐样式。”但我是无法找到任何关于如何使用规则单元 API 执行此操作的解决方案。使用 KIE 的测试项目不使用规则单元数据,我自己无法使它们工作。
Rules.drl(要模拟新文件,只需从文件中删除“test_rule_2”
package rulesAndScenarios.services.ruleDrools;
unit TestRuleUnit;
import rulesAndScenarios.models.drools.*;
rule "test_rule_1"
when
/simpleObjects
then
System.out.println("test_rule_1 triggered");
end
rule "test_rule_2"
when
/simpleObjects
then
System.out.println("test_rule_2 triggered");
end
规则单元(TestRuleUnit):
package rulesAndScenarios.services.ruleDrools;
import org.drools.ruleunits.api.DataSource;
import org.drools.ruleunits.api.DataStore;
import org.drools.ruleunits.api.RuleUnitData;
public class TestRuleUnit implements RuleUnitData {
private final DataStore<String> simpleObjects;
public TestRuleUnit() {
this(DataSource.createStore());
}
public TestRuleUnit(DataStore<String> simpleObjects) {
this.simpleObjects = simpleObjects;
}
public DataStore<String> getSimpleObjects() {
return simpleObjects;
}
}
我尝试过做的事情:
1.创建两个实例并将新文件添加到目录中:
测试:
public void testSimpleRule() throws Exception {
TestRuleUnit testRuleUnit = new TestRuleUnit();
testRuleUnit.getSimpleObjects().add("test_1");
RuleUnitInstance<TestRuleUnit> instance = RuleUnitProvider.get().createRuleUnitInstance(testRuleUnit);
try {
instance.fire();
} finally {
instance.close();
}
Files.move(Paths.get("C:/Java folder/testRules2.drl"), Paths.get("C:/Users/aleks/my-project/target/classes/testRules.drl"), StandardCopyOption.REPLACE_EXISTING);
TestRuleUnit testRuleUnit2 = new TestRuleUnit();
testRuleUnit2.getSimpleObjects().add("test_1");
RuleUnitInstance<TestRuleUnit> instance2 = RuleUnitProvider.get().createRuleUnitInstance(testRuleUnit);
try {
instance2.fire();
} finally {
instance2.close();
}
}
通过以下测试,尽管创建了新实例并提供了新文件,但仍会根据之前的规则集检查该实例。
2.使用规则单元 API 来调整具有 KIE API 的现有测试项目,但无法使规则发挥作用 - 没有错误,但同时没有触发任何内容。规则本身是正确的,我已经在没有 KIE 会话的情况下通过简单测试进行了检查。有问题的项目 - https://www.baeldung.com/drools.
3.研究有关该问题的开源资源。找到以下线程https://groups.google.com/g/drools-usage/c/G6A3EMbec90,但无法理解应如何使用方法 invalidateRuleUnits,无法在该线程之外找到关于 Drools 门户的文档并提供链接。甚至不确定这是否是我需要的
到目前为止,我已经辞职尝试使用 RuleUnit API 来实现这一点。 回到传统语法和 Kie 的用法。
以下是任何感兴趣的人的解决方案:
@Component("FirstKieContainerConfigurationImpl")
public class FirstKieContainerConfigurationImpl implements KieContainerConfiguration {
private KieContainer kieContainer;
@Override
public synchronized KieContainer getKieContainer() {
if (kieContainer == null) {
KieServices kieServices = KieServices.Factory.get();
KieFileSystem kfs = kieServices.newKieFileSystem();
File ruleFile = new File("path_to_rules/TAXI_FARE_RULE.drl");
kfs.write(ResourceFactory.newFileResource(ruleFile));
KieBuilder kieBuilder = kieServices.newKieBuilder(kfs);
kieBuilder.buildAll();
if (kieBuilder.getResults().hasMessages(Message.Level.ERROR)) {
throw new RuntimeException("Errors while building KieModule: " + kieBuilder.getResults().getMessages());
}
KieModule kieModule = kieBuilder.getKieModule();
kieContainer = kieServices.newKieContainer(kieModule.getReleaseId());
}
return kieContainer;
}
@Override
public void rebuildKieContainer() {
kieContainer = null;
kieContainer = getKieContainer();
}
}
不能将其视为第一个问题的答案,但如果有人会发现这很有用 - 那就太好了。