Fix response messages returned by Get delta between anchor and JSON payload API 15/142815/11
authorSourabh Verma <sv001010507@techmahindra.com>
Thu, 1 Jan 2026 08:58:46 +0000 (14:28 +0530)
committerSourabh Verma <sv001010507@techmahindra.com>
Wed, 21 Jan 2026 11:23:53 +0000 (16:53 +0530)
-Updated response message for syntactically invalid JSON input.
-Added proper response codes and exception messages for:
    -Non-existing xpath
    -Invalid xpath
    -Invalid JSON payload/file format
    -Malformed yang/zip file

Issue-ID: CPS-3104
Change-Id: Ic76004fdcf2a3e91afc415f8da7641016ba17258
Signed-off-by: Sourabh Verma <sv001010507@techmahindra.com>
cps-rest/src/test/groovy/org/onap/cps/rest/controller/DeltaRestControllerSpec.groovy
cps-service/src/main/java/org/onap/cps/impl/CpsDeltaServiceImpl.java
cps-service/src/main/java/org/onap/cps/impl/DataNodeFactoryImpl.java
cps-service/src/main/java/org/onap/cps/utils/JsonObjectMapper.java

index a1eb32c..e0938b8 100644 (file)
@@ -177,7 +177,7 @@ class DeltaRestControllerSpec extends Specification {
         then: 'expected response code is returned'
             assert response.status == HttpStatus.BAD_REQUEST.value()
         then: 'the response contains expected error message'
-            assert response.contentAsString.contains("Parsing error occurred while converting JSON content to Json Node")
+            assert response.contentAsString.contains("JSON parsing error at line: 1, column: 2")
     }
 
     def 'Apply changes from a delta report, in JSON format, on an anchor'() {
index 51e48e2..e38bfb3 100644 (file)
@@ -75,11 +75,11 @@ public class CpsDeltaServiceImpl implements CpsDeltaService {
                                                            final FetchDescendantsOption fetchDescendantsOption,
                                                            final boolean groupDataNodes) {
 
-        final String xpathForDeltaReport = validateXpath(xpath);
+        final String normalizedXpath = getNormalizedXpath(xpath);
         final Collection<DataNode> sourceDataNodes = cpsDataService.getDataNodesForMultipleXpaths(dataspaceName,
-            sourceAnchorName, Collections.singletonList(xpathForDeltaReport), fetchDescendantsOption);
+            sourceAnchorName, Collections.singletonList(normalizedXpath), fetchDescendantsOption);
         final Collection<DataNode> targetDataNodes = cpsDataService.getDataNodesForMultipleXpaths(dataspaceName,
-            targetAnchorName, Collections.singletonList(xpathForDeltaReport), fetchDescendantsOption);
+            targetAnchorName, Collections.singletonList(normalizedXpath), fetchDescendantsOption);
         return getDeltaReports(sourceDataNodes, targetDataNodes, groupDataNodes);
     }
 
@@ -94,13 +94,14 @@ public class CpsDeltaServiceImpl implements CpsDeltaService {
                                                                  final FetchDescendantsOption fetchDescendantsOption,
                                                                  final boolean groupDataNodes) {
 
+        final String normalizedXpath = getNormalizedXpath(xpath);
         final Anchor sourceAnchor = cpsAnchorService.getAnchor(dataspaceName, sourceAnchorName);
         final Collection<DataNode> sourceDataNodes = cpsDataService.getDataNodesForMultipleXpaths(dataspaceName,
-            sourceAnchorName, Collections.singletonList(xpath), fetchDescendantsOption);
+            sourceAnchorName, Collections.singletonList(normalizedXpath), fetchDescendantsOption);
         final Collection<DataNode> sourceDataNodesRebuilt =
