将类对象传递给 Drools 规则 (drt) 文件

Posted

技术标签:

【中文标题】将类对象传递给 Drools 规则 (drt) 文件【英文标题】:Passing Class objects to Drools Rules (drt) file 【发布时间】:2020-09-15 17:50:21 【问题描述】:

我正在使用 Drools 模板进行决策,我创建了类实例并使用插入将类对象传递给 Kie 会话

在drt文件中,我尝试将模板列与Class对象进行比较,某些参数已通过阈值,然后根据模板文件中的值设置优先级

模板文件的格式(Excel)

Parameter     Mountpoint       Threshold      Severity
Disk            /root           80              MINOR
Disk            /tmp            90              MAJOR

My class Capacity 

private String component;
private String subComponent;
privat Integer value;

public String getComponent() 
            return component;
        
        public void setComponent(String component) 
            this.component = component;
        
        public String getSubComponent() 
            return subComponent;
        
        public void setSubComponent(String subComponent) 
            this.subComponent = subComponent;
        
        public Integer getValue() 
            return value;
        
        public void setValue(Integer value) 
            this.value = value;
        

public Capacity()        
        
            super();
            this.component = component;
            this.subComponent = subComponent;
            this.value = value;
         


在另一个类中,我正在启动 KieSession 并注入容量类对象并加载模板文件 流口水

        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
    KieSessionConfiguration sessionConfig = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
    sessionConfig.setOption( ClockTypeOption.get( ClockType.PSEUDO_CLOCK.getId() ) );
    try 
        loadRuleTemplate(DATA_FILE, RULE_TEMPLATE_FILE, "OperationalMeasurement", 2, 1);
     catch (IOException errorMsg) 
        log.error(errorMsg.getMessage());       
    InternalKnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
    kbase.addPackages(kbuilder.getKnowledgePackages());       
    KieSession kieSession =  kbase.newKieSession(sessionConfig, null);
    sessionClock = ksession.getSessionClock();
    ksession.insert(Capacity);
    ksession.fireAllRules();
    ksession.dispose();

规则文件

template header
Parameter
Mountpoint
Threshold
Severity

package com.test.drools;

dialect "java"

template "OperationalMeasurement"

rule "Check_Threshold_@row.rowNumber"
ruleflow-group "capacityManagement"
salience 500
when
   $capacity: Capacity(component == "@Parameter" && subComponent == "@Mountpoint" && value >= "@Threshold")
  then   
    System.out.println("Thresold cross for Component and Priority is set " + @Severity"); 
end
end template

当我运行它时,组件被视为文字字符串而不是容量类变量,虽然我没有收到任何错误,但它只是在控制台中打印了 drt 文件的所有内容。 而且我似乎没有得到 Sysout 语句

【问题讨论】:

模板展开后能否粘贴至少一条生成的规则?我还注意到您在模板中使用了ruleflow-group,但在执行KieSession 时从未激活它。这是故意的吗? @EstebanAliverti..这是输出 'c.b.d.a.capacity.capacityEventHandler : package com.test.drools;方言“java”导入com.test.drools.Capacity; rule "Check_Threshold_2" 显着性 500 当 $capacity: Capacity(component == "Disk" && subComponent == "/tmp" && value >= 90) then System.out.println("Thresold crossed for Component::" +component + " 并且优先级设置为 " + Major"); 结束 它只是打印整个规则文件内容,只是它而不是模板字段,它用模板中的实际值替换,如果模板中有两条记录,则触发两次规则。我也从 drl 文件中删除了规则流组,结果仍然相同 【参考方案1】:

组件被视为文字字符串而不是容量类变量

不确定你的意思。什么“组件”被视为文字?

根据您作为评论添加的生成规则,正在生成的规则中有一些错误:

    System.out.println("Thresold crossed for Component::" +component + " and Priority is set " + Major"); 

在上面的行中,“组件”应该是一个变量,但没有同名的变量。在“主要”字符串之前还有一个缺少的引号。 我建议您将模板更改为以下内容:

rule "Check_Threshold_@row.rowNumber"
ruleflow-group "capacityManagement"
salience 500
when
   $capacity: Capacity(component == "@Parameter" && subComponent == "@Mountpoint" && value >= "@Threshold")
  then   
    System.out.println("Threshold cross for Component:: @Parameter and Priority is set to @Severity"); 
end
end template

这应该会生成有效的 DRL。

另一件值得一提的事情是,由于某些我从未完全理解的奇怪原因,如果您的知识库中有错误(即 DRL 文件中的错误),Drools 不会抱怨。在使用知识库之前,您必须自行检查错误。 KnowledgeBuilder 类有一个 hasErrors() 方法和一个 getResults() 方法,可用于检查错误。如果您使用的是KieContainer,那么您可以使用verify() 方法。您如何将 DRL 加载到 KieBase

希望对你有帮助,

【讨论】:

以上是关于将类对象传递给 Drools 规则 (drt) 文件的主要内容,如果未能解决你的问题,请参考以下文章

如何将类对象作为参数传递给不同的类方法?

是否可以将类类型的对象作为参数传递给另一个类,这样我就不必再次初始化? (Python 3.x)

将类作为参数传递给方法,然后调用静态方法

将类函数传递给 PySpark RDD

如何将类方法作为参数传递给该类外部的函数?

试图将类作为参数传递给不同的类构造函数,但出现“转换”错误