Fix response code returned by Get delta between 2 anchors API 68/142368/9
authorArpit Singh <AS00745003@techmahindra.com>
Fri, 14 Nov 2025 12:24:29 +0000 (17:54 +0530)
committerArpit Singh <AS00745003@techmahindra.com>
Thu, 4 Dec 2025 04:42:36 +0000 (10:12 +0530)
- Get delta between 2 anchors returned a 200 OK response in case an
  invalid xpath is provided with the request.
- The patch fixes that and now the API returns 400 BAD RERQUEST when an
  invalid xpath is used

Issue-ID: CPS-3041
Change-Id: Ic73003fdcf8e2f67cdf715f8da7641016ba61258
Signed-off-by: Arpit Singh <AS00745003@techmahindra.com>
cps-service/src/main/java/org/onap/cps/impl/CpsDeltaServiceImpl.java
cps-service/src/test/groovy/org/onap/cps/impl/CpsDeltaServiceImplSpec.groovy

index e9f5137..51e48e2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ============LICENSE_START=======================================================
- *  Copyright (C) 2023-2025 TechMahindra Ltd.
+ *  Copyright (C) 2023-2025 Deutsche Telekom AG
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
 
 package org.onap.cps.impl;
 
+import static org.onap.cps.cpspath.parser.CpsPathUtil.ROOT_NODE_XPATH;
 import static org.onap.cps.utils.ContentType.JSON;
 
 import io.micrometer.core.annotation.Timed;
@@ -34,10 +35,13 @@ import org.onap.cps.api.CpsAnchorService;
 import org.onap.cps.api.CpsDataService;
 import org.onap.cps.api.CpsDeltaService;
 import org.onap.cps.api.DataNodeFactory;
+import org.onap.cps.api.exceptions.DataValidationException;
 import org.onap.cps.api.model.Anchor;
 import org.onap.cps.api.model.DataNode;
 import org.onap.cps.api.model.DeltaReport;
 import org.onap.cps.api.parameters.FetchDescendantsOption;
+import org.onap.cps.cpspath.parser.CpsPathUtil;
+import org.onap.cps.cpspath.parser.PathParsingException;
 import org.onap.cps.utils.CpsValidator;
 import org.onap.cps.utils.DataMapper;
 import org.onap.cps.utils.JsonObjectMapper;
@@ -71,10 +75,11 @@ public class CpsDeltaServiceImpl implements CpsDeltaService {
                                                            final FetchDescendantsOption fetchDescendantsOption,
                                                            final boolean groupDataNodes) {
 
+        final String xpathForDeltaReport = validateXpath(xpath);
         final Collection<DataNode> sourceDataNodes = cpsDataService.getDataNodesForMultipleXpaths(dataspaceName,
-            sourceAnchorName, Collections.singletonList(xpath), fetchDescendantsOption);
+            sourceAnchorName, Collections.singletonList(xpathForDeltaReport), fetchDescendantsOption);
         final Collection<DataNode> targetDataNodes = cpsDataService.getDataNodesForMultipleXpaths(dataspaceName,
-            targetAnchorName, Collections.singletonList(xpath), fetchDescendantsOption);
+            targetAnchorName, Collections.singletonList(xpathForDeltaReport), fetchDescendantsOption);
         return getDeltaReports(sourceDataNodes, targetDataNodes, groupDataNodes);
     }
 
@@ -153,4 +158,13 @@ public class CpsDeltaServiceImpl implements CpsDeltaService {
         }
     }
 
+    private String validateXpath(final String xpath) {
+        try {
+            return ROOT_NODE_XPATH.equals(xpath) ? ROOT_NODE_XPATH : CpsPathUtil.getNormalizedXpath(xpath);
+        } catch (final PathParsingException pathParsingException) {
+            throw new DataValidationException("Invalid xpath: " + xpath, pathParsingException.getMessage(),
+                pathParsingException);
+        }
+    }
+
 }
index e6cac2a..076c4de 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ============LICENSE_START=======================================================
- *  Copyright (C) 2023-2025 TechMahindra Ltd.
+ *  Copyright (C) 2023-2025 Deutsche Telekom AG
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -142,6 +142,16 @@ class CpsDeltaServiceImplSpec extends Specification {
             'updated with grouping enabled'  | sourceDataNode           | targetDataNode          | GROUPING_ENABLED  || 'replace'      | ['parent':['parent-leaf': 'parent-leaf-as-source-data']]                                                      | ['parent':['parent-leaf': 'parent-leaf-as-target-data']]
     }
 
+    def 'Get delta between 2 anchors with invalid xpath'() {
+        given: 'an invalid xpath'
+            def invalidXpath = '/test[invalid'
+        when: 'attempt to get delta between 2 anchors with invalid xpath'
+            objectUnderTest.getDeltaByDataspaceAndAnchors(dataspaceName, ANCHOR_NAME_1, ANCHOR_NAME_2, invalidXpath, INCLUDE_ALL_DESCENDANTS, GROUPING_DISABLED)
+        then: 'DataValidationException is thrown'
+            def exception = thrown(DataValidationException)
+            assert exception.message == 'Invalid xpath: /test[invalid'
+    }
+
     def 'Delta Report between parent nodes with children where data node is #scenario without grouping of data nodes'() {
         given: 'root node xpath and expected source and target data'
             def xpath = '/'