【问题标题】:Drools rules - multiple issues (halt execution, condition to stop execution) not workingDrools 规则 - 多个问题(停止执行、停止执行的条件)不起作用
【发布时间】:2015-03-24 01:19:40
【问题描述】:

我正在使用 Drools 6.1.0.FINAL 和无状态会话来触发所有规则。

我的 .drl 文件中有以下 2 条简单规则。

rule "Null Check"
    when
        $paymentHolder : PaymentHolder(pmtRequest.requestDetails == null 
        || pmtRequest.requestDetails.paymentData == null
        || pmtRequest.requestDetails.paymentData.accountDetails == null
        || pmtRequest.requestDetails.paymentData.payments == null
        || pmtRequest.requestDetails.paymentData.payments.payment == null
        || pmtRequest.requestDetails.paymentData.payments.payment.get(0).tenderDetails == null
        || pmtRequest.requestDetails.paymentData.payments.payment.get(0).tenderDetails.paymentCardDetails == null
        || pmtRequest.requestDetails.paymentData.payments.payment.get(0).tenderDetails.paymentCardDetails.authorizationInfo == null)
    then
        System.out.println("Some Manadatory data is null ");
        // populate error code and error message
        List<ErrorHolder> errors = $paymentHolder.getErrors();
        ErrorHolder erroHolder = new ErrorHolder();
        errors.add(erroHolder);
      erroHolder.setErrorCode(com.wdpr.payment.exception.ErrorCode.MANDATORY_DATA_MISSING);
        // drools.halt();
       // kcontext.getKieRuntime().halt();        
end

rule "Amount is -ve"
    when
        
        $paymentHolder : PaymentHolder(errors.size() == 0)
    $paymentHolder(pmtRequest.getRequestDetails()!.getPaymentData().getPayments().getPayment().get(0).getAmount().getAmount() < 0)
    then
        //System.out.println(paymentHolder.getProcessId());
        System.out.println("Amount is -ve");
        //throw new com.wdpr.payment.exception.PaymentPlatformException(com.wdpr.payment.exception.ErrorCode.DATA_RANGE_INVALID, "Data Range Invalid - Amount", null);
end

我想这样做:如果第一条规则为真,则不执行任何其他规则并退出 .drl 文件。

我尝试了以下操作:

  1. 试图在第一个规则中抛出一个运行时异常,但它仍然会因为 NullPointerException 而失败。

  2. 添加了 drools.halt() 和 kcontext.getKieRuntime().halt() 但没有奏效,继续下一条规则。

  3. 所以我在我的第一条规则中的自定义 erroHolder 中添加了一些错误代码,并在第二条规则中检查了相同的条件,这样它就不会被执行,但它仍然会被执行并抛出 NullPointerException。

如果我删除第二条规则,那么第一条规则将完美执行并打印系统输出。但是当我使用这两条规则运行我的 .drl 时,它给了我低于 NPE

堆栈跟踪

Exception in thread "main" java.lang.RuntimeException: Error while creating KieBase[Message [id=1, level=ERROR, path=com/my/payment/rules/validation.drl, line=40, column=0
   text=[ERR 102] Line 40:53 mismatched input '!.' in rule "Amount is -ve"], Message [id=2, level=ERROR, path=com/my/payment/rules/validation.drl, line=0, column=0
   text=Parser returned a null Package]]
    at org.drools.compiler.kie.builder.impl.KieContainerImpl.getKieBase(KieContainerImpl.java:349)
    at org.drools.compiler.kie.builder.impl.KieContainerImpl.newStatelessKieSession(KieContainerImpl.java:540)
    at org.drools.compiler.kie.builder.impl.KieContainerImpl.newStatelessKieSession(KieContainerImpl.java:528)
    at com.my.payment.workflow.DroolsRuleProcessor.runRules(DroolsRuleProcessor.java:58)
    at com.my.payment.workflow.DroolsRuleProcessor.main(DroolsRuleProcessor.java:81)

我的java代码sn-p

// some code

final StatelessKieSession kSession = this.kContainer.newStatelessKieSession(rulesSession);

         // provide the necessary data and execute rules.
         kSession.execute(paymentHolder);

注意:我不想使用 salient 和 activate-group

【问题讨论】:

    标签: java drools bpmn business-rules


    【解决方案1】:

    解决方案很简单(尽管它可能不会让您满意)。为避免在评估访问包含对象的字段的约束时出现 NPE,请确保该字段不为空,或者将针对空的测试与访问相结合。

    // (#1) either:
    class PmtRequest {
        // guarantee non-null requestDetails
        List<rRequestDetail> requestDetails = new ArrayList<>(); 
    
    
    // (#2) or:
    when
    $paymentHolder: PaymentHolder(errors.size() == 0,
                    pmtRequest != null &&
                    pmtRequest.getRequestDetails() ... )
    then ...
    

    对于深度嵌套的约束,这越来越不方便,这就是为什么建议不要编写此类访问,而是将包含的对象作为事实插入或在顶级对象中添加方法以访问包含的对象。

    还有另一个选项 (#3):在您的规则执行中使用两个会话。新的 PaymentHolder 事实必须通过仅包含 nun-null 测试的第一个会话,然后才能插入到第二个会话中。

    恕我直言,一种可靠的方法是结合#1 和#3。

    (问题的根源在于,您需要在设计规则和应用程序之前考虑规则评估的工作方式。所有约束在插入事实时进行评估 /em>。来自 Drools 手册:条件评估不依赖于特定的评估顺序或时间点,而是在引擎生命周期的任何时间连续发生。

    【讨论】:

    • 感谢您的回复,当您说使用选项#1和选项#3时,我仍然不清楚,您是否还建议如果我的所有规则都无法停止执行下一个规则位于单个文件中,因为它们将被并行评估
    • 我的意思是#1,即初始化字段尽可能(例如,使用空列表)应该完成,但是#3是必不可少的,除非你可以对所有字段执行 #1 并完全避免 null。 - 我不是建议,我是在引用 Drools 关于条件评估的文档。
    猜你喜欢
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-12
    • 1970-01-01
    相关资源
    最近更新 更多