Слюни: Оценка DMN 1.2 FEEL-функций не работает

Я хочу оценить в 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);
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
543
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Было бы лучше порекомендовать нет (не)маршалировать и не компилировать файл 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, подробно описанной в документации, как и в предыдущем примере, но я надеюсь, что этот ответ поможет вам решить в любом случае - локально оба работают для меня.

Надеюсь это поможет!

Большое спасибо за вашу поддержку, это работает и для меня!

Gustav Great 28.05.2019 15:55

Другие вопросы по теме