Я хочу оценить в Drools 7.21 FEEL-функции, новые в DMN 1.2, такие как sqrt() или modulo(), но метод
dmnRuntime.evaluateAll (dmnModel, контекст)
всегда возвращает значение «null» (только для новых функций) со статусом «SUCCESS». Что я делаю не так или чего не хватает?
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);
Было бы лучше порекомендовать нет (не)маршалировать и не компилировать файл DMN вручную; вместо этого использовать стандартные средства стандартной сборки KieContainer от KJAR; как подробно описано в руководстве пользователя в документации.
Другими словами, это правильно работает с вашим файлом 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, подробно описанной в документации, как и в предыдущем примере, но я надеюсь, что этот ответ поможет вам решить в любом случае - локально оба работают для меня.
Надеюсь это поможет!
Большое спасибо за вашу поддержку, это работает и для меня!