-            rebuildSourceDataNodes(xpath, sourceAnchor, sourceDataNodes);
+            rebuildSourceDataNodes(normalizedXpath, sourceAnchor, sourceDataNodes);
         final Collection<DataNode> targetDataNodes = new ArrayList<>(
-            buildTargetDataNodes(sourceAnchor, xpath, yangResourceContentPerName, targetData));
+            buildTargetDataNodes(sourceAnchor, normalizedXpath, yangResourceContentPerName, targetData));
         return getDeltaReports(sourceDataNodesRebuilt, targetDataNodes, groupDataNodes);
     }
 
@@ -158,7 +159,7 @@ public class CpsDeltaServiceImpl implements CpsDeltaService {
         }
     }
 
-    private String validateXpath(final String xpath) {
+    private String getNormalizedXpath(final String xpath) {
         try {
             return ROOT_NODE_XPATH.equals(xpath) ? ROOT_NODE_XPATH : CpsPathUtil.getNormalizedXpath(xpath);
         } catch (final PathParsingException pathParsingException) {
index 76db887..199ccd7 100644 (file)
@@ -61,7 +61,7 @@ public class DataNodeFactoryImpl implements DataNodeFactory {
         final String xpathToBuildNodes = isRootNodeXpath(xpath) ? NO_PARENT_PATH :
             CpsPathUtil.getNormalizedParentXpath(xpath);
         final ContainerNode containerNode = yangParser.parseData(contentType, nodeData, anchor, xpathToBuildNodes);
-        return convertToDataNodes(xpathToBuildNodes, containerNode);
+        return convertToDataNodes(xpathToBuildNodes, containerNode, xpath);
     }
 
     @Override
@@ -73,7 +73,7 @@ public class DataNodeFactoryImpl implements DataNodeFactory {
         final String normalizedParentNodeXpath = CpsPathUtil.getNormalizedXpath(parentNodeXpath);
         final ContainerNode containerNode =
             yangParser.parseData(contentType, nodeData, anchor, normalizedParentNodeXpath);
-        return convertToDataNodes(normalizedParentNodeXpath, containerNode);
+        return convertToDataNodes(normalizedParentNodeXpath, containerNode, parentNodeXpath);
     }
 
     @Override
@@ -84,19 +84,20 @@ public class DataNodeFactoryImpl implements DataNodeFactory {
         final String normalizedParentNodeXpath = isRootNodeXpath(xpath) ? NO_PARENT_PATH :
             CpsPathUtil.getNormalizedParentXpath(xpath);
         final ContainerNode containerNode =
-            yangParser.parseData(contentType, nodeData, yangResourceContentPerName, normalizedParentNodeXpath);
-        return convertToDataNodes(normalizedParentNodeXpath, containerNode);
+                yangParser.parseData(contentType, nodeData, yangResourceContentPerName, normalizedParentNodeXpath);
+        return convertToDataNodes(normalizedParentNodeXpath, containerNode, xpath);
     }
 
     private static Collection<DataNode> convertToDataNodes(final String normalizedParentNodeXpath,
-                                                           final ContainerNode containerNode) {
+                                                           final ContainerNode containerNode,
+                                                           final String xpath) {
         final Collection<DataNode> dataNodes = new DataNodeBuilder()
             .withParentNodeXpath(normalizedParentNodeXpath)
             .withContainerNode(containerNode)
             .buildCollection();
         if (dataNodes.isEmpty()) {
             throw new DataValidationException("No Data Nodes", "The request did not return any data nodes for xpath "
-                + normalizedParentNodeXpath);
+                + xpath);
         }
         return dataNodes;
     }
index eec99c5..e9ba0c3 100644 (file)
@@ -119,8 +119,8 @@ public class JsonObjectMapper {
             return objectMapper.readTree(jsonContent);
         } catch (final JsonProcessingException e) {
             log.error("Parsing error occurred while converting JSON content to Json Node.");
-            throw new DataValidationException("Parsing error occurred while converting "
-                    + "JSON content to Json Node.", e.getMessage());
+            throw new DataValidationException(String.format("JSON parsing error at line: %d, column: %d",
+                e.getLocation().getLineNr(), e.getLocation().getColumnNr()), e.getOriginalMessage());
         }
     }