簡體   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