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-kogito-apps.git


The following commit(s) were added to refs/heads/main by this push:
     new 2aa57d745 [Incubator kie issues#1882] DMN: Return full path of invalid 
element (until its root) from jit-executor  (#2206)
2aa57d745 is described below

commit 2aa57d74543b9a85dd24c82eeabe46536a2754d2
Author: AthiraHari77 <[email protected]>
AuthorDate: Mon Apr 14 13:29:01 2025 +0530

    [Incubator kie issues#1882] DMN: Return full path of invalid element (until 
its root) from jit-executor  (#2206)
    
    * [incubator-kie-issues#1882] WIP
    
    * [incubator-kie-issues#1882] WIP
    
    * [incubator-kie-issues#1882] WIP
    
    * [incubator-kie-issues#1882] update models
    
    * [incubator-kie-issues#1882] update testcases
    
    * [incubator-kie-issues#1882] update testcases
    
    * [incubator-kie-issues#1882] Fix review comments
    
    * [incubator-kie-issues#1882] code refactoring
    
    * [incubator-kie-issues#1882] code refactoring
    
    * [incubator-kie-issues#1882] code formatted
    
    * [incubator-kie-issues#1882] code formatted
    
    * [incubator-kie-issues#1882] code formatted
    
    * [incubator-kie-issues#1882] sort imports
    
    * [incubator-kie-issues#1882] Remove duplicate paths
    
    * [incubator-kie-issues#1882] Remove duplicate paths
    
    * [incubator-kie-issues#1882] Fix review comments
    
    * [incubator-kie-issues#1882] Code formatted
    
    * [incubator-kie-issues#1882] Test cases updated
    
    ---------
    
    Co-authored-by: athira <[email protected]>
---
 .../kie/kogito/jitexecutor/dmn/DMNEvaluator.java   |  77 ++++++++++++-
 .../kogito/jitexecutor/dmn/JITDMNServiceImpl.java  |   4 +-
 .../jitexecutor/dmn/responses/JITDMNResult.java    |  15 ++-
 .../kogito/jitexecutor/dmn/DMNEvaluatorTest.java   | 127 +++++++++++++++++++++
 .../jitexecutor/dmn/api/JITDMNResourceTest.java    |  23 +++-
 .../dmn/responses/JITDMNResultTest.java            |  47 +++++++-
 6 files changed, 283 insertions(+), 10 deletions(-)

diff --git 
a/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/DMNEvaluator.java
 
b/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/DMNEvaluator.java
index 0f364d000..c0f43ce6f 100644
--- 
a/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/DMNEvaluator.java
+++ 
b/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/DMNEvaluator.java
@@ -19,11 +19,13 @@
 package org.kie.kogito.jitexecutor.dmn;
 
 import java.io.StringReader;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.stream.Collectors;
 
@@ -38,6 +40,10 @@ import org.kie.dmn.core.compiler.RuntimeTypeCheckOption;
 import org.kie.dmn.core.impl.DMNRuntimeImpl;
 import org.kie.dmn.core.internal.utils.DMNRuntimeBuilder;
 import org.kie.dmn.core.internal.utils.DynamicDMNContextBuilder;
+import org.kie.dmn.model.api.ChildExpression;
+import org.kie.dmn.model.api.DMNElement;
+import org.kie.dmn.model.api.DMNModelInstrumentedBase;
+import org.kie.dmn.model.api.Definitions;
 import org.kie.internal.io.ResourceFactory;
 import org.kie.kogito.jitexecutor.common.requests.MultipleResourcesPayload;
 import org.kie.kogito.jitexecutor.common.requests.ResourceWithURI;
@@ -95,6 +101,74 @@ public class DMNEvaluator {
         }
     }
 
+    static List<String> getPathToRoot(DMNModel dmnModel, String invalidId) {
+        List<String> path = new ArrayList<>();
+        DMNModelInstrumentedBase node = getNodeById(dmnModel, invalidId);
+
+        while (node != null && !(node instanceof Definitions)) {
+            if (node instanceof DMNElement dmnElement) {
+                path.add(dmnElement.getId());
+            } else if (node instanceof ChildExpression childExpression) {
+                path.add(childExpression.getId());
+            } else {
+                path.add(node.getIdentifierString());
+            }
+            node = node.getParent();
+        }
+        Collections.reverse(path);
+        return path.isEmpty() ? Collections.singletonList(invalidId) : path;
+    }
+
+    static DMNModelInstrumentedBase getNodeById(DMNModel dmnModel, String id) {
+        return dmnModel.getDefinitions().getChildren().stream().map(child -> 
getNodeById(child, id))
+                .filter(Objects::nonNull).findFirst().orElse(null);
+    }
+
+    static DMNModelInstrumentedBase getNodeById(DMNModelInstrumentedBase 
dmnModelInstrumentedBase, String id) {
+        if (dmnModelInstrumentedBase.getIdentifierString().equals(id)) {
+            return dmnModelInstrumentedBase;
+        }
+        for (DMNModelInstrumentedBase child : 
dmnModelInstrumentedBase.getChildren()) {
+            DMNModelInstrumentedBase result = getNodeById(child, id);
+            if (result != null) {
+                return result;
+            }
+        }
+        return null;
+    }
+
+    static List<List<String>> retrieveInvalidElementPaths(List<DMNMessage> 
messages, DMNModel dmnModel) {
+        List<List<String>> invalidElementPaths = 
messages.stream().filter(message -> 
message.getLevel().equals(Message.Level.WARNING) ||
+                message.getLevel().equals(Message.Level.ERROR)).map(message -> 
getPathToRoot(dmnModel, message.getSourceId())).collect(Collectors.toList());
+        return removeDuplicates(invalidElementPaths);
+    }
+
+    static List<List<String>> removeDuplicates(List<List<String>> 
invalidElementPaths) {
+        invalidElementPaths.sort((a, b) -> Integer.compare(b.size(), 
a.size()));
+        List<List<String>> result = new ArrayList<>();
+        Map<List<String>, String> pathToStringMap = new HashMap<>();
+
+        for (List<String> invalidPath : invalidElementPaths) {
+            String mergedInvalidPath = 
pathToStringMap.computeIfAbsent(invalidPath, DMNEvaluator::getMergedPaths);
+            boolean isSubset = false;
+            for (List<String> path : result) {
+                String mergedPath = pathToStringMap.computeIfAbsent(path, 
DMNEvaluator::getMergedPaths);
+                if (mergedPath.contains(mergedInvalidPath)) {
+                    isSubset = true;
+                    break;
+                }
+            }
+            if (!isSubset) {
+                result.add(invalidPath);
+            }
+        }
+        return result;
+    }
+
+    static String getMergedPaths(List<String> toMerge) {
+        return String.join("|", toMerge);
+    }
+
     private DMNEvaluator(DMNModel dmnModel, DMNRuntime dmnRuntime) {
         this.dmnModel = dmnModel;
         this.dmnRuntime = dmnRuntime;
@@ -121,13 +195,14 @@ public class DMNEvaluator {
         DMNContext dmnContext =
                 new DynamicDMNContextBuilder(dmnRuntime.newContext(), 
dmnModel).populateContextWith(context);
         DMNResult dmnResult = dmnRuntime.evaluateAll(dmnModel, dmnContext);
+        List<List<String>> invalidElementPaths = 
retrieveInvalidElementPaths(dmnResult.getMessages(), dmnModel);
         Optional<Map<String, Map<String, Integer>>> 
decisionEvaluationHitIdsMap = dmnRuntime.getListeners().stream()
                 .filter(JITDMNListener.class::isInstance)
                 .findFirst()
                 .map(JITDMNListener.class::cast)
                 .map(JITDMNListener::getDecisionEvaluationHitIdsMap);
         return JITDMNResult.of(getNamespace(), getName(), dmnResult,
-                decisionEvaluationHitIdsMap.orElse(Collections.emptyMap()));
+                decisionEvaluationHitIdsMap.orElse(Collections.emptyMap()), 
invalidElementPaths);
     }
 
 }
diff --git 
a/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/JITDMNServiceImpl.java
 
b/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/JITDMNServiceImpl.java
index 13f71b24d..ca1a4b631 100644
--- 
a/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/JITDMNServiceImpl.java
+++ 
b/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/JITDMNServiceImpl.java
@@ -119,14 +119,14 @@ public class JITDMNServiceImpl implements JITDMNService {
                 Thread.currentThread().interrupt();
             }
             return new DMNResultWithExplanation(
-                    JITDMNResult.of(dmnEvaluator.getNamespace(), 
dmnEvaluator.getName(), dmnResult, Collections.emptyMap()),
+                    JITDMNResult.of(dmnEvaluator.getNamespace(), 
dmnEvaluator.getName(), dmnResult, Collections.emptyMap(), 
dmnResult.getInvalidElementPaths()),
                     new SalienciesResponse(EXPLAINABILITY_FAILED, 
EXPLAINABILITY_FAILED_MESSAGE, null));
         }
 
         List<SaliencyResponse> saliencyModelResponse = 
buildSalienciesResponse(dmnEvaluator.getDmnModel(), saliencyMap);
 
         return new DMNResultWithExplanation(
-                JITDMNResult.of(dmnEvaluator.getNamespace(), 
dmnEvaluator.getName(), dmnResult, Collections.emptyMap()),
+                JITDMNResult.of(dmnEvaluator.getNamespace(), 
dmnEvaluator.getName(), dmnResult, Collections.emptyMap(), 
dmnResult.getInvalidElementPaths()),
                 new SalienciesResponse(EXPLAINABILITY_SUCCEEDED, null, 
saliencyModelResponse));
     }
 
diff --git 
a/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/responses/JITDMNResult.java
 
b/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/responses/JITDMNResult.java
index 2466c238a..3ca71c897 100644
--- 
a/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/responses/JITDMNResult.java
+++ 
b/jitexecutor/jitexecutor-dmn/src/main/java/org/kie/kogito/jitexecutor/dmn/responses/JITDMNResult.java
@@ -51,13 +51,17 @@ public class JITDMNResult implements Serializable,
 
     private List<DMNDecisionResult> decisionResults;
 
-    public static JITDMNResult of(String namespace, String modelName, 
org.kie.dmn.api.core.DMNResult dmnResult, Map<String, Map<String, Integer>> 
decisionEvaluationHitIdsMap) {
+    private List<List<String>> invalidElementPaths;
+
+    public static JITDMNResult of(String namespace, String modelName, 
org.kie.dmn.api.core.DMNResult dmnResult, Map<String, Map<String, Integer>> 
decisionEvaluationHitIdsMap,
+            List<List<String>> invalidElementPaths) {
         JITDMNResult toReturn = new JITDMNResult();
         toReturn.namespace = namespace;
         toReturn.modelName = modelName;
         toReturn.dmnContext = 
internalGetContext(dmnResult.getContext().getAll());
         toReturn.messages = internalGetMessages(dmnResult.getMessages());
         toReturn.decisionResults = 
internalGetDecisionResults(dmnResult.getDecisionResults(), 
decisionEvaluationHitIdsMap);
+        toReturn.invalidElementPaths = invalidElementPaths;
         return toReturn;
     }
 
@@ -93,6 +97,14 @@ public class JITDMNResult implements Serializable,
         this.messages = messages;
     }
 
+    public List<List<String>> getInvalidElementPaths() {
+        return invalidElementPaths;
+    }
+
+    public void setInvalidElementPaths(List<List<String>> invalidElementPaths) 
{
+        this.invalidElementPaths = invalidElementPaths;
+    }
+
     @JsonIgnore
     @Override
     public DMNContext getContext() {
@@ -163,6 +175,7 @@ public class JITDMNResult implements Serializable,
                 .append(", dmnContext=").append(dmnContext)
                 .append(", messages=").append(messages)
                 .append(", decisionResults=").append(decisionResults)
+                .append(", invalidPaths=").append(invalidElementPaths)
                 .append("]").toString();
     }
 
diff --git 
a/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/DMNEvaluatorTest.java
 
b/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/DMNEvaluatorTest.java
index 71a5edb1a..17f43dd30 100644
--- 
a/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/DMNEvaluatorTest.java
+++ 
b/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/DMNEvaluatorTest.java
@@ -19,15 +19,29 @@
 package org.kie.kogito.jitexecutor.dmn;
 
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.Collections;
+import java.util.List;
+import java.util.stream.Stream;
 
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.kie.api.io.Resource;
+import org.kie.dmn.api.core.DMNContext;
 import org.kie.dmn.api.core.DMNMessage;
 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.core.api.DMNFactory;
 import org.kie.dmn.core.impl.DMNRuntimeImpl;
+import org.kie.dmn.core.internal.utils.DMNRuntimeBuilder;
+import org.kie.dmn.model.api.DMNModelInstrumentedBase;
+import org.kie.internal.io.ResourceFactory;
 
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.kie.kogito.jitexecutor.dmn.TestingUtils.getModelFromIoUtils;
@@ -88,4 +102,117 @@ public class DMNEvaluatorTest {
         assertNotNull(evaluator);
     }
 
+    @Test
+    void testRetrieveInvalidElementPaths() throws IOException {
+        Resource resource = 
ResourceFactory.newClassPathResource("invalid_models/DMNv1_5/DMN-MultipleInvalidElements.dmn");
+        DMNRuntime dmnRuntime = 
DMNRuntimeBuilder.fromDefaults().buildConfiguration()
+                
.fromResources(Collections.singletonList(resource)).getOrElseThrow(RuntimeException::new);
+        assertThat(dmnRuntime).isNotNull();
+        String nameSpace = 
"https://kie.org/dmn/_79591DB5-1EE1-4CBD-AA5D-2E3EDF31150E";;
+
+        final DMNModel dmnModel = dmnRuntime.getModel(nameSpace, 
"DMN_8F7C4323-412A-4E0B-9AEF-0F24C8F55282");
+        assertThat(dmnModel).isNotNull();
+        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", 8);
+        DMNResult dmnResult = dmnRuntime.evaluateAll(dmnModel, dmnContext);
+        List<List<String>> invalidElementPaths = List.of(
+                List.of("_3DC41DB9-BE1D-4289-A639-24AB57ED082D", 
"_2B147ECC-2457-4623-B841-3360D75F9F76", 
"_6F318F57-DA06-4F71-80AD-288E0BBB3A52", 
"_43236F2B-9857-454F-8EA0-39B37C7519CF"),
+                List.of("_09186183-0646-4CD0-AD67-A159E9F87F5E", 
"_D386D137-582B-49F9-B6F9-F341C3AC4B3E", 
"_2E43C09D-011A-436C-B40B-9154405EAF3A"),
+                List.of("_A40F3AA4-2832-4D98-83F0-7D604F9A090F", 
"_4AC1BD7D-5A8D-4A88-94F9-0B80BDF0D9B1"), 
List.of("_E9468D45-51EB-48DA-8B30-7D65696FDFB8"));
+
+        List<List<String>> retrieved = 
DMNEvaluator.retrieveInvalidElementPaths(dmnResult.getMessages(), dmnModel);
+        assertNotNull(retrieved);
+        assertThat(invalidElementPaths.size()).isEqualTo(retrieved.size());
+        assertThat(invalidElementPaths).isEqualTo(retrieved);
+    }
+
+    @Test
+    void testGetPathToRoot() {
+        Resource resource = 
ResourceFactory.newClassPathResource("invalid_models/DMNv1_5/InvalidElementPath.dmn");
+        DMNRuntime dmnRuntime = 
DMNRuntimeBuilder.fromDefaults().buildConfiguration()
+                
.fromResources(Collections.singletonList(resource)).getOrElseThrow(RuntimeException::new);
+        assertThat(dmnRuntime).isNotNull();
+        String nameSpace = 
"https://kie.org/dmn/_608570C5-8344-42B6-9538-6E0EA9892C38";;
+
+        final DMNModel dmnModel = dmnRuntime.getModel(nameSpace, 
"DMN_039CBA90-29EC-4A15-B376-FC0FBC5F6807");
+        assertThat(dmnModel).isNotNull();
+        String id = "_8577FE15-1512-4BBE-885F-C30FD73ADC6B";
+        List<String> invalidPath = 
List.of("_172F9901-0884-47C1-A5B4-3C09CC83D5B6", 
"_8577FE15-1512-4BBE-885F-C30FD73ADC6B");
+
+        List<String> retrieved = DMNEvaluator.getPathToRoot(dmnModel, id);
+
+        assertNotNull(retrieved);
+        assertThat(invalidPath).isEqualTo(retrieved);
+    }
+
+    @Test
+    void testGetNode() {
+        DMNModelInstrumentedBase dmnModelInstrumentedBaseNode = 
mock(DMNModelInstrumentedBase.class);
+        Resource resource = 
ResourceFactory.newClassPathResource("invalid_models/DMNv1_5/DMN-MultipleInvalidElements.dmn");
+        DMNRuntime dmnRuntime = 
DMNRuntimeBuilder.fromDefaults().buildConfiguration()
+                
.fromResources(Collections.singletonList(resource)).getOrElseThrow(RuntimeException::new);
+        assertThat(dmnRuntime).isNotNull();
+        String nameSpace = 
"https://kie.org/dmn/_79591DB5-1EE1-4CBD-AA5D-2E3EDF31150E";;
+
+        final DMNModel dmnModel = dmnRuntime.getModel(nameSpace, 
"DMN_8F7C4323-412A-4E0B-9AEF-0F24C8F55282");
+        assertThat(dmnModel).isNotNull();
+        String id = "_43236F2B-9857-454F-8EA0-39B37C7519CF";
+        
when(dmnModelInstrumentedBaseNode.getIdentifierString()).thenReturn(id);
+
+        DMNModelInstrumentedBase node = DMNEvaluator.getNodeById(dmnModel, id);
+
+        assertNotNull(node);
+        
assertThat(dmnModelInstrumentedBaseNode.getIdentifierString()).isEqualTo(node.getIdentifierString());
+    }
+
+    @Test
+    void testGetNodeById() {
+        DMNModelInstrumentedBase dmnModelInstrumentedBaseNode = 
mock(DMNModelInstrumentedBase.class);
+        Resource resource = 
ResourceFactory.newClassPathResource("invalid_models/DMNv1_5/InvalidElementPath.dmn");
+        DMNRuntime dmnRuntime = 
DMNRuntimeBuilder.fromDefaults().buildConfiguration()
+                
.fromResources(Collections.singletonList(resource)).getOrElseThrow(RuntimeException::new);
+        assertThat(dmnRuntime).isNotNull();
+        String nameSpace = 
"https://kie.org/dmn/_608570C5-8344-42B6-9538-6E0EA9892C38";;
+
+        final DMNModel dmnModel = dmnRuntime.getModel(nameSpace, 
"DMN_039CBA90-29EC-4A15-B376-FC0FBC5F6807");
+        assertThat(dmnModel).isNotNull();
+        String id = "_8577FE15-1512-4BBE-885F-C30FD73ADC6B";
+        
when(dmnModelInstrumentedBaseNode.getIdentifierString()).thenReturn(id);
+
+        DMNModelInstrumentedBase node = 
DMNEvaluator.getNodeById(dmnModelInstrumentedBaseNode, id);
+
+        assertNotNull(node);
+        
assertThat(dmnModelInstrumentedBaseNode.getIdentifierString()).isEqualTo(node.getIdentifierString());
+    }
+
+    @ParameterizedTest
+    @MethodSource("provideParametersForRemoveDuplicates")
+    void testRemoveDuplicates(List<List<String>> input, List<List<String>> 
expected) {
+        List<List<String>> retrieved = DMNEvaluator.removeDuplicates(input);
+        assertThat(expected.size()).isEqualTo(retrieved.size());
+        assertThat(expected).isEqualTo(retrieved);
+    }
+
+    private static Stream<Arguments> provideParametersForRemoveDuplicates() {
+        return Stream.of(Arguments.of(Arrays.asList(List.of("A", "B", "D"), 
List.of("A", "B", "B", "D"), List.of("A", "B", "C", "D"), List.of("C", "B", 
"A"),
+                List.of("A", "B", "C"), List.of("F", "G", "H", "I"), 
List.of("F", "H"), List.of("I", "H"), List.of("FG", "H", "I"), List.of("F", 
"GH")),
+                Arrays.asList(List.of("A", "B", "B", "D"), List.of("A", "B", 
"C", "D"), List.of("F", "G", "H", "I"), List.of("A", "B", "D"), List.of("C", 
"B", "A"),
+                        List.of("FG", "H", "I"), List.of("F", "H"), 
List.of("I", "H"), List.of("F", "GH"))),
+                // subset
+                Arguments.of(Arrays.asList(List.of("A", "B", "C", "D"), 
List.of("A", "B"), List.of("B", "C"), List.of("C", "D")),
+                        List.of(List.of("A", "B", "C", "D"))),
+                // all duplicates
+                Arguments.of(Arrays.asList(List.of("A", "B", "C"), 
List.of("A", "B", "C"), List.of("A", "B", "C")),
+                        List.of(List.of("A", "B", "C"))),
+                // no duplicates
+                Arguments.of(Arrays.asList(List.of("A", "B", "C"), 
List.of("X", "Y", "Z")),
+                        Arrays.asList(List.of("A", "B", "C"), List.of("X", 
"Y", "Z"))),
+                // one complete duplicate
+                Arguments.of(Arrays.asList(List.of("A", "B", "C"), 
List.of("A", "B", "C"), List.of("X", "Y", "Z")),
+                        Arrays.asList(List.of("A", "B", "C"), List.of("X", 
"Y", "Z"))));
+    }
+
 }
diff --git 
a/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/api/JITDMNResourceTest.java
 
b/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/api/JITDMNResourceTest.java
index 9a2df4933..92d1c2a95 100644
--- 
a/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/api/JITDMNResourceTest.java
+++ 
b/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/api/JITDMNResourceTest.java
@@ -47,11 +47,14 @@ import io.restassured.response.ResponseBody;
 
 import static io.restassured.RestAssured.given;
 import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.Matchers.hasItems;
 import static org.kie.kogito.jitexecutor.dmn.TestingUtils.getModelFromIoUtils;
 
 @QuarkusTest
 public class JITDMNResourceTest {
 
+    static final String EVALUATION_HIT_IDS_FIELD_NAME = "evaluationHitIds";
+    private static final ObjectMapper MAPPER = new ObjectMapper();
     private static String invalidModel1x;
     private static String invalidModel15;
     private static String validModel15;
@@ -59,10 +62,6 @@ public class JITDMNResourceTest {
     private static String modelWithMultipleEvaluationHitIds;
     private static String modelWithNestedConditionalEvaluationHitIds;
 
-    private static final ObjectMapper MAPPER = new ObjectMapper();
-
-    static final String EVALUATION_HIT_IDS_FIELD_NAME = "evaluationHitIds";
-
     static {
         MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, 
false);
     }
@@ -288,6 +287,22 @@ public class JITDMNResourceTest {
                 .body(containsString("Error compiling FEEL expression 'Person 
Age >= 18' for name 'Can Drive?' on node 'Can Drive?': syntax error near 
'Age'"));
     }
 
+    @Test
+    void testjitdmnRetrieveInvalidElementPath() throws IOException {
+        Map<String, Object> context = new HashMap<>();
+        context.put("id", "_641F6FB1-6720-425E-9045-7EB9B90E2FFF");
+        context.put("New Input Data", 8888);
+        JITDMNPayload jitdmnpayload = new 
JITDMNPayload(getModelFromIoUtils("invalid_models/DMNv1_5/InvalidElementPath.dmn"),
 context);
+        given()
+                .contentType(ContentType.JSON)
+                .body(jitdmnpayload)
+                .when().post("/jitdmn/dmnresult")
+                .then()
+                .statusCode(200)
+                .body("invalidElementPaths", 
hasItems(List.of("_172F9901-0884-47C1-A5B4-3C09CC83D5B6", 
"_8577FE15-1512-4BBE-885F-C30FD73ADC6B"),
+                        List.of("_4FF85EFF-B9E6-41C3-9115-DC9690E3B6F7")));
+    }
+
     static Map<String, Object> buildMultipleHitContext() {
         final List<BigDecimal> numbers = new ArrayList<>();
         numbers.add(BigDecimal.valueOf(10));
diff --git 
a/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/responses/JITDMNResultTest.java
 
b/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/responses/JITDMNResultTest.java
index aeb8d5365..30c6fa88b 100644
--- 
a/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/responses/JITDMNResultTest.java
+++ 
b/jitexecutor/jitexecutor-dmn/src/test/java/org/kie/kogito/jitexecutor/dmn/responses/JITDMNResultTest.java
@@ -20,8 +20,10 @@ package org.kie.kogito.jitexecutor.dmn.responses;
 
 import java.io.IOException;
 import java.io.StringReader;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.junit.jupiter.api.BeforeAll;
@@ -77,8 +79,16 @@ class JITDMNResultTest {
         DMNResultImpl dmnResult = new DMNResultImpl(DMN_MODEL);
         dmnResult.setContext(createContext());
         dmnResult.addDecisionResult(decisionResult);
+        Map<String, Map<String, Integer>> decisionEvaluationHitIdsMap = new 
HashMap<>();
+        Map<String, Integer> evaluationHitIds = 
Map.of("_1FA12B9F-288C-42E8-B77F-BE2D3702B7B6", 1);
+        
decisionEvaluationHitIdsMap.put("_3c8cee68-99dd-418c-847d-0b54697354f2", 
evaluationHitIds);
 
-        JITDMNResult jitdmnResult = 
JITDMNResult.of("http://www.trisotech.com/definitions/_9d01a0c4-f529-4ad8-ad8e-ec5fb5d96ad4";,
 "Chapter 11 Example", dmnResult, Collections.emptyMap());
+        List<List<String>> invalidElementPaths = new ArrayList<>();
+        List<String> invalidPath = 
List.of("_4bd33d4a-741b-444a-968b-64e1841211e7");
+        invalidElementPaths.add(invalidPath);
+
+        JITDMNResult jitdmnResult =
+                
JITDMNResult.of("http://www.trisotech.com/definitions/_9d01a0c4-f529-4ad8-ad8e-ec5fb5d96ad4";,
 "Chapter 11 Example", dmnResult, decisionEvaluationHitIdsMap, 
invalidElementPaths);
         String retrieved = MAPPER.writeValueAsString(jitdmnResult);
         assertThat(retrieved).isNotNull().isNotBlank();
         JITDMNResult result = MAPPER.readValue(retrieved, JITDMNResult.class);
@@ -297,6 +307,9 @@ class JITDMNResultTest {
                 "      \"evaluationStatus\": \"SKIPPED\"\n" +
                 "    },\n" +
                 "    {\n" +
+                "      \"invalidElementPaths\" : 
[[\"_5b8356f3-2cf2-40e8-8f80-324937e8b276\"]]\n" +
+                "    },\n" +
+                "    {\n" +
                 "      \"decisionId\": 
\"_b5e759df-f662-44cd-94f5-55c3c81f0ee3\",\n" +
                 "      \"decisionName\": \"Eligibility\",\n" +
                 "      \"result\": null,\n" +
@@ -330,6 +343,9 @@ class JITDMNResultTest {
                 "      \"evaluationStatus\": \"SKIPPED\"\n" +
                 "    },\n" +
                 "    {\n" +
+                "      \"invalidElementPaths\" : 
[[\"_b5e759df-f662-44cd-94f5-55c3c81f0ee3\"]]\n" +
+                "    },\n" +
+                "    {\n" +
                 "      \"decisionId\": 
\"_4bd33d4a-741b-444a-968b-64e1841211e7\",\n" +
                 "      \"decisionName\": \"Adjudication\",\n" +
                 "      \"result\": null,\n" +
@@ -363,6 +379,9 @@ class JITDMNResultTest {
                 "      \"evaluationStatus\": \"SKIPPED\"\n" +
                 "    },\n" +
                 "    {\n" +
+                "      \"invalidElementPaths\" : 
[[\"_4bd33d4a-741b-444a-968b-64e1841211e7\"]]\n" +
+                "    },\n" +
+                "    {\n" +
                 "      \"decisionId\": 
\"_e905f02c-c5d9-4f2a-ba57-7912ff523b46\",\n" +
                 "      \"decisionName\": \"Application risk score\",\n" +
                 "      \"result\": null,\n" +
@@ -380,6 +399,9 @@ class JITDMNResultTest {
                 "      \"evaluationStatus\": \"SKIPPED\"\n" +
                 "    },\n" +
                 "    {\n" +
+                "      \"invalidElementPaths\" : 
[[\"_e905f02c-c5d9-4f2a-ba57-7912ff523b46\"]]\n" +
+                "    },\n" +
+                "    {\n" +
                 "      \"decisionId\": 
\"_ed60265c-25e2-400f-a99f-fafd3b489838\",\n" +
                 "      \"decisionName\": \"Pre-bureau affordability\",\n" +
                 "      \"result\": null,\n" +
@@ -405,6 +427,9 @@ class JITDMNResultTest {
                 "      \"evaluationStatus\": \"SKIPPED\"\n" +
                 "    },\n" +
                 "    {\n" +
+                "      \"invalidElementPaths\" : 
[[\"_ed60265c-25e2-400f-a99f-fafd3b489838\"]]\n" +
+                "    },\n" +
+                "    {\n" +
                 "      \"decisionId\": 
\"_40b45659-9299-43a6-af30-04c948c5c0ec\",\n" +
                 "      \"decisionName\": \"Post-bureau risk category\",\n" +
                 "      \"result\": null,\n" +
@@ -430,6 +455,9 @@ class JITDMNResultTest {
                 "      \"evaluationStatus\": \"SKIPPED\"\n" +
                 "    },\n" +
                 "    {\n" +
+                "      \"invalidElementPaths\" : 
[[\"_40b45659-9299-43a6-af30-04c948c5c0ec\"]]\n" +
+                "    },\n" +
+                "    {\n" +
                 "      \"decisionId\": 
\"_728e3a50-f00f-42c0-b3ee-1ee5aabd5474\",\n" +
                 "      \"decisionName\": \"Post-bureau affordability\",\n" +
                 "      \"result\": null,\n" +
@@ -455,6 +483,9 @@ class JITDMNResultTest {
                 "      \"evaluationStatus\": \"SKIPPED\"\n" +
                 "    },\n" +
                 "    {\n" +
+                "      \"invalidElementPaths\" : 
[[\"_728e3a50-f00f-42c0-b3ee-1ee5aabd5474\"]]\n" +
+                "    },\n" +
+                "    {\n" +
                 "      \"decisionId\": 
\"_3c8cee68-99dd-418c-847d-0b54697354f2\",\n" +
                 "      \"decisionName\": \"Required monthly installment\",\n" +
                 "      \"result\": 333.3636546143084985132842970339110,\n" +
@@ -463,6 +494,9 @@ class JITDMNResultTest {
                 "      \"evaluationStatus\": \"SUCCEEDED\"\n" +
                 "    },\n" +
                 "    {\n" +
+                "      \"invalidElementPaths\" : []\n" +
+                "    },\n" +
+                "    {\n" +
                 "      \"decisionId\": 
\"_ca1e6032-12eb-428a-a80b-49028a88c0b5\",\n" +
                 "      \"decisionName\": \"Routing\",\n" +
                 "      \"result\": null,\n" +
@@ -488,6 +522,9 @@ class JITDMNResultTest {
                 "      \"evaluationStatus\": \"SKIPPED\"\n" +
                 "    },\n" +
                 "    {\n" +
+                "      \"invalidElementPaths\" : 
[[\"_ca1e6032-12eb-428a-a80b-49028a88c0b5\"]]\n" +
+                "    },\n" +
+                "    {\n" +
                 "      \"decisionId\": 
\"_9997fcfd-0f50-4933-939e-88a235b5e2a0\",\n" +
                 "      \"decisionName\": \"Pre-bureau risk category\",\n" +
                 "      \"result\": null,\n" +
@@ -513,6 +550,9 @@ class JITDMNResultTest {
                 "      \"evaluationStatus\": \"SKIPPED\"\n" +
                 "    },\n" +
                 "    {\n" +
+                "      \"invalidElementPaths\" : 
[[\"_9997fcfd-0f50-4933-939e-88a235b5e2a0\"]]\n" +
+                "    },\n" +
+                "    {\n" +
                 "      \"decisionId\": 
\"_8b838f06-968a-4c66-875e-f5412fd692cf\",\n" +
                 "      \"decisionName\": \"Strategy\",\n" +
                 "      \"result\": null,\n" +
@@ -536,7 +576,10 @@ class JITDMNResultTest {
                 "      ],\n" +
                 "      \"evaluationHitIds\": {},\n" +
                 "      \"evaluationStatus\": \"SKIPPED\"\n" +
-                "    }\n" +
+                "    },\n" +
+                "    {\n" +
+                "      \"invalidElementPaths\" : 
[[\"_8b838f06-968a-4c66-875e-f5412fd692cf\"]]\n" +
+                "    } \n" +
                 "  ]\n" +
                 "}";
         JITDMNResult result = MAPPER.readValue(json, JITDMNResult.class);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to