在 Drools 6 中以编程方式创建新的 drools 规则的新接受方式是啥?

Posted

技术标签:

【中文标题】在 Drools 6 中以编程方式创建新的 drools 规则的新接受方式是啥?【英文标题】:What is the new accepted way of programmatically creating new drools rules in Drools 6?在 Drools 6 中以编程方式创建新的 drools 规则的新接受方式是什么? 【发布时间】:2015-02-18 15:33:26 【问题描述】:

简而言之,我想在运行时从规则存储库中创建、编辑和删除规则。我无法弄清楚如何在 drools 6+ 中执行此操作。

我知道在先前版本的 drools (https://docs.jboss.org/drools/release/5.6.0.Final/drools-expert-docs/html/ch04.html#d0e8052。

从 5.6 开始的 drools 文档表明此功能已弃用,并且似乎在 6 时已完全删除。我不想使用已知没有直接升级路径的 API。

由于工作流程要求和 Web 用户界面的复杂性,将 Guvnor 或 Workbench UI 暴露给用户以进行规则编辑也不适合此处。我想从 Java 代码创建和管理规则。

我想要一种比将字符串模板化为 .drl 文件更好的方法来创建新规则和修改规则。从 Java 以编程方式创建新规则有什么用?我做了很多搜索,但似乎找不到一组用于此的 Java API 调用。

【问题讨论】:

【参考方案1】:

我不知道这是否是“已接受”的方式,但使用以下代码,我将 .drl 文件与 Drools 6 中以编程方式创建的规则结合在一起。

public KieContainer build(KieServices kieServices) 
    KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
    ReleaseId rid = kieServices.newReleaseId("com.example.rulesengine", 
        "model-test", "1.0-SNAPSHOT");
    kieFileSystem.generateAndWritePomXML(rid);

    kieFileSystem.write("src/main/resources/rules.drl", 
        getResource(kieServices, "rules.drl"));

    addRule(kieFileSystem);

    KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
    kieBuilder.buildAll();
    if (kieBuilder.getResults().hasMessages(Message.Level.ERROR)) 
        throw new RuntimeException("Build Errors:\n" + 
           kieBuilder.getResults().toString());
    

    return kieServices.newKieContainer(rid);


private void addRule(KieFileSystem kieFileSystem) 
    PackageDescrBuilder packageDescrBuilder = DescrFactory.newPackage();
    packageDescrBuilder
            .name("com.example.model")
            .newRule()
            .name("Is of valid age")
            .lhs()
            .pattern("Person").constraint("age < 18").end()
            .pattern().id("$a", false).type("Action").end()
            .end()
            .rhs("$a.showBanner( false );")
            .end();

    String rules = new DrlDumper().dump(packageDescrBuilder.getDescr());
    kieFileSystem.write("src/main/resources/rule-1.drl", rules);


private Resource getResource(KieServices kieServices, String resourcePath) 
    try 
        InputStream is = Resources.getResource(resourcePath).openStream(); //guava
        return kieServices.getResources()
                  .newInputStreamResource(is)
                  .setResourceType(ResourceType.DRL);
     catch (IOException e) 
        throw new RuntimeException("Failed to load drools resource file.", e);
    

我使用Guava Resources 类。

【讨论】:

哇,用于动态规则构建的 DescFactory API 看起来如此酷炫和灵活。只是,它的用例是什么?为什么要在 Java 中构建动态规则?首先将 DRL 规则具体化不是重点吗? 在将现有规则集迁移到 DRL 文件时会很有用。这就是我目前正在努力实现的目标。 结帐github.com/trmsmy/drools-example@Tim...是你的吗?【参考方案2】:

以编程方式创建规则的内置方法基于“Descr”流畅 API,该 API 直接操作编译器的 AST,绕过解析器。

查看课程org.drools.compiler.lang.api.DescrFactory

org.drools.compiler.lang.DrlDumper 类从 AST 中检索 DRL 近似值。

【讨论】:

好的,但是您如何评估构建的 PackageDescr?【参考方案3】:

没有用于从 Java 代码构建规则的稳定 API。当然,有一个用于 DRL 编译器解析器的 API,但它不像 DRL 规则语法那样稳定且复杂,这是相当可观的。

XML 是一个至少左侧语法足够简单的选项,它以 5.2 (IIRC) 结尾。现在,您可以结合使用 Java 的完整表达式语法等多种方式来编写 CE。

如果您的规则非常简单,您可能会想出一个可以通过可管理的 API 操作的规则模型。否则,您最好的选择是文本编辑器(或者,当然,Kie Workbench)。

【讨论】:

以上是关于在 Drools 6 中以编程方式创建新的 drools 规则的新接受方式是啥?的主要内容,如果未能解决你的问题,请参考以下文章

text 在wordpress中以编程方式检查并创建新的帖子/页面

如何在 Drupal 7 中以编程方式创建新的内容类型?

在 iOS 6 中以编程方式打开地图应用

无法在 Xcode 中以编程方式创建地图(Big Nerd Ranch IOS 编程:第 6 章 p97)

如何在 Entity Framework 6 中以编程方式创建与 MS SQL 的连接字符串?

在 WordPress 中以编程方式将文件上传给用户