This is an automated email from the ASF dual-hosted git repository.
gitgabrio pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-drools.git
The following commit(s) were added to refs/heads/main by this push:
new 8cb84aa3fa [incubator-kie-issues#2015] Add error handling modes in DMN
engine (#6387)
8cb84aa3fa is described below
commit 8cb84aa3fadac7360d6e1d569069876b06a8b73a
Author: Gabriele Cardosi <[email protected]>
AuthorDate: Mon Jul 7 13:37:50 2025 +0200
[incubator-kie-issues#2015] Add error handling modes in DMN engine (#6387)
* Deprecate type time with timezone
* [incubator-kie-issues#2011] Implemented support for 1.6. Refactored to
avoid duplication and moved common code to abstract classes
* [incubator-kie-issues#2011] Remove leftover xsd
* Added code changes to get the current model version
* [incubator-kie-issues#2011] Fixed license headers
* [incubator-kie-issues#2011] Fixed license headers
* get dmn model version changes
* code changes to get dmn model version
* DMN Engine 1.6 changes
* Fixing Review comments fix
* Fixing Review comments
* [incubator-kie-issues#2015] Implemented lenient vs strict mode DMN
runtime evaluation. Implemented fast-fail for DMN runtime strict mode.
Implemented tests
* [incubator-kie-issues#2015] Fixed test as per PR suggestion
* [incubator-kie-issues#2015] Clean up as per PR suggestion
---------
Co-authored-by: ChinchuAjith <[email protected]>
Co-authored-by: Gabriele-Cardosi <[email protected]>
---
.../kie/dmn/core/compiler/RuntimeModeOption.java | 75 ++++++++
.../java/org/kie/dmn/core/impl/DMNRuntimeImpl.java | 190 +++++++++++---------
.../java/org/kie/dmn/core/DMNCompilerTest.java | 43 +++++
.../java/org/kie/dmn/core/DMNInputRuntimeTest.java | 156 ++++++++++++++--
.../DMNv1_6/DMN-MultipleInvalidElements.dmn | 196 +++++++++++++++++++++
5 files changed, 567 insertions(+), 93 deletions(-)
diff --git
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/RuntimeModeOption.java
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/RuntimeModeOption.java
new file mode 100644
index 0000000000..a90ee895f2
--- /dev/null
+++
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/RuntimeModeOption.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.kie.dmn.core.compiler;
+
+import java.io.Serial;
+import org.kie.dmn.core.assembler.DMNAssemblerService;
+
+public class RuntimeModeOption implements DMNOption {
+
+ public static final String PROPERTY_NAME =
DMNAssemblerService.ORG_KIE_DMN_PREFIX + ".runtime.mode";
+
+ @Serial
+ private static final long serialVersionUID = -372562279892008329L;
+
+ public enum MODE {
+ LENIENT("lenient"),
+ STRICT("strict");
+
+ private final String mode;
+
+ MODE(String mode) {
+ this.mode = mode;
+ }
+
+ public String getMode() {
+ return mode;
+ }
+ }
+
+ /**
+ * The default <code>MODE</code> for this option
+ */
+ public static final MODE DEFAULT_VALUE = MODE.LENIENT;
+
+ private final MODE runtimeMode;
+
+ public RuntimeModeOption(String runtimeMode) {
+ MODE toSet = null;
+ try {
+ toSet = MODE.valueOf(runtimeMode);
+ } catch (Exception e) {
+ toSet = DEFAULT_VALUE;
+ }
+ this.runtimeMode = toSet;
+ }
+
+ public RuntimeModeOption(MODE runtimeMode) {
+ this.runtimeMode = runtimeMode != null ? runtimeMode : DEFAULT_VALUE;
+ }
+
+ @Override
+ public String getPropertyName() {
+ return PROPERTY_NAME;
+ }
+
+ public MODE getRuntimeMode() {
+ return runtimeMode;
+ }
+}
diff --git
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeImpl.java
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeImpl.java
index 50780bf3b6..a22c7eb065 100644
---
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeImpl.java
+++
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeImpl.java
@@ -18,6 +18,8 @@
*/
package org.kie.dmn.core.impl;
+import javax.xml.namespace.QName;
+
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -26,9 +28,6 @@ import java.util.Optional;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
-
-import javax.xml.namespace.QName;
-
import org.drools.kiesession.rulebase.InternalKnowledgeBase;
import org.kie.dmn.api.core.DMNContext;
import org.kie.dmn.api.core.DMNDecisionResult;
@@ -37,6 +36,7 @@ import org.kie.dmn.api.core.DMNModel;
import org.kie.dmn.api.core.DMNResult;
import org.kie.dmn.api.core.DMNRuntime;
import org.kie.dmn.api.core.DMNType;
+import org.kie.dmn.api.core.EvaluatorResult;
import org.kie.dmn.api.core.ast.BusinessKnowledgeModelNode;
import org.kie.dmn.api.core.ast.DMNNode;
import org.kie.dmn.api.core.ast.DecisionNode;
@@ -45,7 +45,6 @@ import org.kie.dmn.api.core.ast.InputDataNode;
import org.kie.dmn.api.core.event.BeforeEvaluateDecisionEvent;
import org.kie.dmn.api.core.event.DMNRuntimeEventListener;
import org.kie.dmn.core.api.DMNFactory;
-import org.kie.dmn.api.core.EvaluatorResult;
import org.kie.dmn.core.ast.BusinessKnowledgeModelNodeImpl;
import org.kie.dmn.core.ast.DMNBaseNode;
import org.kie.dmn.core.ast.DMNDecisionServiceEvaluator;
@@ -55,6 +54,7 @@ import org.kie.dmn.core.ast.DecisionServiceNodeImpl;
import org.kie.dmn.core.ast.InputDataNodeImpl;
import org.kie.dmn.core.compiler.DMNOption;
import org.kie.dmn.core.compiler.DMNProfile;
+import org.kie.dmn.core.compiler.RuntimeModeOption;
import org.kie.dmn.core.compiler.RuntimeTypeCheckOption;
import org.kie.dmn.core.util.Msg;
import org.kie.dmn.core.util.MsgUtil;
@@ -77,6 +77,7 @@ public class DMNRuntimeImpl
private final DMNRuntimeKB runtimeKB;
private boolean overrideRuntimeTypeCheck = false;
+ private RuntimeModeOption.MODE runtimeModeOption =
RuntimeModeOption.MODE.LENIENT;
private DMNResultImplFactory dmnResultFactory = new DMNResultImplFactory();
@@ -112,12 +113,13 @@ public class DMNRuntimeImpl
Objects.requireNonNull(model, () ->
MsgUtil.createMessage(Msg.PARAM_CANNOT_BE_NULL, "model"));
Objects.requireNonNull(context, () ->
MsgUtil.createMessage(Msg.PARAM_CANNOT_BE_NULL, "context"));
boolean performRuntimeTypeCheck = performRuntimeTypeCheck(model);
+ boolean strictMode =
this.runtimeModeOption.equals(RuntimeModeOption.MODE.STRICT);
DMNResultImpl result = createResult( model, context );
DMNRuntimeEventManagerUtils.fireBeforeEvaluateAll( eventManager,
model, result );
// the engine should evaluate all Decisions belonging to the "local"
model namespace, not imported decision explicitly.
Set<DecisionNode> decisions = model.getDecisions().stream().filter(d
->
d.getModelNamespace().equals(model.getNamespace())).collect(Collectors.toSet());
for( DecisionNode decision : decisions ) {
- evaluateDecision(context, result, decision,
performRuntimeTypeCheck);
+ evaluateDecision(context, result, decision,
performRuntimeTypeCheck, strictMode);
}
DMNRuntimeEventManagerUtils.fireAfterEvaluateAll( eventManager, model,
result );
return result;
@@ -150,18 +152,19 @@ public class DMNRuntimeImpl
throw new
IllegalArgumentException(MsgUtil.createMessage(Msg.PARAM_CANNOT_BE_EMPTY,
"decisionNames"));
}
final DMNResultImpl result = createResult( model, context );
+ boolean strictMode =
this.runtimeModeOption.equals(RuntimeModeOption.MODE.STRICT);
for (String name : decisionNames) {
- evaluateByNameInternal( model, context, result, name );
+ evaluateByNameInternal( model, context, result, name, strictMode );
}
return result;
}
- private void evaluateByNameInternal( DMNModel model, DMNContext context,
DMNResultImpl result, String name ) {
+ private void evaluateByNameInternal( DMNModel model, DMNContext context,
DMNResultImpl result, String name, boolean strictMode ) {
boolean performRuntimeTypeCheck = performRuntimeTypeCheck(model);
Optional<DecisionNode> decision =
Optional.ofNullable(model.getDecisionByName(name));
if (decision.isPresent()) {
final boolean walkingIntoScope =
walkIntoImportScopeInternalDecisionInvocation(result, model, decision.get());
- evaluateDecision(context, result, decision.get(),
performRuntimeTypeCheck);
+ evaluateDecision(context, result, decision.get(),
performRuntimeTypeCheck, strictMode);
if (walkingIntoScope) {
result.getContext().popScope();
}
@@ -186,18 +189,19 @@ public class DMNRuntimeImpl
throw new
IllegalArgumentException(MsgUtil.createMessage(Msg.PARAM_CANNOT_BE_EMPTY,
"decisionIds"));
}
final DMNResultImpl result = createResult( model, context );
+ boolean strictMode =
this.runtimeModeOption.equals(RuntimeModeOption.MODE.STRICT);
for ( String id : decisionIds ) {
- evaluateByIdInternal( model, context, result, id );
+ evaluateByIdInternal( model, context, result, id, strictMode );
}
return result;
}
- private void evaluateByIdInternal( DMNModel model, DMNContext context,
DMNResultImpl result, String id ) {
+ private void evaluateByIdInternal( DMNModel model, DMNContext context,
DMNResultImpl result, String id, boolean strictMode ) {
boolean performRuntimeTypeCheck = performRuntimeTypeCheck(model);
Optional<DecisionNode> decision =
Optional.ofNullable(model.getDecisionById(id));
if (decision.isPresent()) {
final boolean walkingIntoScope =
walkIntoImportScopeInternalDecisionInvocation(result, model, decision.get());
- evaluateDecision(context, result, decision.get(),
performRuntimeTypeCheck);
+ evaluateDecision(context, result, decision.get(),
performRuntimeTypeCheck, strictMode);
if (walkingIntoScope) {
result.getContext().popScope();
}
@@ -553,7 +557,7 @@ public class DMNRuntimeImpl
}
- private boolean evaluateDecision(DMNContext context, DMNResultImpl result,
DecisionNode d, boolean typeCheck) {
+ private boolean evaluateDecision(DMNContext context, DMNResultImpl result,
DecisionNode d, boolean typeCheck, boolean strictMode) {
DecisionNodeImpl decision = (DecisionNodeImpl) d;
String decisionId =
d.getModelNamespace().equals(result.getModel().getNamespace()) ?
decision.getId() : decision.getModelNamespace() + "#" + decision.getId();
if (isNodeValueDefined(result, decision, decision)) {
@@ -571,7 +575,6 @@ public class DMNRuntimeImpl
BeforeEvaluateDecisionEvent beforeEvaluateDecisionEvent = null;
try {
beforeEvaluateDecisionEvent =
DMNRuntimeEventManagerUtils.fireBeforeEvaluateDecision(eventManager, decision,
result);
- boolean missingInput = false;
DMNDecisionResultImpl dr = (DMNDecisionResultImpl)
result.getDecisionResultById(decisionId);
if (dr == null) { // an imported Decision now evaluated, requires
the creation of the decision result:
String decisionResultName = d.getName();
@@ -585,74 +588,8 @@ public class DMNRuntimeImpl
}
}
dr.setEvaluationStatus(DMNDecisionResult.DecisionEvaluationStatus.EVALUATING);
- for( DMNNode dep : decision.getDependencies().values() ) {
- try {
- if (typeCheck && !checkDependencyValueIsValid(dep,
result)) {
- missingInput = true;
- DMNMessage message = MsgUtil.reportMessage( logger,
- DMNMessage.Severity.ERROR,
- ((DMNBaseNode) dep).getSource(),
- result,
- null,
- null,
- Msg.ERROR_EVAL_NODE_DEP_WRONG_TYPE,
- getIdentifier( decision ),
- getDependencyIdentifier(decision, dep),
-
MsgUtil.clipString(Objects.toString(result.getContext().get(dep.getName())),
50),
- ((DMNBaseNode) dep).getType()
- );
- reportFailure( dr, message,
DMNDecisionResult.DecisionEvaluationStatus.SKIPPED );
- }
- } catch ( Exception e ) {
- MsgUtil.reportMessage( logger,
- DMNMessage.Severity.ERROR,
- ((DMNBaseNode)dep).getSource(),
- result,
- e,
- null,
- Msg.ERROR_CHECKING_ALLOWED_VALUES,
- getDependencyIdentifier(decision,
dep),
- e.getMessage() );
- }
- if (!isNodeValueDefined(result, decision, dep)) {
- boolean walkingIntoScope = walkIntoImportScope(result,
decision, dep);
- if( dep instanceof DecisionNode ) {
- if (!evaluateDecision(context, result, (DecisionNode)
dep, typeCheck)) {
- missingInput = true;
- DMNMessage message = MsgUtil.reportMessage( logger,
-
DMNMessage.Severity.ERROR,
-
decision.getSource(),
- result,
- null,
- null,
-
Msg.UNABLE_TO_EVALUATE_DECISION_REQ_DEP,
-
getIdentifier( decision ),
-
getDependencyIdentifier(decision, dep) );
- reportFailure( dr, message,
DMNDecisionResult.DecisionEvaluationStatus.SKIPPED );
- }
- } else if( dep instanceof BusinessKnowledgeModelNode ) {
- evaluateBKM(context, result,
(BusinessKnowledgeModelNode) dep, typeCheck);
- } else if (dep instanceof DecisionServiceNode) {
- evaluateDecisionService(context, result,
(DecisionServiceNode) dep, typeCheck);
- } else {
- missingInput = true;
- DMNMessage message = MsgUtil.reportMessage( logger,
-
DMNMessage.Severity.ERROR,
-
decision.getSource(),
- result,
- null,
- null,
-
Msg.REQ_DEP_NOT_FOUND_FOR_NODE,
-
getDependencyIdentifier(decision, dep),
-
getIdentifier( decision )
- );
- reportFailure( dr, message,
DMNDecisionResult.DecisionEvaluationStatus.SKIPPED );
- }
- if (walkingIntoScope) {
- result.getContext().popScope();
- }
- }
- }
+
+ boolean missingInput = isMissingInputForDependencies(context,
decision, result, dr, typeCheck, strictMode);
if( missingInput ) {
return false;
}
@@ -671,7 +608,11 @@ public class DMNRuntimeImpl
}
try {
EvaluatorResult er = decision.getEvaluator().evaluate( this,
result);
- if( er.getResultType() == EvaluatorResult.ResultType.SUCCESS ||
+ // if result messages contains errors && runtime mode = strict
-> stop execution and return null
+ if (strictMode && result.hasErrors()) {
+ logger.warn("Immediately return due to strict mode");
+ return false;
+ } else if( er.getResultType() ==
EvaluatorResult.ResultType.SUCCESS ||
(((DMNModelImpl)result.getModel()).getFeelDialect().equals(FEELDialect.BFEEL)
&& er.getResult() != null)) {
Object value = coerceValue(decision.getResultType(),
er.getResult());
try {
@@ -746,6 +687,89 @@ public class DMNRuntimeImpl
return true;
}
+ private boolean isMissingInputForDependencies(DMNContext context,
DecisionNodeImpl decision, DMNResultImpl result, DMNDecisionResultImpl dr,
boolean typeCheck, boolean strictMode) {
+ boolean toReturn = false;
+ for( DMNNode dep : decision.getDependencies().values() ) {
+ toReturn |= isMissingInputForDependency(dep, decision, result, dr,
typeCheck);
+ if (toReturn && strictMode) {
+ logger.warn("Immediately return due to strict mode");
+ return toReturn;
+ }
+ if (!isNodeValueDefined(result, decision, dep)) {
+ boolean walkingIntoScope = walkIntoImportScope(result,
decision, dep);
+ if( dep instanceof DecisionNode ) {
+ if (!evaluateDecision(context, result, (DecisionNode) dep,
typeCheck, strictMode)) {
+ toReturn = true;
+ DMNMessage message = MsgUtil.reportMessage( logger,
+
DMNMessage.Severity.ERROR,
+
decision.getSource(),
+ result,
+ null,
+ null,
+
Msg.UNABLE_TO_EVALUATE_DECISION_REQ_DEP,
+
getIdentifier( decision ),
+
getDependencyIdentifier(decision, dep) );
+ reportFailure( dr, message,
DMNDecisionResult.DecisionEvaluationStatus.SKIPPED );
+ }
+ } else if( dep instanceof BusinessKnowledgeModelNode ) {
+ evaluateBKM(context, result, (BusinessKnowledgeModelNode)
dep, typeCheck);
+ } else if (dep instanceof DecisionServiceNode) {
+ evaluateDecisionService(context, result,
(DecisionServiceNode) dep, typeCheck);
+ } else {
+ toReturn = true;
+ DMNMessage message = MsgUtil.reportMessage( logger,
+
DMNMessage.Severity.ERROR,
+
decision.getSource(),
+ result,
+ null,
+ null,
+
Msg.REQ_DEP_NOT_FOUND_FOR_NODE,
+
getDependencyIdentifier(decision, dep),
+ getIdentifier(
decision )
+ );
+ reportFailure( dr, message,
DMNDecisionResult.DecisionEvaluationStatus.SKIPPED );
+ }
+ if (walkingIntoScope) {
+ result.getContext().popScope();
+ }
+ }
+ }
+ return toReturn;
+ }
+
+ private boolean isMissingInputForDependency(DMNNode dep, DecisionNodeImpl
decision, DMNResultImpl result, DMNDecisionResultImpl dr, boolean typeCheck ) {
+ boolean toReturn = false;
+ try {
+ if (typeCheck && !checkDependencyValueIsValid(dep, result)) {
+ toReturn = true;
+ DMNMessage message = MsgUtil.reportMessage( logger,
+
DMNMessage.Severity.ERROR,
+ ((DMNBaseNode)
dep).getSource(),
+ result,
+ null,
+ null,
+
Msg.ERROR_EVAL_NODE_DEP_WRONG_TYPE,
+ getIdentifier(
decision ),
+
getDependencyIdentifier(decision, dep),
+
MsgUtil.clipString(Objects.toString(result.getContext().get(dep.getName())),
50),
+ ((DMNBaseNode)
dep).getType()
+ );
+ reportFailure( dr, message,
DMNDecisionResult.DecisionEvaluationStatus.SKIPPED );
+ }
+ } catch ( Exception e ) {
+ MsgUtil.reportMessage( logger,
+ DMNMessage.Severity.ERROR,
+ ((DMNBaseNode)dep).getSource(),
+ result,
+ e,
+ null,
+ Msg.ERROR_CHECKING_ALLOWED_VALUES,
+ getDependencyIdentifier(decision, dep),
+ e.getMessage() );
+ }
+ return toReturn;
+ }
+
private static String getIdentifier(DMNNode node) {
return node.getName() != null ? node.getName() : node.getId();
}
@@ -772,6 +796,8 @@ public class DMNRuntimeImpl
public final <T extends DMNOption> void setOption(T option) {
if (option instanceof RuntimeTypeCheckOption) {
this.overrideRuntimeTypeCheck = ((RuntimeTypeCheckOption)
option).isRuntimeTypeCheck();
+ } else if (option instanceof RuntimeModeOption) {
+ this.runtimeModeOption = ((RuntimeModeOption)
option).getRuntimeMode();
}
}
diff --git
a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNCompilerTest.java
b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNCompilerTest.java
index b00f87053d..9ec6ce73a7 100644
--- a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNCompilerTest.java
+++ b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNCompilerTest.java
@@ -35,10 +35,12 @@ import org.kie.dmn.api.core.ast.DecisionNode;
import org.kie.dmn.api.core.ast.ItemDefNode;
import org.kie.dmn.core.api.DMNFactory;
import org.kie.dmn.core.compiler.DMNTypeRegistry;
+import org.kie.dmn.core.compiler.RuntimeModeOption;
import org.kie.dmn.core.impl.BaseDMNTypeImpl;
import org.kie.dmn.core.impl.CompositeTypeImpl;
import org.kie.dmn.core.impl.DMNContextFPAImpl;
import org.kie.dmn.core.impl.DMNModelImpl;
+import org.kie.dmn.core.impl.DMNRuntimeImpl;
import org.kie.dmn.core.impl.SimpleTypeImpl;
import org.kie.dmn.core.util.DMNRuntimeUtil;
import org.kie.dmn.feel.lang.EvaluationContext;
@@ -508,6 +510,47 @@ public class DMNCompilerTest extends BaseVariantTest {
assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse();
}
+ @ParameterizedTest
+ @MethodSource("params")
+ void errorHandlingWithDefaultMode(VariantTestConf conf) {
+ testConfig = conf;
+ String nameSpace =
"https://kie.org/dmn/_79591DB5-1EE1-4CBD-AA5D-2E3EDF31155E";
+ final DMNRuntime runtime =
DMNRuntimeUtil.createRuntime("invalid_models/DMNv1_6/DMN-MultipleInvalidElements.dmn",
this.getClass());
+ final DMNModel dmnModel = runtime.getModel(
+ nameSpace,
+ "DMN_8F7C4323-412A-4E0B-9AEF-0F24C8F55282");
+ assertThat(dmnModel).isNotNull();
+
assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse();
+ }
+
+ @ParameterizedTest
+ @MethodSource("params")
+ void errorHandlingWithLenientMode(VariantTestConf conf) {
+ testConfig = conf;
+ String nameSpace =
"https://kie.org/dmn/_79591DB5-1EE1-4CBD-AA5D-2E3EDF31155E";
+ final DMNRuntime runtime =
DMNRuntimeUtil.createRuntime("invalid_models/DMNv1_6/DMN-MultipleInvalidElements.dmn",
this.getClass());
+ ((DMNRuntimeImpl)runtime).setOption(new
RuntimeModeOption(RuntimeModeOption.MODE.LENIENT));
+ final DMNModel dmnModel = runtime.getModel(
+ nameSpace,
+ "DMN_8F7C4323-412A-4E0B-9AEF-0F24C8F55282");
+ assertThat(dmnModel).isNotNull();
+
assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse();
+ }
+
+ @ParameterizedTest
+ @MethodSource("params")
+ void errorHandlingWithStrictMode(VariantTestConf conf) {
+ testConfig = conf;
+ String nameSpace =
"https://kie.org/dmn/_79591DB5-1EE1-4CBD-AA5D-2E3EDF31155E";
+ final DMNRuntime runtime =
DMNRuntimeUtil.createRuntime("invalid_models/DMNv1_6/DMN-MultipleInvalidElements.dmn",
this.getClass());
+ ((DMNRuntimeImpl)runtime).setOption(new
RuntimeModeOption(RuntimeModeOption.MODE.STRICT));
+ final DMNModel dmnModel = runtime.getModel(
+ nameSpace,
+ "DMN_8F7C4323-412A-4E0B-9AEF-0F24C8F55282");
+ assertThat(dmnModel).isNotNull();
+
assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse();
+ }
+
private void commonValidateUnnamedImport(String importingModelRef, String
importedModelRef) {
final DMNRuntime runtime =
createRuntimeWithAdditionalResources(importingModelRef,
this.getClass(),
diff --git
a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNInputRuntimeTest.java
b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNInputRuntimeTest.java
index abd88e9635..40039a2b5d 100644
---
a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNInputRuntimeTest.java
+++
b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/DMNInputRuntimeTest.java
@@ -27,6 +27,7 @@ import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.kie.dmn.api.core.DMNContext;
@@ -47,6 +48,8 @@ import org.kie.dmn.api.core.event.AfterEvaluateDecisionEvent;
import org.kie.dmn.api.core.event.AfterEvaluateDecisionTableEvent;
import org.kie.dmn.core.api.DMNFactory;
import org.kie.dmn.core.api.event.DefaultDMNRuntimeEventListener;
+import org.kie.dmn.core.compiler.RuntimeModeOption;
+import org.kie.dmn.core.impl.DMNRuntimeImpl;
import org.kie.dmn.core.util.DMNRuntimeUtil;
import static org.assertj.core.api.Assertions.assertThat;
@@ -492,7 +495,6 @@ public class DMNInputRuntimeTest extends
BaseInterpretedVsCompiledTest {
public void afterEvaluateDecision(AfterEvaluateDecisionEvent
event) {
executedDecisionIds.add(event.getDecision().getId());
}
-
});
final DMNModel dmnModel = runtime.getModel(
"https://kie.org/dmn/_0E7C2E43-9E1B-4AB6-8FD1-B3A1461B8C54",
@@ -657,10 +659,11 @@ public class DMNInputRuntimeTest extends
BaseInterpretedVsCompiledTest {
@MethodSource("params")
void multipleInvalidElements(boolean useExecModelCompiler) {
init(useExecModelCompiler);
- final DMNRuntime runtime =
DMNRuntimeUtil.createRuntime("invalid_models/DMNv1_5/DMN-MultipleInvalidElements.dmn",
- this.getClass());
+ final DMNRuntime runtime =
DMNRuntimeUtil.createRuntime("invalid_models/DMNv1_5/DMN-MultipleInvalidElements"
+
+ ".dmn",
+
this.getClass());
final DMNModel dmnModel =
runtime.getModel("https://kie.org/dmn/_79591DB5-1EE1-4CBD-AA5D-2E3EDF31150E",
- "DMN_8F7C4323-412A-4E0B-9AEF-0F24C8F55282");
+
"DMN_8F7C4323-412A-4E0B-9AEF-0F24C8F55282");
assertThat(dmnModel).isNotNull();
assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse();
@@ -678,15 +681,15 @@ public class DMNInputRuntimeTest extends
BaseInterpretedVsCompiledTest {
String decision2RoundUpLiteralExpressionSourceId =
"_43236F2B-9857-454F-8EA0-39B37C7519CF";
String businessKnowledgeModelExpressionSourceId =
"_4AC1BD7D-5A8D-4A88-94F9-0B80BDF0D9B1";
Set<String> expectedIds = new
HashSet<>(Arrays.asList(decision1SourceId,
- decision2SourceId,
- decision1RoundUpLiteralExpressionSourceId,
- decision2RoundUpLiteralExpressionSourceId,
- businessKnowledgeModelExpressionSourceId));
+
decision2SourceId,
+
decision1RoundUpLiteralExpressionSourceId,
+
decision2RoundUpLiteralExpressionSourceId,
+
businessKnowledgeModelExpressionSourceId));
assertThat(dmnResult.getMessages()).hasSize(6);
Set<String> retrievedIds =
dmnResult.getMessages(DMNMessage.Severity.ERROR)
- .stream()
- .map(DMNMessage::getSourceId)
+ .stream()
+ .map(DMNMessage::getSourceId)
.collect(Collectors.toSet());
assertThat(retrievedIds).hasSameSizeAs(expectedIds).containsAll(expectedIds);
@@ -697,7 +700,138 @@ public class DMNInputRuntimeTest extends
BaseInterpretedVsCompiledTest {
retrievedResult = dmnResult.getDecisionResultById(decision2SourceId);
assertThat(retrievedResult).isNotNull();
assertThat(retrievedResult.getEvaluationStatus()).isEqualTo(DMNDecisionResult.DecisionEvaluationStatus.FAILED);
+ }
+
+ @ParameterizedTest
+ @MethodSource("params")
+ void errorHandlingWithDefaultMode(boolean useExecModelCompiler) {
+ init(useExecModelCompiler);
+ String nameSpace =
"https://kie.org/dmn/_79591DB5-1EE1-4CBD-AA5D-2E3EDF31155E";
+ final DMNRuntime runtime =
DMNRuntimeUtil.createRuntime("invalid_models/DMNv1_6/DMN-MultipleInvalidElements"
+
+
".dmn", this.getClass());
+ final DMNModel dmnModel = runtime.getModel(
+ nameSpace,
+ "DMN_8F7C4323-412A-4E0B-9AEF-0F24C8F55282");
+ assertThat(dmnModel).isNotNull();
+
assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse();
+ final DMNContext dmnContext = DMNFactory.newContext();
+ dmnContext.set("id", "_7273EA2E-2CC3-4012-8F87-39E310C8DF3C");
+ dmnContext.set("Conditional Input", 107);
+ dmnContext.set("New Input Data", 8888);
+ dmnContext.set("Score", 80);
+ final DMNResult dmnResult = runtime.evaluateAll(dmnModel, dmnContext);
+
assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isTrue();
+
assertThat(dmnResult.getMessages(DMNMessage.Severity.ERROR).size()).isEqualTo(3);
+ assertThat(dmnResult.getDecisionResults()).isNotNull().hasSize(3);
+ List<String> nullResults =
Arrays.asList("_A40F3AA4-2832-4D98-83F0-7D604F9A090F",
"_3DC41DB9-BE1D-4289-A639-24AB57ED082D");
+ String succeedResult = "_E9468D45-51EB-48DA-8B30-7D65696FDFB8";
+ nullResults.forEach(nullResult ->
assertThat(dmnResult.getDecisionResultById(nullResult).getResult()).isNull());
+
assertThat(dmnResult.getDecisionResultById(succeedResult).getResult()).isNotNull();
+ }
+ @ParameterizedTest
+ @MethodSource("params")
+ void errorHandlingWithLenientMode(boolean useExecModelCompiler) {
+ init(useExecModelCompiler);
+ String nameSpace =
"https://kie.org/dmn/_79591DB5-1EE1-4CBD-AA5D-2E3EDF31155E";
+ final DMNRuntime runtime =
DMNRuntimeUtil.createRuntime("invalid_models/DMNv1_6/DMN-MultipleInvalidElements"
+
+
".dmn", this.getClass());
+ ((DMNRuntimeImpl)runtime).setOption(new
RuntimeModeOption(RuntimeModeOption.MODE.LENIENT));
+ final DMNModel dmnModel = runtime.getModel(
+ nameSpace,
+ "DMN_8F7C4323-412A-4E0B-9AEF-0F24C8F55282");
+ assertThat(dmnModel).isNotNull();
+
assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse();
+ final DMNContext dmnContext = DMNFactory.newContext();
+ dmnContext.set("id", "_7273EA2E-2CC3-4012-8F87-39E310C8DF3C");
+ dmnContext.set("Conditional Input", 107);
+ dmnContext.set("New Input Data", 8888);
+ dmnContext.set("Score", 80);
+ final DMNResult dmnResult = runtime.evaluateAll(dmnModel, dmnContext);
+
assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isTrue();
+
assertThat(dmnResult.getMessages(DMNMessage.Severity.ERROR).size()).isEqualTo(3);
+ assertThat(dmnResult.getDecisionResults()).isNotNull().hasSize(3);
+ List<String> nullResults =
Arrays.asList("_A40F3AA4-2832-4D98-83F0-7D604F9A090F",
"_3DC41DB9-BE1D-4289-A639-24AB57ED082D");
+ String succeedResult = "_E9468D45-51EB-48DA-8B30-7D65696FDFB8";
+ nullResults.forEach(nullResult ->
assertThat(dmnResult.getDecisionResultById(nullResult).getResult()).isNull());
+
assertThat(dmnResult.getDecisionResultById(succeedResult).getResult()).isNotNull();
+ }
- }
+ @ParameterizedTest
+ @MethodSource("params")
+ void errorHandlingWithStrictModeEvaluateAll(boolean useExecModelCompiler) {
+ init(useExecModelCompiler);
+ String nameSpace =
"https://kie.org/dmn/_79591DB5-1EE1-4CBD-AA5D-2E3EDF31155E";
+ final DMNRuntime runtime =
DMNRuntimeUtil.createRuntime("invalid_models/DMNv1_6/DMN-MultipleInvalidElements"
+
+
".dmn", this.getClass());
+ ((DMNRuntimeImpl)runtime).setOption(new
RuntimeModeOption(RuntimeModeOption.MODE.STRICT));
+ final DMNModel dmnModel = runtime.getModel(
+ nameSpace,
+ "DMN_8F7C4323-412A-4E0B-9AEF-0F24C8F55282");
+ assertThat(dmnModel).isNotNull();
+
assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse();
+ final DMNContext dmnContext = DMNFactory.newContext();
+ dmnContext.set("id", "_7273EA2E-2CC3-4012-8F87-39E310C8DF3C");
+ dmnContext.set("Conditional Input", 107);
+ dmnContext.set("New Input Data", 8888);
+ dmnContext.set("Score", 80);
+ final DMNResult dmnResult = runtime.evaluateAll(dmnModel, dmnContext);
+
assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isTrue();
+
assertThat(dmnResult.getMessages(DMNMessage.Severity.ERROR).size()).isEqualTo(2);
+ assertThat(dmnResult.getDecisionResults()).isNotNull().hasSize(3);
+ dmnResult.getDecisionResults().forEach(decisionResult ->
assertThat(decisionResult.getResult()).isNull());
+ }
+
+ @ParameterizedTest
+ @MethodSource("params")
+ void errorHandlingWithStrictModeEvaluateInvalidDecision(boolean
useExecModelCompiler) {
+ init(useExecModelCompiler);
+ String nameSpace =
"https://kie.org/dmn/_79591DB5-1EE1-4CBD-AA5D-2E3EDF31155E";
+ final DMNRuntime runtime =
DMNRuntimeUtil.createRuntime("invalid_models/DMNv1_6/DMN-MultipleInvalidElements"
+
+
".dmn", this.getClass());
+ ((DMNRuntimeImpl)runtime).setOption(new
RuntimeModeOption(RuntimeModeOption.MODE.STRICT));
+ final DMNModel dmnModel = runtime.getModel(
+ nameSpace,
+ "DMN_8F7C4323-412A-4E0B-9AEF-0F24C8F55282");
+ assertThat(dmnModel).isNotNull();
+
assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse();
+ final DMNContext dmnContext = DMNFactory.newContext();
+ dmnContext.set("id", "_7273EA2E-2CC3-4012-8F87-39E310C8DF3C");
+ dmnContext.set("Conditional Input", 107);
+ dmnContext.set("New Input Data", 8888);
+ dmnContext.set("Score", 80);
+ final DMNResult dmnResult = runtime.evaluateById(dmnModel, dmnContext,
"_A40F3AA4-2832-4D98-83F0-7D604F9A090F");
+
assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isTrue();
+
assertThat(dmnResult.getMessages(DMNMessage.Severity.ERROR).size()).isEqualTo(1);
+ assertThat(dmnResult.getDecisionResults()).isNotNull().hasSize(3);
+ dmnResult.getDecisionResults().forEach(decisionResult ->
assertThat(decisionResult.getResult()).isNull());
+ }
+
+ @ParameterizedTest
+ @MethodSource("params")
+ void errorHandlingWithStrictModeEvaluateValidDecision(boolean
useExecModelCompiler) {
+ init(useExecModelCompiler);
+ String nameSpace =
"https://kie.org/dmn/_79591DB5-1EE1-4CBD-AA5D-2E3EDF31155E";
+ final DMNRuntime runtime =
DMNRuntimeUtil.createRuntime("invalid_models/DMNv1_6/DMN-MultipleInvalidElements"
+
+
".dmn", this.getClass());
+ ((DMNRuntimeImpl)runtime).setOption(new
RuntimeModeOption(RuntimeModeOption.MODE.STRICT));
+ final DMNModel dmnModel = runtime.getModel(
+ nameSpace,
+ "DMN_8F7C4323-412A-4E0B-9AEF-0F24C8F55282");
+ assertThat(dmnModel).isNotNull();
+
assertThat(dmnModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnModel.getMessages())).isFalse();
+ final DMNContext dmnContext = DMNFactory.newContext();
+ dmnContext.set("id", "_7273EA2E-2CC3-4012-8F87-39E310C8DF3C");
+ dmnContext.set("Conditional Input", 107);
+ dmnContext.set("New Input Data", 8888);
+ dmnContext.set("Score", 80);
+ final DMNResult dmnResult = runtime.evaluateById(dmnModel, dmnContext,
"_E9468D45-51EB-48DA-8B30-7D65696FDFB8");
+
assertThat(dmnResult.hasErrors()).as(DMNRuntimeUtil.formatMessages(dmnResult.getMessages())).isFalse();
+ assertThat(dmnResult.getMessages(DMNMessage.Severity.ERROR)).isEmpty();
+ assertThat(dmnResult.getDecisionResults()).isNotNull().hasSize(3);
+ List<String> nullResults =
Arrays.asList("_A40F3AA4-2832-4D98-83F0-7D604F9A090F",
"_3DC41DB9-BE1D-4289-A639-24AB57ED082D");
+ String succeedResult = "_E9468D45-51EB-48DA-8B30-7D65696FDFB8";
+ nullResults.forEach(nullResult ->
assertThat(dmnResult.getDecisionResultById(nullResult).getResult()).isNull());
+
assertThat(dmnResult.getDecisionResultById(succeedResult).getResult()).isNotNull();
+ }
}
diff --git
a/kie-dmn/kie-dmn-test-resources/src/test/resources/invalid_models/DMNv1_6/DMN-MultipleInvalidElements.dmn
b/kie-dmn/kie-dmn-test-resources/src/test/resources/invalid_models/DMNv1_6/DMN-MultipleInvalidElements.dmn
new file mode 100644
index 0000000000..31f8288191
--- /dev/null
+++
b/kie-dmn/kie-dmn-test-resources/src/test/resources/invalid_models/DMNv1_6/DMN-MultipleInvalidElements.dmn
@@ -0,0 +1,196 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<definitions xmlns="https://www.omg.org/spec/DMN/20240513/MODEL/"
+ xmlns:dmndi="https://www.omg.org/spec/DMN/20230324/DMNDI/"
+ xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/"
+ xmlns:di="http://www.omg.org/spec/DMN/20180521/DI/"
+ xmlns:kie="https://kie.org/dmn/extensions/1.0"
+ expressionLanguage="https://www.omg.org/spec/DMN/20240513/FEEL/"
+
namespace="https://kie.org/dmn/_79591DB5-1EE1-4CBD-AA5D-2E3EDF31155E"
+ id="_C8433920-37EC-4814-A3DE-197917CDEB52"
+ name="DMN_8F7C4323-412A-4E0B-9AEF-0F24C8F55282">
+ <inputData name="New Input Data" id="_3A190E59-760B-45C2-86E6-2D50D8D9527C">
+ <variable name="New Input Data" id="_CE5FC851-DED9-48C1-9540-08ACDC56312C"
typeRef="string" />
+ </inputData>
+ <decision name="Decision1" id="_A40F3AA4-2832-4D98-83F0-7D604F9A090F">
+ <variable id="_9E0A3CF8-7B76-4908-B9A5-6ADED81780F4" typeRef="number"
name="Decision1" />
+ <informationRequirement id="_35609EBD-709A-4130-BFF9-826AA6FB605F">
+ <requiredInput href="#_3A190E59-760B-45C2-86E6-2D50D8D9527C" />
+ </informationRequirement>
+ <knowledgeRequirement id="_B27B7577-2FF5-47C9-8693-FAEECEE52EFB">
+ <requiredKnowledge href="#_09186183-0646-4CD0-AD67-A159E9F87F5E" />
+ </knowledgeRequirement>
+ <literalExpression id="_4AC1BD7D-5A8D-4A88-94F9-0B80BDF0D9B1"
typeRef="string" label="Decision1">
+ <text>Round Up(New Input Data)</text>
+ </literalExpression>
+ </decision>
+ <decision name="Decision2" id="_3DC41DB9-BE1D-4289-A639-24AB57ED082D">
+ <variable id="_ABCF6EB8-CF66-4D12-9B26-5D109C69328A" name="Decision2" />
+ <informationRequirement id="_5848A89D-BEED-4BCC-AFC5-EB2D96AE2A9F">
+ <requiredInput href="#_ED8D803B-1CE0-4BBF-B515-FFD98FD8BF21" />
+ </informationRequirement>
+ <conditional id="_2B147ECC-2457-4623-B841-3360D75F9F76" label="Decision2">
+ <if id="_AB2F8078-B54D-4D12-A9EB-1ABA5FA276F8">
+ <literalExpression id="_E9277A40-E525-40BB-90B5-540E81B0F451"
label="Expression Name">
+ <text>Conditional Input < 100</text>
+ </literalExpression>
+ </if>
+ <then id="_300AAEEE-70C0-4CEF-B241-FD6424D95C08">
+ <literalExpression id="_1FD8E4FC-8375-4EBB-B474-2BA28A3D613C"
label="Expression Name">
+ <text>100</text>
+ </literalExpression>
+ </then>
+ <else id="_6F318F57-DA06-4F71-80AD-288E0BBB3A52">
+ <literalExpression id="_43236F2B-9857-454F-8EA0-39B37C7519CF"
label="Expression Name">
+ <text>round up(Conditional Input, 15000)</text>
+ </literalExpression>
+ </else>
+ </conditional>
+ </decision>
+ <businessKnowledgeModel name="Round Up"
id="_09186183-0646-4CD0-AD67-A159E9F87F5E">
+ <variable name="Round Up" id="_D9B2ABE3-8F70-47EB-9F58-06A442F1AFB1"
typeRef="number" />
+ <encapsulatedLogic label="Round Up" typeRef="number"
id="_D386D137-582B-49F9-B6F9-F341C3AC4B3E" kind="FEEL">
+ <formalParameter id="_BD31D51E-29BC-49E5-97EE-55571DD97A35" name="New
Input Data" typeRef="number" />
+ <literalExpression id="_2E43C09D-011A-436C-B40B-9154405EAF3A"
typeRef="number" label="Return">
+ <text>round up(New Input Data, 12000)</text>
+ </literalExpression>
+ </encapsulatedLogic>
+ </businessKnowledgeModel>
+ <inputData name="Conditional Input"
id="_ED8D803B-1CE0-4BBF-B515-FFD98FD8BF21">
+ <variable name="Conditional Input"
id="_6953E989-101B-4AC9-AA08-963CFD8D7C7F" typeRef="number" />
+ </inputData>
+ <inputData name="Score" id="_75C34B3D-3B34-4E4A-97FE-BC349E436384">
+ <variable name="Score" id="_BA30B1A4-6AA6-45C1-AC3B-401401A19CC0"
typeRef="number" />
+ </inputData>
+ <decision name="Decision3" id="_E9468D45-51EB-48DA-8B30-7D65696FDFB8">
+ <variable name="Decision3" id="_58E0F2FB-0468-491F-96E3-22EE34F6394C"
typeRef="string" />
+ <informationRequirement id="_5CA9FF49-53D6-4531-BD54-A83FE0517FA5">
+ <requiredInput href="#_75C34B3D-3B34-4E4A-97FE-BC349E436384" />
+ </informationRequirement>
+ <decisionTable id="_E501048E-2655-46F8-95DE-39ECBED586A8" typeRef="string"
hitPolicy="UNIQUE" label="Decision3">
+ <input id="_1B359AD0-A378-47E7-AE30-CB4EE2AAFE1B">
+ <inputExpression id="_40F8D7F7-997F-4FBB-A0A5-58220C7D8054"
typeRef="number">
+ <text>Score</text>
+ </inputExpression>
+ </input>
+ <output id="_FAC0CB76-27A8-401A-8E6C-84260A1356DD" />
+ <annotation name="Annotations" />
+ <rule id="_5FC8F0E5-41A9-44BA-90AA-8F8C4ACE9659">
+ <inputEntry id="_57E40741-AABE-4E01-95DF-5A8C2240F9D0">
+ <text>>=90</text>
+ </inputEntry>
+ <outputEntry id="_BF64C76F-25EE-485A-AC38-87A986DC591E">
+ <text>"Excellent"</text>
+ </outputEntry>
+ <annotationEntry>
+ <text></text>
+ </annotationEntry>
+ </rule>
+ <rule id="_80A8E701-D227-4536-879C-E75BBE7D4CEB">
+ <inputEntry id="_AF86852D-F96D-4E72-BF71-A02E2308DF36">
+ <text>[70..90)</text>
+ </inputEntry>
+ <outputEntry id="_5AF82E14-2401-4300-9FBA-AF971BB19256">
+ <text>"Good"</text>
+ </outputEntry>
+ <annotationEntry>
+ <text></text>
+ </annotationEntry>
+ </rule>
+ <rule id="_A088B541-B86C-4A2E-ADF8-9D3BB18274AB">
+ <inputEntry id="_C44B2FE7-026A-400A-8D81-3A316D8B5E12">
+ <text>[50..70)</text>
+ </inputEntry>
+ <outputEntry id="_E7E20B17-82D7-4272-BB15-3ABEDE747ADA">
+ <text>"Fair"</text>
+ </outputEntry>
+ <annotationEntry>
+ <text></text>
+ </annotationEntry>
+ </rule>
+ </decisionTable>
+ </decision>
+ <dmndi:DMNDI>
+ <dmndi:DMNDiagram id="_35F2B440-6456-4617-9288-C1DB4571BD64" name="Default
DRD" useAlternativeInputDataShape="false">
+ <di:extension>
+ <kie:ComponentsWidthsExtension>
+ <kie:ComponentWidths
dmnElementRef="_4AC1BD7D-5A8D-4A88-94F9-0B80BDF0D9B1">
+ <kie:width>190</kie:width>
+ </kie:ComponentWidths>
+ <kie:ComponentWidths
dmnElementRef="_2E43C09D-011A-436C-B40B-9154405EAF3A">
+ <kie:width>190</kie:width>
+ </kie:ComponentWidths>
+ <kie:ComponentWidths
dmnElementRef="_E9277A40-E525-40BB-90B5-540E81B0F451">
+ <kie:width>190</kie:width>
+ </kie:ComponentWidths>
+ <kie:ComponentWidths
dmnElementRef="_1FD8E4FC-8375-4EBB-B474-2BA28A3D613C">
+ <kie:width>190</kie:width>
+ </kie:ComponentWidths>
+ <kie:ComponentWidths
dmnElementRef="_43236F2B-9857-454F-8EA0-39B37C7519CF">
+ <kie:width>190</kie:width>
+ </kie:ComponentWidths>
+ <kie:ComponentWidths
dmnElementRef="_E501048E-2655-46F8-95DE-39ECBED586A8">
+ <kie:width>60</kie:width>
+ <kie:width>118</kie:width>
+ <kie:width>118</kie:width>
+ <kie:width>240</kie:width>
+ </kie:ComponentWidths>
+ </kie:ComponentsWidthsExtension>
+ </di:extension>
+ <dmndi:DMNShape id="_10BB430B-C3BB-4787-8BD3-C16902638A42"
dmnElementRef="_3A190E59-760B-45C2-86E6-2D50D8D9527C" isCollapsed="false"
isListedInputData="false">
+ <dc:Bounds x="60" y="-20" width="160" height="80" />
+ </dmndi:DMNShape>
+ <dmndi:DMNShape id="_2AE7DDAE-7164-4079-BFB1-D3D64EDCDE1D"
dmnElementRef="_A40F3AA4-2832-4D98-83F0-7D604F9A090F" isCollapsed="false"
isListedInputData="false">
+ <dc:Bounds x="320" y="-20" width="160" height="80" />
+ </dmndi:DMNShape>
+ <dmndi:DMNShape id="_E4AF0974-016B-427B-B3B7-D61CBE26FD14"
dmnElementRef="_3DC41DB9-BE1D-4289-A639-24AB57ED082D" isCollapsed="false"
isListedInputData="false">
+ <dc:Bounds x="620" y="-20" width="160" height="80" />
+ </dmndi:DMNShape>
+ <dmndi:DMNShape id="_CC5CFF75-4E2D-4B09-BA95-FD51EE4BAAAB"
dmnElementRef="_09186183-0646-4CD0-AD67-A159E9F87F5E" isCollapsed="false"
isListedInputData="false">
+ <dc:Bounds x="320" y="240" width="160" height="80" />
+ </dmndi:DMNShape>
+ <dmndi:DMNEdge id="_B7A4C183-976B-4578-92E7-5AF0759E9158"
dmnElementRef="_B27B7577-2FF5-47C9-8693-FAEECEE52EFB"
sourceElement="_CC5CFF75-4E2D-4B09-BA95-FD51EE4BAAAB"
targetElement="_2AE7DDAE-7164-4079-BFB1-D3D64EDCDE1D">
+ <di:waypoint x="400" y="280" />
+ <di:waypoint x="400" y="60" />
+ </dmndi:DMNEdge>
+ <dmndi:DMNShape id="_8E12F39F-A1C2-4FB8-A501-49E91BFDE5A4"
dmnElementRef="_ED8D803B-1CE0-4BBF-B515-FFD98FD8BF21" isCollapsed="false"
isListedInputData="false">
+ <dc:Bounds x="620" y="240" width="160" height="80" />
+ </dmndi:DMNShape>
+ <dmndi:DMNEdge id="_0DDFB6F2-F49C-4D2A-9550-D87D0B87A23B"
dmnElementRef="_5848A89D-BEED-4BCC-AFC5-EB2D96AE2A9F"
sourceElement="_8E12F39F-A1C2-4FB8-A501-49E91BFDE5A4"
targetElement="_E4AF0974-016B-427B-B3B7-D61CBE26FD14">
+ <di:waypoint x="700" y="280" />
+ <di:waypoint x="700" y="60" />
+ </dmndi:DMNEdge>
+ <dmndi:DMNShape id="_E0821EF3-39D4-40B3-9AF0-84BB63BAA6E9"
dmnElementRef="_75C34B3D-3B34-4E4A-97FE-BC349E436384" isCollapsed="false"
isListedInputData="false">
+ <dc:Bounds x="960" y="240" width="160" height="80" />
+ </dmndi:DMNShape>
+ <dmndi:DMNEdge id="_C53BF307-1AF2-4643-A330-AC7F5DCB7874"
dmnElementRef="_35609EBD-709A-4130-BFF9-826AA6FB605F"
sourceElement="_10BB430B-C3BB-4787-8BD3-C16902638A42"
targetElement="_2AE7DDAE-7164-4079-BFB1-D3D64EDCDE1D">
+ <di:waypoint x="140" y="20" />
+ <di:waypoint x="320" y="20" />
+ </dmndi:DMNEdge>
+ <dmndi:DMNShape id="_12F67582-B006-4EA7-9483-0812FBF59743"
dmnElementRef="_E9468D45-51EB-48DA-8B30-7D65696FDFB8" isCollapsed="false"
isListedInputData="false">
+ <dc:Bounds x="960" y="-20" width="160" height="80" />
+ </dmndi:DMNShape>
+ <dmndi:DMNEdge id="_E53F65D7-6626-4B65-BDC9-2938470BF223"
dmnElementRef="_5CA9FF49-53D6-4531-BD54-A83FE0517FA5"
sourceElement="_E0821EF3-39D4-40B3-9AF0-84BB63BAA6E9"
targetElement="_12F67582-B006-4EA7-9483-0812FBF59743">
+ <di:waypoint x="1040" y="280" />
+ <di:waypoint x="1040" y="60" />
+ </dmndi:DMNEdge>
+ </dmndi:DMNDiagram>
+ </dmndi:DMNDI>
+</definitions>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]