使用规则单元 API 在运行时添加新规则

问题描述 投票:0回答:1

正在尝试在运行时切换到一组新规则。是否可以使用规则单元 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 门户的文档并提供链接。甚至不确定这是否是我需要的

java drools
1个回答
0
投票

到目前为止,我已经辞职尝试使用 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();
    }
}
  1. getKieContainer() 创建一个 KieContainer,稍后用于启动新会话和触发规则
  2. 一旦我更新了目录中的规则,就会调用rebuildKieContainer()。
建议的实现有效并满足了我的要求,但是我在有关创建 KieBase 的日志消息中看到了一个奇怪的交互 - 我预计也会在“重建”后收到此消息,但只有当我直接调用 getKieContainer() 时才会发生这种情况在我的筛选中。

不能将其视为第一个问题的答案,但如果有人会发现这很有用 - 那就太好了。

© www.soinside.com 2019 - 2024. All rights reserved.