流口水:DMN 1.2 FEEL功能的评估不起作用

时间:2019-05-27 15:03:48

标签: java drools decision-model-notation

我想在Drools 7.21中评估DMN 1.2中新增的FEEL功能,例如sqrt()或modulo(),但是方法

dmnRuntime.evaluateAll(dmnModel,context)

总是返回状态为“ SUCCESS”的值“ null”(仅适用于新功能)。我做错了什么或缺少了什么?

DMN文件如下:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<semantic:definitions xmlns:semantic="http://www.omg.org/spec/DMN/20180521/MODEL/" xmlns="http://www.trisotech.com/definitions/_56fd6445-ff6a-4c28-8206-71fce7f80436" xmlns:feel="http://www.omg.org/spec/FEEL/20140401" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" exporter="DMN Modeler" exporterVersion="6.0.1" id="_56fd6445-ff6a-4c28-8206-71fce7f80436" name="Sqrt-Function" namespace="http://www.trisotech.com/definitions/_56fd6445-ff6a-4c28-8206-71fce7f80436" >
  <semantic:decision id="_cf6124bd-9907-4ac0-b4fd-59a962dbc502" name="square_root">
    <semantic:variable id="_edaf978e-3634-4e52-8244-5fd4e16fd257" name="square_root" typeRef="feel:number"/>
    <semantic:literalExpression id="_c990c3b2-e322-4ef9-931d-79bcdac99686">
      <semantic:text>sqrt(81)</semantic:text>
    </semantic:literalExpression>
  </semantic:decision>
</semantic:definitions>

在“ dmnModel”中导入文件后:

DMNMarshaller marshaller = new org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller();
FileInputStream fis = new FileInputStream( dmnFile );
Definitions unmarshal = marshaller.unmarshal( new InputStreamReader( fis ) );
DMNCompiler compiler = DMNFactory.newCompiler();
DMNModel dmnModel = compiler.compile(unmarshal);

我这样称呼Drools评估:

KieContainer kieContainer = KieHelper.getKieContainer(ks.newReleaseId("org.kie", "dmn-test-"+UUID.randomUUID(), "1.2"));
DMNRuntime dmnRuntime = kieContainer.newKieSession().getKieRuntime(DMNRuntime.class);
((DMNRuntimeImpl) dmnRuntime).setOption(new RuntimeTypeCheckOption(true));
DMNResult result = dmnRuntime.evaluateAll(dmnModel, context);

1 个答案:

答案 0 :(得分:2)

最好不要建议(取消)编组,并且不必手动编译DMN文件;而是使用KJAR的KieContainer的标准构建标准方法; as detailed by the user guide in the documentation

换句话说,这对于您的DMN文件是正确的:

KieServices kieServices = KieServices.Factory.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
DMNRuntime dmnRuntime = KieRuntimeFactory.of(kieContainer.getKieBase()).get(DMNRuntime.class);
DMNModel dmnModel = dmnRuntime.getModel(namespace, modelName);
DMNContext context = dmnRuntime.newContext();
((DMNRuntimeImpl) dmnRuntime).setOption(new RuntimeTypeCheckOption(true));
DMNResult result = dmnRuntime.evaluateAll(dmnModel, context);

产生9作为结果。

如果您还是想使用KieHelper,最好将DMN文件作为KieResource传递给KieHelper.getKieContainer(...)的调用,例如:

KieContainer kieContainer = KieHelper.getKieContainer(ks.newReleaseId("org.kie", "dmn-test-" + UUID.randomUUID(), "1.2"),
                                                      ks.getResources().newFileSystemResource(new File(dmnFile)));
DMNRuntime dmnRuntime = KieRuntimeFactory.of(kieContainer.getKieBase()).get(DMNRuntime.class);
((DMNRuntimeImpl) dmnRuntime).setOption(new RuntimeTypeCheckOption(true));
DMNModel dmnModel = dmnRuntime.getModel(namespace, modelName);
DMNContext context = dmnRuntime.newContext();
DMNResult result = dmnRuntime.evaluateAll(dmnModel, context);
System.out.println(result);

您可以根据用例,根据需要将调用ks.getResources().newFileSystemResource(...)更改为基于URL,ClassPath,Byte等的资源。这样,KieHelper将负责解组

这第二个代码段也适合您的DMN文件,从而产生9

您的代码中的问题是DMNCompiler的初始化并不是真正由用户手动调用的,实际上,文档中没有任何地方需要手动管理此操作。以上两种方法均会将其委托给KieContainer / KieHelper的内部,这是标准方法。

我建议遵循文档中的KieContainer构建,如上一个示例中所述,但是我希望这个答案可以帮助您解决任何一种问题-在本地都对我有用。

希望这会有所帮助!