This is an automated email from the ASF dual-hosted git repository.
yamer 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 2f93a92a59 [Incubator-kie-issues#2190] DMN - missing evaluationHitIds
in evaluated decision table (#6553)
2f93a92a59 is described below
commit 2f93a92a591cbbf163d2f14f4949889e7245b2da
Author: AthiraHari77 <[email protected]>
AuthorDate: Wed Jan 14 20:11:37 2026 +0530
[Incubator-kie-issues#2190] DMN - missing evaluationHitIds in evaluated
decision table (#6553)
* [incubator-kie-issues#2190] Add dmn to test evaluationHitIds
* [incubator-kie-issues#2190] WIP
* [incubator-kie-issues#2190] WIP
* [incubator-kie-issues#2190] WIP
* [incubator-kie-issues#2190] WIP
* [incubator-kie-issues#2190] WIP
* [incubator-kie-issues#2190] Fix evaluationhitids population
* [incubator-kie-issues#2190] Update test case
* [incubator-kie-issues#2190] Code cleanup
* [incubator-kie-issues#2190] Fix review comments
* [incubator-kie-issues#2190] Fix review comments
* [incubator-kie-issues#2190] Update test
* [incubator-kie-issues#2190] Update tests
* [incubator-kie-issues#2190] Code cleanup
* [incubator-kie-issues#2190] Code cleanup
* [incubator-kie-issues#2190] Code cleanup
* [incubator-kie-issues#2190] Code cleanup
---------
Co-authored-by: athira <[email protected]>
---
.../event/AfterEvaluateDecisionTableEvent.java | 6 +
.../dmn/api/core/event/DMNRuntimeEventManager.java | 6 +
.../core/jsr223/JSR223DTExpressionEvaluator.java | 5 +-
.../kie/dmn/core/ast/DMNDTExpressionEvaluator.java | 8 +-
.../DMNAlphaNetworkEvaluatorImpl.java | 3 +-
.../impl/AfterEvaluateDecisionTableEventImpl.java | 13 +-
.../dmn/core/impl/DMNRuntimeEventManagerImpl.java | 26 ++++
.../dmn/core/impl/DMNRuntimeEventManagerUtils.java | 4 +-
.../java/org/kie/dmn/core/impl/DMNRuntimeImpl.java | 7 +
.../core/impl/DMNRuntimeEventManagerUtilsTest.java | 143 ++++++++++++++++++++-
.../DMNv1_6/decisionsInBKMWithNameInput.dmn | 133 +++++++++++++++++++
11 files changed, 339 insertions(+), 15 deletions(-)
diff --git
a/kie-dmn/kie-dmn-api/src/main/java/org/kie/dmn/api/core/event/AfterEvaluateDecisionTableEvent.java
b/kie-dmn/kie-dmn-api/src/main/java/org/kie/dmn/api/core/event/AfterEvaluateDecisionTableEvent.java
index 0885f060e0..265ad5b6a0 100644
---
a/kie-dmn/kie-dmn-api/src/main/java/org/kie/dmn/api/core/event/AfterEvaluateDecisionTableEvent.java
+++
b/kie-dmn/kie-dmn-api/src/main/java/org/kie/dmn/api/core/event/AfterEvaluateDecisionTableEvent.java
@@ -34,6 +34,12 @@ public interface AfterEvaluateDecisionTableEvent extends
DMNEvent {
return null;
}
+ /**
+ * Returns the name of the decision for which this decision table is being
evaluated.
+ * @return the name of the decision associated with decision table
+ */
+ String getDecisionName();
+
List<Integer> getMatches();
List<Integer> getSelected();
diff --git
a/kie-dmn/kie-dmn-api/src/main/java/org/kie/dmn/api/core/event/DMNRuntimeEventManager.java
b/kie-dmn/kie-dmn-api/src/main/java/org/kie/dmn/api/core/event/DMNRuntimeEventManager.java
index 9c07d406d3..d330612230 100644
---
a/kie-dmn/kie-dmn-api/src/main/java/org/kie/dmn/api/core/event/DMNRuntimeEventManager.java
+++
b/kie-dmn/kie-dmn-api/src/main/java/org/kie/dmn/api/core/event/DMNRuntimeEventManager.java
@@ -57,4 +57,10 @@ public interface DMNRuntimeEventManager {
DMNRuntime getRuntime();
+ /**
+ * Returns the name of the decision that is currently being evaluated
+ * @return the name of the decision currently being evaluated
+ */
+ String getCurrentEvaluatingDecisionName();
+
}
diff --git
a/kie-dmn/kie-dmn-core-jsr223/src/main/java/org/kie/dmn/core/jsr223/JSR223DTExpressionEvaluator.java
b/kie-dmn/kie-dmn-core-jsr223/src/main/java/org/kie/dmn/core/jsr223/JSR223DTExpressionEvaluator.java
index 7cac3907f1..94f39b0368 100644
---
a/kie-dmn/kie-dmn-core-jsr223/src/main/java/org/kie/dmn/core/jsr223/JSR223DTExpressionEvaluator.java
+++
b/kie-dmn/kie-dmn-core-jsr223/src/main/java/org/kie/dmn/core/jsr223/JSR223DTExpressionEvaluator.java
@@ -32,6 +32,7 @@ import org.kie.dmn.api.core.DMNResult;
import org.kie.dmn.api.core.DMNRuntime;
import org.kie.dmn.api.core.DMNVersion;
import org.kie.dmn.api.core.ast.DMNNode;
+import org.kie.dmn.api.core.ast.DecisionNode;
import org.kie.dmn.api.core.event.DMNRuntimeEventManager;
import org.kie.dmn.api.feel.runtime.events.FEELEvent;
import org.kie.dmn.api.feel.runtime.events.FEELEventListener;
@@ -107,11 +108,11 @@ public class JSR223DTExpressionEvaluator implements
DMNExpressionEvaluator {
LOG.debug("failed evaluate", e);
throw new RuntimeException(e);
} finally {
- DMNRuntimeEventManagerUtils.fireAfterEvaluateDecisionTable( dmrem,
node.getName(), node.getName(), dt.getId(), result,
+ DMNRuntimeEventManagerUtils.fireAfterEvaluateDecisionTable(dmrem,
node.getName(), node.getName(), dt.getId(), result,
(r !=
null ? r.matchedRules : null),
(r !=
null ? r.fired : null),
(r !=
null ? r.matchedIds : null),
- (r !=
null ? r.firedIds : null));
+ (r !=
null ? r.firedIds : null), dmrem.getCurrentEvaluatingDecisionName());
}
}
diff --git
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDTExpressionEvaluator.java
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDTExpressionEvaluator.java
index 583d3e1115..de2993bbb9 100644
---
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDTExpressionEvaluator.java
+++
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDTExpressionEvaluator.java
@@ -23,11 +23,11 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
-import java.util.stream.Collectors;
import org.kie.dmn.api.core.DMNMessage;
import org.kie.dmn.api.core.DMNResult;
import org.kie.dmn.api.core.ast.DMNNode;
+import org.kie.dmn.api.core.ast.DecisionNode;
import org.kie.dmn.api.core.event.DMNRuntimeEventManager;
import org.kie.dmn.api.feel.runtime.events.FEELEvent;
import org.kie.dmn.core.api.DMNExpressionEvaluator;
@@ -76,7 +76,7 @@ public class DMNDTExpressionEvaluator
EventResults r = null;
try {
DMNRuntimeEventManagerUtils.fireBeforeEvaluateDecisionTable(
dmrem, node.getName(), dt.getName(), dtNodeId, result );
- List<String> paramNames =
dt.getParameters().get(0).stream().map(Param::getName).collect(Collectors.toList());
+ List<String> paramNames =
dt.getParameters().get(0).stream().map(Param::getName).toList();
Object[] params = new Object[paramNames.size()];
EvaluationContextImpl ctx =
feel.newEvaluationContext(List.of(events::add), Collections.emptyMap());
ctx.setPerformRuntimeTypeCheck(((DMNRuntimeImpl)
dmrem.getRuntime()).performRuntimeTypeCheck(result.getModel()));
@@ -103,11 +103,11 @@ public class DMNDTExpressionEvaluator
r = processEvents( events, dmrem, result, node );
return new EvaluatorResultImpl( dtr, r.hasErrors ?
ResultType.FAILURE : ResultType.SUCCESS );
} finally {
- DMNRuntimeEventManagerUtils.fireAfterEvaluateDecisionTable( dmrem,
node.getName(), dt.getName(), dtNodeId, result,
+ DMNRuntimeEventManagerUtils.fireAfterEvaluateDecisionTable(dmrem,
node.getName(), dt.getName(), dtNodeId, result,
(r !=
null ? r.matchedRules : null),
(r !=
null ? r.fired : null),
(r !=
null ? r.matchedIds : null),
- (r !=
null ? r.firedIds : null));
+ (r !=
null ? r.firedIds : null), dmrem.getCurrentEvaluatingDecisionName());
}
}
diff --git
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/alphanetbased/DMNAlphaNetworkEvaluatorImpl.java
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/alphanetbased/DMNAlphaNetworkEvaluatorImpl.java
index 65ad08a27a..912f6e32d5 100644
---
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/alphanetbased/DMNAlphaNetworkEvaluatorImpl.java
+++
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/compiler/alphanetbased/DMNAlphaNetworkEvaluatorImpl.java
@@ -24,6 +24,7 @@ import java.util.Optional;
import org.kie.dmn.api.core.DMNMessage;
import org.kie.dmn.api.core.DMNResult;
+import org.kie.dmn.api.core.ast.DecisionNode;
import org.kie.dmn.api.core.event.DMNRuntimeEventManager;
import org.kie.dmn.api.feel.runtime.events.FEELEvent;
import org.kie.dmn.core.api.DMNExpressionEvaluator;
@@ -114,7 +115,7 @@ public class DMNAlphaNetworkEvaluatorImpl implements
DMNExpressionEvaluator {
(eventResults != null ? eventResults.matchedRules : null),
(eventResults != null ? eventResults.fired : null),
(eventResults != null ? eventResults.matchedIds : null),
-
(eventResults != null ? eventResults.firedIds : null));
+
(eventResults != null ? eventResults.firedIds : null),
eventManager.getCurrentEvaluatingDecisionName());
}
}
diff --git
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/AfterEvaluateDecisionTableEventImpl.java
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/AfterEvaluateDecisionTableEventImpl.java
index fb588c168c..bff114efdb 100644
---
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/AfterEvaluateDecisionTableEventImpl.java
+++
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/AfterEvaluateDecisionTableEventImpl.java
@@ -35,8 +35,9 @@ public class AfterEvaluateDecisionTableEventImpl
private final List<Integer> fired;
private final List<String> matchesIds;
private final List<String> firedIds;
+ private final String decisionName;
- public AfterEvaluateDecisionTableEventImpl(String nodeName, String
decisionTableName, String dtId, DMNResult result, List<Integer> matches,
List<Integer> fired, List<String> matchesIds, List<String> firedIds) {
+ public AfterEvaluateDecisionTableEventImpl(String nodeName, String
decisionTableName, String dtId, DMNResult result, List<Integer> matches,
List<Integer> fired, List<String> matchesIds, List<String> firedIds, String
decisionName) {
this.nodeName = nodeName;
this.decisionTableName = decisionTableName;
this.dtId = dtId;
@@ -45,6 +46,7 @@ public class AfterEvaluateDecisionTableEventImpl
this.fired = fired;
this.matchesIds = matchesIds;
this.firedIds = firedIds;
+ this.decisionName = decisionName;
}
@Override
@@ -83,12 +85,17 @@ public class AfterEvaluateDecisionTableEventImpl
}
@Override
- public List<String> getSelectedIds() {return firedIds == null ?
Collections.emptyList() : firedIds;
+ public List<String> getSelectedIds() { return firedIds == null ?
Collections.emptyList() : firedIds;
+ }
+
+ @Override
+ public String getDecisionName() {
+ return decisionName;
}
@Override
public String toString() {
- return "AfterEvaluateDecisionTableEvent{ nodeName='"+ nodeName +"'
decisionTableName='" + decisionTableName + "' matches=" + getMatches() + "
fired=" + getSelected() + "' matchesIds=" + getMatchesIds() + " firedIds=" +
getSelectedIds() + " }";
+ return "AfterEvaluateDecisionTableEvent{ nodeName='"+ nodeName +"'
decisionTableName='" + decisionTableName + "' matches=" + getMatches() + "
fired=" + getSelected() + "' matchesIds=" + getMatchesIds() + " firedIds=" +
getSelectedIds() + " decisionName='" + decisionName + "' }";
}
}
diff --git
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeEventManagerImpl.java
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeEventManagerImpl.java
index bcfd567cc8..1eee6d0270 100644
---
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeEventManagerImpl.java
+++
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeEventManagerImpl.java
@@ -31,6 +31,20 @@ public class DMNRuntimeEventManagerImpl implements
DMNRuntimeEventManager {
private DMNRuntime dmnRuntime;
+ /**
+ * Tracks the name of the decision currently being evaluated.
+ * <p>
+ * Scope: This field is shared across all instances of this event manager,
but each thread
+ * maintains its own independent value through ThreadLocal storage.
+ * <p>
+ * Why ThreadLocal: Since a single DMNRuntimeEventManager instance can be
accessed by multiple
+ * threads evaluating different decisions concurrently, using ThreadLocal
prevents race conditions
+ * and ensures that each thread's evaluation context (the current decision
name) remains isolated
+ * from other threads. Without ThreadLocal, concurrent evaluations would
overwrite each other's
+ * decision names, leading to incorrect event reporting.
+ */
+ private final ThreadLocal<String> currentEvaluatingDecisionName = new
ThreadLocal<>();
+
public DMNRuntimeEventManagerImpl() {
}
@@ -66,4 +80,16 @@ public class DMNRuntimeEventManagerImpl implements
DMNRuntimeEventManager {
return dmnRuntime;
}
+ @Override
+ public String getCurrentEvaluatingDecisionName() {
+ return currentEvaluatingDecisionName.get();
+ }
+
+ void setCurrentEvaluatingDecisionName(String decisionName) {
+ currentEvaluatingDecisionName.set(decisionName);
+ }
+
+ void clearCurrentEvaluatingDecisionName() {
+ currentEvaluatingDecisionName.remove();
+ }
}
diff --git
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeEventManagerUtils.java
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeEventManagerUtils.java
index 91375613b3..3ff5d1f033 100644
---
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeEventManagerUtils.java
+++
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeEventManagerUtils.java
@@ -103,9 +103,9 @@ public final class DMNRuntimeEventManagerUtils {
}
}
- public static void fireAfterEvaluateDecisionTable( DMNRuntimeEventManager
eventManager, String nodeName, String dtName, String dtId, DMNResult result,
List<Integer> matches, List<Integer> fired, List<String> matchedIds,
List<String> firedIds ) {
+ public static void fireAfterEvaluateDecisionTable( DMNRuntimeEventManager
eventManager, String nodeName, String dtName, String dtId, DMNResult result,
List<Integer> matches, List<Integer> fired, List<String> matchedIds,
List<String> firedIds, String decisionName) {
if( eventManager.hasListeners() ) {
- AfterEvaluateDecisionTableEvent event = new
AfterEvaluateDecisionTableEventImpl(nodeName, dtName, dtId, result, matches,
fired, matchedIds, firedIds);
+ AfterEvaluateDecisionTableEvent event = new
AfterEvaluateDecisionTableEventImpl(nodeName, dtName, dtId, result, matches,
fired, matchedIds, firedIds, decisionName);
notifyListeners(eventManager, l ->
l.afterEvaluateDecisionTable(event));
}
}
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 b96cec4b01..5930f08f10 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
@@ -250,6 +250,11 @@ public class DMNRuntimeImpl
return this.eventManager.getListeners();
}
+ @Override
+ public String getCurrentEvaluatingDecisionName() {
+ return this.eventManager.getCurrentEvaluatingDecisionName();
+ }
+
private DMNResultImpl createResult(DMNModel model, DMNContext context) {
DMNResultImpl result = createResultImpl(model, context);
@@ -625,6 +630,7 @@ public class DMNRuntimeImpl
return false;
}
try {
+ eventManager.setCurrentEvaluatingDecisionName(d.getName());
EvaluatorResult er = decision.getEvaluator().evaluate(this,
result);
// if result messages contains errors && runtime mode = strict
-> stop execution and return null
if (strictMode && result.hasErrors()) {
@@ -703,6 +709,7 @@ public class DMNRuntimeImpl
} finally {
DMNRuntimeEventManagerUtils.fireAfterEvaluateDecision(eventManager, decision,
result,
beforeEvaluateDecisionEvent);
+ eventManager.clearCurrentEvaluatingDecisionName();
}
}
diff --git
a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/impl/DMNRuntimeEventManagerUtilsTest.java
b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/impl/DMNRuntimeEventManagerUtilsTest.java
index 52a51e7e41..762711f02a 100644
---
a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/impl/DMNRuntimeEventManagerUtilsTest.java
+++
b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/impl/DMNRuntimeEventManagerUtilsTest.java
@@ -19,8 +19,14 @@
package org.kie.dmn.core.impl;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.IntStream;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
@@ -33,6 +39,7 @@ import org.kie.dmn.api.core.DMNRuntime;
import org.kie.dmn.api.core.EvaluatorResult;
import org.kie.dmn.api.core.event.AfterConditionalEvaluationEvent;
import org.kie.dmn.api.core.event.AfterEvaluateConditionalEvent;
+import org.kie.dmn.api.core.event.AfterEvaluateDecisionTableEvent;
import org.kie.dmn.api.core.event.DMNRuntimeEventListener;
import org.kie.dmn.api.core.event.DMNRuntimeEventManager;
import org.kie.dmn.core.api.DMNFactory;
@@ -44,6 +51,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -72,7 +80,7 @@ class DMNRuntimeEventManagerUtilsTest {
String executedId = "EXECUTED_ID";
DMNRuntimeEventManagerUtils.fireAfterEvaluateConditional(eventManagerMock,
evaluatorResult, executedId);
ArgumentCaptor<AfterEvaluateConditionalEvent>
evaluateConditionalEventArgumentCaptor =
ArgumentCaptor.forClass(AfterEvaluateConditionalEvent.class);
- verify(spiedListener).afterEvaluateConditional
(evaluateConditionalEventArgumentCaptor.capture());
+
verify(spiedListener).afterEvaluateConditional(evaluateConditionalEventArgumentCaptor.capture());
AfterEvaluateConditionalEvent evaluateConditionalEvent =
evaluateConditionalEventArgumentCaptor.getValue();
assertThat(evaluateConditionalEvent).isNotNull();
assertThat(evaluateConditionalEvent.getEvaluatorResultResult()).isEqualTo(evaluatorResult);
@@ -87,7 +95,7 @@ class DMNRuntimeEventManagerUtilsTest {
String executedId = "EXECUTED_ID";
DMNRuntimeEventManagerUtils.fireAfterConditionalEvaluation(eventManagerMock,
conditionalName, decisionName, evaluatorResult, executedId);
ArgumentCaptor<AfterConditionalEvaluationEvent>
conditionalEvaluationEventArgumentCaptor =
ArgumentCaptor.forClass(AfterConditionalEvaluationEvent.class);
- verify(spiedListener).afterConditionalEvaluation
(conditionalEvaluationEventArgumentCaptor.capture());
+
verify(spiedListener).afterConditionalEvaluation(conditionalEvaluationEventArgumentCaptor.capture());
AfterConditionalEvaluationEvent evaluateConditionalEvent =
conditionalEvaluationEventArgumentCaptor.getValue();
assertThat(evaluateConditionalEvent).isNotNull();
assertThat(evaluateConditionalEvent.getNodeName()).isEqualTo(conditionalName);
@@ -117,7 +125,7 @@ class DMNRuntimeEventManagerUtilsTest {
assertThat(dmnResult.getDecisionResultByName(decisionName).getResult()).isEqualTo(List.of("pos"));
ArgumentCaptor<AfterConditionalEvaluationEvent>
conditionalEvaluationEventArgumentCaptor =
ArgumentCaptor.forClass(AfterConditionalEvaluationEvent.class);
- verify(spiedListener).afterConditionalEvaluation
(conditionalEvaluationEventArgumentCaptor.capture());
+
verify(spiedListener).afterConditionalEvaluation(conditionalEvaluationEventArgumentCaptor.capture());
AfterConditionalEvaluationEvent evaluateConditionalEvent =
conditionalEvaluationEventArgumentCaptor.getValue();
assertThat(evaluateConditionalEvent).isNotNull();
assertThat(evaluateConditionalEvent.getDecisionName()).isEqualTo(decisionName);
@@ -125,4 +133,133 @@ class DMNRuntimeEventManagerUtilsTest {
assertThat(retrieved).isNotNull();
assertThat(evaluateConditionalEvent.getExecutedId()).isEqualTo(executedId);
}
+
+ @Test
+ void testEvaluateDecisionTableEvent() {
+ String decisionName = "New Decision";
+ String bkmName = "New BKM";
+ String dtId = "_46B46F91-5810-452F-B1D4-A0B0304737B1";
+ Resource resource =
ResourceFactory.newClassPathResource("valid_models/DMNv1_6/decisionsInBKMWithNameInput.dmn");
+ DMNRuntime dmnRuntime = DMNRuntimeBuilder.fromDefaults()
+ .buildConfiguration()
+ .fromResources(Collections.singletonList(resource))
+ .getOrElseThrow(RuntimeException::new);
+ dmnRuntime.addListener(spiedListener);
+ assertThat(dmnRuntime).isNotNull();
+ String nameSpace =
"https://kie.org/dmn/_8010864B-CC05-4DB2-A6CB-B19968FD56BC";
+
+ final DMNModel dmnModel = dmnRuntime.getModel(nameSpace,
"DMN_DE9C9FE9-DF27-43B7-917C-96765C61467F");
+ assertThat(dmnModel).isNotNull();
+ DMNContext context = DMNFactory.newContext();
+ context.set("name", "2");
+ DMNResult dmnResult = dmnRuntime.evaluateAll(dmnModel, context);
+
assertThat(dmnResult.getDecisionResultByName(decisionName)).isNotNull();
+
assertThat(dmnResult.getDecisionResultByName(decisionName).getResult()).isEqualTo("bb");
+
+ ArgumentCaptor<AfterEvaluateDecisionTableEvent>
evaluateDecisionTableEventCaptor =
ArgumentCaptor.forClass(AfterEvaluateDecisionTableEvent.class);
+ verify(spiedListener,
times(5)).afterEvaluateDecisionTable(evaluateDecisionTableEventCaptor.capture());
+
+ AfterEvaluateDecisionTableEvent evaluateDecisionTableEvent =
evaluateDecisionTableEventCaptor.getAllValues().stream()
+ .filter(event -> decisionName.equals(event.getDecisionName()))
+ .findFirst()
+ .orElseThrow(() -> new IllegalArgumentException("No event
found for decision: " + decisionName));
+
+ assertThat(evaluateDecisionTableEvent).isNotNull();
+
assertThat(evaluateDecisionTableEvent.getDecisionName()).isEqualTo(decisionName);
+
assertThat(evaluateDecisionTableEvent.getNodeName()).isEqualTo(bkmName);
+
assertThat(evaluateDecisionTableEvent.getDecisionTableName()).isEqualTo(bkmName);
+
assertThat(evaluateDecisionTableEvent.getDecisionTableId()).isEqualTo(dtId);
+ assertThat(evaluateDecisionTableEvent.getSelected()).isNotEmpty();
+
assertThat(evaluateDecisionTableEvent.getSelectedIds()).contains("_4FCA6937-8E97-4513-8D43-460E6B7D5686");
+ }
+
+ @Test
+ void verifyDependentDecisionEvaluationEvents() {
+ String decisionName = "Loan Pre-Qualification";
+ String nodeName = "Loan Pre-Qualification";
+ String dtId = "_EF7F404A-939E-4889-95D8-E4053DD1EED9";
+ Resource resource =
ResourceFactory.newClassPathResource("valid_models/DMNv1_5/Sample.dmn");
+ DMNRuntime dmnRuntime = DMNRuntimeBuilder.fromDefaults()
+ .buildConfiguration()
+ .fromResources(Collections.singletonList(resource))
+ .getOrElseThrow(RuntimeException::new);
+ dmnRuntime.addListener(spiedListener);
+ assertThat(dmnRuntime).isNotNull();
+ String nameSpace =
"https://kie.apache.org/dmn/_857FE424-BEDA-4772-AB8E-2F4CDDB864AB";
+
+ final DMNModel dmnModel = dmnRuntime.getModel(nameSpace,
"loan_pre_qualification");
+ assertThat(dmnModel).isNotNull();
+ DMNContext context = DMNFactory.newContext();
+ context.set("Credit Score", Map.of("FICO", 700));
+
+ Map<String, Object> monthly = new HashMap<>();
+ monthly.put("Income", 121233);
+ monthly.put("Repayments", 33);
+ monthly.put("Expenses", 123);
+ monthly.put("Tax", 32);
+ monthly.put("Insurance", 55);
+ Map<String, Object> applicantData = new HashMap<>();
+ applicantData.put("Age", 32);
+ applicantData.put("Marital Status", "S");
+ applicantData.put("Employment Status", "Employed");
+ applicantData.put("Existing Customer", false);
+ applicantData.put("Monthly", monthly);
+ context.set("Applicant Data", applicantData);
+
+ Map<String, Object> requestedProduct = new HashMap<>();
+ requestedProduct.put("Type", "Special Loan");
+ requestedProduct.put("Rate", 1);
+ requestedProduct.put("Term", 2);
+ requestedProduct.put("Amount", 333);
+ context.set("Requested Product", requestedProduct);
+
+ context.set("id", "_0A185BAC-7692-45FA-B722-7C86C626BD51");
+
+ DMNResult dmnResult = dmnRuntime.evaluateAll(dmnModel, context);
+
assertThat(dmnResult.getDecisionResultByName(decisionName)).isNotNull();
+
+ ArgumentCaptor<AfterEvaluateDecisionTableEvent>
evaluateDecisionTableEventCaptor =
ArgumentCaptor.forClass(AfterEvaluateDecisionTableEvent.class);
+ verify(spiedListener,
times(2)).afterEvaluateDecisionTable(evaluateDecisionTableEventCaptor.capture());
+
+ AfterEvaluateDecisionTableEvent evaluateDecisionTableEvent =
evaluateDecisionTableEventCaptor.getAllValues().stream()
+ .filter(event -> decisionName.equals(event.getDecisionName()))
+ .findFirst()
+ .orElseThrow(() -> new IllegalArgumentException("No event
found for decision: " + decisionName));
+
+ assertThat(evaluateDecisionTableEvent).isNotNull();
+
assertThat(evaluateDecisionTableEvent.getDecisionName()).isEqualTo(decisionName);
+
assertThat(evaluateDecisionTableEvent.getNodeName()).isEqualTo(nodeName);
+
assertThat(evaluateDecisionTableEvent.getDecisionTableName()).isEqualTo(nodeName);
+
assertThat(evaluateDecisionTableEvent.getDecisionTableId()).isEqualTo(dtId);
+ assertThat(evaluateDecisionTableEvent.getSelected()).isNotEmpty();
+
assertThat(evaluateDecisionTableEvent.getSelectedIds()).contains("_C8FA33B1-AF6E-4A59-B7B9-6FDF1F495C44");
+ }
+
+ @Test
+ void testThreadLocalValue() throws Exception {
+ DMNRuntimeEventManagerImpl eventManager = new
DMNRuntimeEventManagerImpl();
+ int elements = 6;
+ Set<Thread> threads = new HashSet<>();
+ Map<Integer, AtomicReference<String>> mappedThreadValues = new
HashMap<>();
+ CountDownLatch latch = new CountDownLatch(elements);
+
+ IntStream.range(0, elements).forEach(i -> {
+ AtomicReference<String> threadValue = new AtomicReference<>();
+ Thread thread = new Thread(() -> {
+ eventManager.setCurrentEvaluatingDecisionName("New Decision "
+ i);
+
threadValue.set(eventManager.getCurrentEvaluatingDecisionName());
+ eventManager.clearCurrentEvaluatingDecisionName();
+
assertThat(eventManager.getCurrentEvaluatingDecisionName()).isNull();
+ latch.countDown();
+ });
+ mappedThreadValues.put(i, threadValue);
+ threads.add(thread);
+ });
+
+ threads.forEach(Thread::start);
+ latch.await();
+
+ mappedThreadValues.forEach((i, threadValue) ->
assertThat(threadValue.get()).isEqualTo("New Decision " + i));
+ }
+
}
\ No newline at end of file
diff --git
a/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_6/decisionsInBKMWithNameInput.dmn
b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_6/decisionsInBKMWithNameInput.dmn
new file mode 100644
index 0000000000..09060c8092
--- /dev/null
+++
b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_6/decisionsInBKMWithNameInput.dmn
@@ -0,0 +1,133 @@
+<?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/_8010864B-CC05-4DB2-A6CB-B19968FD56BC"
id="_728A50FD-CCEC-43E0-ACB1-0F2461B7FAF1"
name="DMN_DE9C9FE9-DF27-43B7-917C-9676 [...]
+ <decision name="New Decision" id="_8377E2EC-82E5-4475-B4E6-2B15225D7BD9">
+ <variable id="_B7D83BCF-2B6D-4A6B-A136-6C911CC05ABB" typeRef="string"
name="New Decision" />
+ <informationRequirement id="_9FA66027-794F-41B4-9C89-BFF30CD0736C">
+ <requiredInput href="#_12359977-D958-4485-83C5-D79AF3FF8863" />
+ </informationRequirement>
+ <knowledgeRequirement id="_1315758F-AD90-4216-B54E-EC96C31329FD">
+ <requiredKnowledge href="#_93668164-47E9-4A97-AA50-67C31645D2D7" />
+ </knowledgeRequirement>
+ <literalExpression id="_71FC6055-83B3-4669-8DA6-49596A1011DD"
typeRef="string" label="New Decision">
+ <text>New BKM(name) + New BKM(name)</text>
+ </literalExpression>
+ </decision>
+ <decision name="New Decision 2" id="_6A689F06-1D94-470B-B24E-702B79F1C4A9">
+ <variable name="New Decision 2" id="_0FC0CF47-B754-440D-A1E5-44F328AE9A3D"
typeRef="string" />
+ <informationRequirement id="_99556EFA-7C2F-4683-8A5B-9B9B67B26994">
+ <requiredInput href="#_12359977-D958-4485-83C5-D79AF3FF8863" />
+ </informationRequirement>
+ <knowledgeRequirement id="_2D31AC83-821C-4E2E-850C-8E0E0DC6A4AC">
+ <requiredKnowledge href="#_93668164-47E9-4A97-AA50-67C31645D2D7" />
+ </knowledgeRequirement>
+ <literalExpression id="_D885169F-4023-4AAF-A4D1-E8BEA0B7D6A6"
typeRef="string" label="New Decision 2">
+ <text>New BKM(name) + New BKM(name) + New BKM(name)</text>
+ </literalExpression>
+ </decision>
+ <businessKnowledgeModel name="New BKM"
id="_93668164-47E9-4A97-AA50-67C31645D2D7">
+ <variable name="New BKM" id="_1C01DB54-70D6-4D54-B718-F9CA030EC396"
typeRef="string" />
+ <encapsulatedLogic label="New BKM" typeRef="string"
id="_8A70C3DA-7940-4384-9F8D-EA52F24838A2" kind="FEEL">
+ <formalParameter id="_8BC2757D-AE9D-46C4-9346-8152C917BED2" name="name"
typeRef="string" />
+ <decisionTable id="_46B46F91-5810-452F-B1D4-A0B0304737B1"
typeRef="string" hitPolicy="UNIQUE" label="Return">
+ <input id="_E833CBD2-9DA2-4CD8-9D27-E7B3482AABB2">
+ <inputExpression id="_B59142DC-D45D-41A3-AF99-1836D1F833BF"
typeRef="string">
+ <text>name</text>
+ </inputExpression>
+ </input>
+ <output id="_5FF999A4-4B03-43DE-A258-EF87A27CA201" />
+ <annotation name="Annotations" />
+ <rule id="_1B2F0690-03E4-4BC0-82C1-D4A9F2379269">
+ <inputEntry id="_5EB126DB-BBEE-47EA-9F0E-E147F7CE9FEB">
+ <text>"1"</text>
+ </inputEntry>
+ <outputEntry id="_5136ECF6-629F-48AB-83EC-42B6AF95B1D7">
+ <text>"a"</text>
+ </outputEntry>
+ <annotationEntry>
+ <text></text>
+ </annotationEntry>
+ </rule>
+ <rule id="_4FCA6937-8E97-4513-8D43-460E6B7D5686">
+ <inputEntry id="_854C2344-64D1-40BC-8963-7979C31B4BEC">
+ <text>"2"</text>
+ </inputEntry>
+ <outputEntry id="_6026F313-1ED2-4153-99DE-1F7236E2942B">
+ <text>"b"</text>
+ </outputEntry>
+ <annotationEntry>
+ <text></text>
+ </annotationEntry>
+ </rule>
+ </decisionTable>
+ </encapsulatedLogic>
+ </businessKnowledgeModel>
+ <inputData name="name" id="_12359977-D958-4485-83C5-D79AF3FF8863">
+ <variable name="name" id="_D5727689-B3DD-4E50-AB00-59E4D8EC7C74"
typeRef="string" />
+ </inputData>
+ <dmndi:DMNDI>
+ <dmndi:DMNDiagram id="_C41A0576-32B3-44F6-9BAA-34A8F2301FD6" name="Default
DRD" useAlternativeInputDataShape="false">
+ <di:extension>
+ <kie:ComponentsWidthsExtension>
+ <kie:ComponentWidths
dmnElementRef="_71FC6055-83B3-4669-8DA6-49596A1011DD">
+ <kie:width>345</kie:width>
+ </kie:ComponentWidths>
+ <kie:ComponentWidths
dmnElementRef="_46B46F91-5810-452F-B1D4-A0B0304737B1">
+ <kie:width>60</kie:width>
+ <kie:width>118</kie:width>
+ <kie:width>118</kie:width>
+ <kie:width>240</kie:width>
+ </kie:ComponentWidths>
+ <kie:ComponentWidths
dmnElementRef="_D885169F-4023-4AAF-A4D1-E8BEA0B7D6A6">
+ <kie:width>383</kie:width>
+ </kie:ComponentWidths>
+ </kie:ComponentsWidthsExtension>
+ </di:extension>
+ <dmndi:DMNShape id="_350D0412-78E3-45EA-83F4-EB9FEB02976E"
dmnElementRef="_8377E2EC-82E5-4475-B4E6-2B15225D7BD9" isCollapsed="false"
isListedInputData="false">
+ <dc:Bounds x="160" y="40" width="160" height="80" />
+ </dmndi:DMNShape>
+ <dmndi:DMNShape id="_970774E6-8C1F-4527-A94A-1BF59FEE7F66"
dmnElementRef="_93668164-47E9-4A97-AA50-67C31645D2D7" isCollapsed="false"
isListedInputData="false">
+ <dc:Bounds x="420" y="80" width="160" height="80" />
+ </dmndi:DMNShape>
+ <dmndi:DMNShape id="_15507C8E-7792-4369-A5D3-88677AB2A297"
dmnElementRef="_6A689F06-1D94-470B-B24E-702B79F1C4A9" isCollapsed="false"
isListedInputData="false">
+ <dc:Bounds x="160" y="160" width="160" height="80" />
+ </dmndi:DMNShape>
+ <dmndi:DMNShape id="_CDA349BC-98B9-4B6A-9269-F40BA3C4F117"
dmnElementRef="_12359977-D958-4485-83C5-D79AF3FF8863" isCollapsed="false"
isListedInputData="false">
+ <dc:Bounds x="560" y="320" width="160" height="80" />
+ </dmndi:DMNShape>
+ <dmndi:DMNEdge id="_97F1A8D9-FA34-4721-AD0F-5E10DF7A2330"
dmnElementRef="_1315758F-AD90-4216-B54E-EC96C31329FD"
sourceElement="_970774E6-8C1F-4527-A94A-1BF59FEE7F66"
targetElement="_350D0412-78E3-45EA-83F4-EB9FEB02976E">
+ <di:waypoint x="500" y="120" />
+ <di:waypoint x="320" y="80" />
+ </dmndi:DMNEdge>
+ <dmndi:DMNEdge id="_054F4FED-8333-453D-81F6-5B5155144BD1"
dmnElementRef="_2D31AC83-821C-4E2E-850C-8E0E0DC6A4AC"
sourceElement="_970774E6-8C1F-4527-A94A-1BF59FEE7F66"
targetElement="_15507C8E-7792-4369-A5D3-88677AB2A297">
+ <di:waypoint x="500" y="120" />
+ <di:waypoint x="320" y="200" />
+ </dmndi:DMNEdge>
+ <dmndi:DMNEdge id="_3589E9F9-C8FC-4F14-BD54-612645A3AABA"
dmnElementRef="_99556EFA-7C2F-4683-8A5B-9B9B67B26994"
sourceElement="_CDA349BC-98B9-4B6A-9269-F40BA3C4F117"
targetElement="_15507C8E-7792-4369-A5D3-88677AB2A297">
+ <di:waypoint x="640" y="360" />
+ <di:waypoint x="240" y="240" />
+ </dmndi:DMNEdge>
+ <dmndi:DMNEdge id="_61104987-502A-4BAC-934B-4B1635D5C119"
dmnElementRef="_9FA66027-794F-41B4-9C89-BFF30CD0736C"
sourceElement="_CDA349BC-98B9-4B6A-9269-F40BA3C4F117"
targetElement="_350D0412-78E3-45EA-83F4-EB9FEB02976E">
+ <di:waypoint x="640" y="360" />
+ <di:waypoint x="320" y="80" />
+ </dmndi:DMNEdge>
+ </dmndi:DMNDiagram>
+ </dmndi:DMNDI>
+</definitions>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]