首页 > 解决方案 > 在运行时动态更新规则。Drools + Spring-Boot

问题描述

所以目前我正在练习使用 Drools (7.13.0.Final) 和 Spring-boot(1.5.12.RELEASE)。我在 Spring-boot 中制作了一个示例应用程序,其中包含以下类

模型:TaxiFare.java

@Data
public class TaxiFare {
    private double surge;
    private double netFare;
    private double baseFare;
    private double distanceTraveled;
}

服务:TaxiFareService.java

@Service
public class TaxiFareService {

    @Autowired
    private KieContainer kieContainer;


    public TaxiFare getTaxiFare(TaxiFare fare) {

        KieSession kieSession = kieContainer.newKieSession("rulesSession");

        kieSession.insert(fare);
        kieSession.fireAllRules();
        kieSession.dispose();
        return fare;
    }
}

休息控制器:TaxiFareController.java

@RestController
public class TaxiFareController {

    @Autowired
    private TaxiFareService taxiFareService;

    @RequestMapping(value = "/getFare", method = RequestMethod.GET)
    public String getQuestions(@RequestParam(required = true) double baseFare, @RequestParam(required = true) double surge, @RequestParam(required = true) double distanceTraveled) {

        TaxiFare fare = new TaxiFare();
        fare.setBaseFare(baseFare);
        fare.setSurge(surge);
        fare.setDistanceTraveled(distanceTraveled);

        taxiFareService.getTaxiFare(fare);

        return String.format("NET FARE IS: %s", fare.getNetFare());
    }


}

配置:

@Bean
public KieContainer kieContainer2() {
    return KieServices.Factory.get().getKieClasspathContainer();
}

具有定义的规则

rule "No Surge"
    when
        $fareObject: TaxiFare(surge == 0.0);
    then
        $fareObject.setNetFare($fareObject.getBaseFare() * $fareObject.getDistanceTraveled());
end
rule "Has Surge"
    when
        $fareObject: TaxiFare(surge > 0.0);
    then
        $fareObject.setNetFare($fareObject.getSurge() * $fareObject.getBaseFare() * $fareObject.getDistanceTraveled());
end

我已经使用我在网上找到的各种 Drools + Spring 集成教程构建了这个示例应用程序。目前,规则引擎可以正常工作,但我想要做的是每次添加新规则或修改现有规则时,我希望能够在应用程序运行时动态重新加载规则文件。该应用程序被打包为 WAR 并部署在 Web 服务器中。

我已经阅读了多篇关于使用的文章,KieScanner但没有一篇关于它的书面教程,甚至是文档本身。按照他们提供的示例代码,

KieScanner kieScanner = kieServices.newKieScanner(kieContainer);

总是导致构建失败,因为 newKieScanner 似乎无法根据提供的 kieContainer 创建 kieScanner。有没有其他方法可以为 Drools 设置动态规则或说明如何正确实施 KieScanner?

谢谢你。

标签: javaspringspring-bootdrools

解决方案


你可以试试这个,实际上效果很好

 @Test
public void messageRuleFromUTFString() {
 String ruleContent =
     "package rules\r\n"+
     "import mypackage.Message\r\n" +
         "rule \"myrule\"\r\n" +
        "    \twhen\r\n" +
        "        $id : Message([\"38196-2\"] contains id)\r\n" +
        "    then\r\n" +
        "\t\tSystem.out.println(\"Works!\");\r\n" +
        "end\r\n";
    KieSession kSession = null;
    try {
        KnowledgeBuilder kb = KnowledgeBuilderFactory.newKnowledgeBuilder();
        kb.add(ResourceFactory.newByteArrayResource(ruleContent.getBytes("utf-8")), ResourceType.DRL);

        KnowledgeBuilderErrors errors = kb.getErrors();
        for (KnowledgeBuilderError error : errors) {
            System.out.println(error);
        }
        InternalKnowledgeBase kBase = KnowledgeBaseFactory.newKnowledgeBase();
        kBase.addPackages(kb.getKnowledgePackages());
        kSession = kBase.newKieSession();
        kSession.insert(createMessage("38196-2"));
        kSession.fireAllRules();

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } finally {
        if (kSession != null)
            kSession.dispose();
    }
}

感谢其中一位 github 用户。我的例子稍微修改为最新版本的drools: https ://github.com/ityouknow/drools-examples.git


推荐阅读