繁体   English   中英

我们可以在 Drools 中动态设置事实类型和事实字段吗

[英]Can we set fact type and fact field dynamically in Drools

如何在 drl 文件中动态设置事实类型和事实字段?我正在读取一个包含记录的 json 文件。我正在映射到 pojo 类,该类从 json 模式动态生成我使用了json2pojo maven 插件 .现在我想在该课程上制定一些规则。 但我无法将 drl 文件中的该类作为字段的事实.相同。 下面是drl规则。

rule "not null"

when 

  obj:Class(fieldName==null)
then
  //take action
end

这个 Class 和 fieldName 是动态生成的。 请建议我解决这个问题。 谢谢。

我已经成功实施了类似的问题陈述。 快速浏览一下。 我应该在用户在 Web 应用程序中运行时选择的 sql 表上动态生成规则。 这里要注意的一点是 pojo 类也应该在运行时生成。 Drools 6 有一个内置的 API(类似于 JAVA 反射 API),您可以在其中动态生成一个类,因此也可以动态生成 factTypes。 所以首先是 .drl 文件:-

declare {insert tablename as chosen by the user}
{columnname} : {columntype}  
{columnname} : {columntype}  
end

这将生成一个 pojo 类以及可以在规则中直接访问的属性的 getter 和 setter。 现在,java文件:-

生成的类可以在 java 应用程序中访问,如下所示:

//获取声明的FactType

FactType  tableType = kbase.getFactType({packagename},{tablename});

//创建实例:

Object obj = tableType.newInstance();

现在,从与所选表对应的 sql 插入的事实是通过 hibernate 实现的。 如果规则进行了任何修改,这也会使表格保持更新。

随意问任何问题。 乐于帮助..:)

我根据我的要求找到了一个解决方案。这是我动态删除生成的 POJO 的另一种方法。我创建了一个 POJO 作为“参数”,它将用作事实类型。因为我的字段为 fieldName(Json field path),rulesToFire (规则)和 json 记录列表。所以在 drl 文件中我可以获取这些值。使用 com.jayway.jsonpath.JsonPath 我可以读取受尊重的值。

JSON 适用于通过线路发送数据等。但是您应该将其转换为 POJO 并根据 Java 对象编写验证规则。 我看不出你为什么不能这样做的充分理由。

但是...如果你想花费大量的时间和精力...

您可能使用 XML 完成的操作是数据集(“记录”)的另一种(文本)表示。 查看 JSON 结构定义,您可以看到您有“对象”和“数组”。 这些将是您的事实类型。 (JS-)Object 可以由包含 Map 的 POJO 表示,(JS-)Array 可以由具有 java.util.List 字段的 POJO 实现。

您可以编写选择 JS 对象并执行字段检查的规则。

FactType接口中有一个选项为setFromMap 如果你能够提供你在输入Map集合(可能是JSON或JSON到Map ),那么你可以设置所有从这个声明的类型的属性的Map 下面是这种方法的测试用例。 我希望它会有所帮助。

   @Test
    void test_StatelessKieSession_DynamicRuleNestedObjects_DeclaredVariables_Standalone() throws Exception{
        Map<String,Object> fields =
                Stream.of(new Object[][] {
                        {"name","server001"},
                        {"processors",4},
                        {"memory",8192},
                        {"diskSpace",128},
                        {"cpuUsage",3},
                        {"virtualizations"
                                ,Stream.of(
                                new HashMap<String,Object>(){{
                                    put("name","virtualization - 1");
                                    put("diskSpace",4);
                                    put("memory",1024);}},
                                new HashMap<String,Object>(){{
                                    put("name","virtualization - 2");
                                    put("diskSpace",8);
                                    put("memory",2048);}}
                        ).collect(Collectors.toList())}
                }).collect(Collectors.toMap(key -> (String)key[0], val -> val[1]));

        String packageName = "com.genericrule";
        String mainObjectName = "Server";

        String ruleStr = "package com.genericrule import java.util.List; declare Server name : String processors : int memory : int diskSpace : int virtualizations : List cpuUsage : int ruleMessage : String end; declare Virtualization name : String diskSpace : int memory : int end; rule \"check minimum server configuration\" dialect \"mvel\" when $server : Server(processors < 2 || memory <= 1024 || diskSpace <= 250 ) then $server.ruleMessage = $server.name + \" was rejected by don't apply the minimum configuration.\"; end;";

        KieServices kieServices = KieServices.Factory.get();

        KieRepository kr = kieServices.getRepository();
        KieFileSystem kfs = kieServices.newKieFileSystem();

        kfs.write("src/main/resources/genericRule.drl", ruleStr);

        KieBuilder kb = kieServices.newKieBuilder(kfs);
        kb.buildAll();

        KieContainer kContainer = kieServices.newKieContainer(kr.getDefaultReleaseId());

        StatelessKieSession sks = kContainer.newStatelessKieSession();

        FactType mainObjectFact = sks.getKieBase().getFactType(packageName,mainObjectName);

        Object mainObject = mainObjectFact.newInstance();

        mainObjectFact.setFromMap(mainObject,fields);
        sks.execute(mainObject);

        assertThat((String) mainObjectFact.get(mainObject,"ruleMessage")).contains("rejected");
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM