CPS-1526 Fix response message for PATCH operation

- Fixed the Response code and message when trying to update multiple
  data trees at once
- Response code changed to 400
- Since the patch operation across multiple data trees is not
  supported when xpath is set to root node xpath, appropriate message is
  returned in response
- Existing functionality of updating one data node with root node xpath
  remains as it is.
- Updated API documentation and release notes

Issue-ID: CPS-1526
Signed-off-by: arpitsingh <as00745003@techmahindra.com>
Change-Id: I5d25a06bb5d407316ccfb2f85877cbe56a9f6f31
diff --git a/cps-rest/docs/openapi/cpsData.yml b/cps-rest/docs/openapi/cpsData.yml
index 1d60e1f..0a032e4 100644
--- a/cps-rest/docs/openapi/cpsData.yml
+++ b/cps-rest/docs/openapi/cpsData.yml
@@ -131,7 +131,8 @@
       '500':
         $ref: 'components.yml#/components/responses/InternalServerError'
   patch:
-    description: Update a data node leaves for a given dataspace and anchor and a parent node xpath
+    description: Update a data node leaves for a given dataspace and anchor and a parent node xpath. This operation
+                  is currently supported for one top level data node only.
     tags:
       - cps-data
     summary: Update node leaves
diff --git a/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java b/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java
index 39fa45a..fc00868 100644
--- a/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java
+++ b/cps-service/src/main/java/org/onap/cps/api/CpsDataService.java
@@ -138,7 +138,9 @@
                                                        FetchDescendantsOption fetchDescendantsOption);
 
     /**
-     * Updates data node for given dataspace and anchor using xpath to parent node.
+     * Updates data node for given dataspace and anchor using xpath to parent node. This method can currently
+     * update only one top level data node. The method will throw DataValidationException when more than one top level
+     * data nodes are provided in jsonData
      *
      * @param dataspaceName   dataspace name
      * @param anchorName      anchor name
diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java
index cd14795..51e31f0 100755
--- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java
+++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsDataServiceImpl.java
@@ -160,9 +160,15 @@
         final String jsonData, final OffsetDateTime observedTimestamp) {
         cpsValidator.validateNameCharacters(dataspaceName, anchorName);
         final Anchor anchor = cpsAdminService.getAnchor(dataspaceName, anchorName);
-        final DataNode dataNode = buildDataNode(anchor, parentNodeXpath, jsonData, ContentType.JSON);
-        cpsDataPersistenceService.updateDataLeaves(dataspaceName, anchorName, dataNode.getXpath(),
-            dataNode.getLeaves());
+        final Collection<DataNode> dataNodesInPatch = buildDataNodes(anchor, parentNodeXpath, jsonData,
+                ContentType.JSON);
+        if (dataNodesInPatch.size() > 1) {
+            throw new DataValidationException("Operation is not supported for multiple data nodes",
+                    "Number of data nodes present: " + dataNodesInPatch.size());
+        }
+        cpsDataPersistenceService.updateDataLeaves(dataspaceName, anchorName,
+                dataNodesInPatch.iterator().next().getXpath(),
+            dataNodesInPatch.iterator().next().getLeaves());
         processDataUpdatedEventAsync(anchor, parentNodeXpath, UPDATE, observedTimestamp);
     }
 
diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
index faa5d2e..be397b9 100644
--- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
+++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsDataServiceImplSpec.groovy
@@ -240,6 +240,17 @@
             'one leaf'        | '{"name": "some-name"}'
     }
 
+    def 'Update multiple data nodes' () {
+        given: 'schema set for given dataspace and anchor refers multipleDataTree model'
+            setupSchemaSetMocks('multipleDataTree.yang')
+        and: 'json string with multiple data trees'
+            def updatedJsonData = '{"first-container":{"a-leaf":"a-new-Value"},"last-container":{"x-leaf":"x-new-value"}}'
+        when: 'update operation is performed on multiple data nodes'
+            objectUnderTest.updateNodeLeaves(dataspaceName, anchorName, '/', updatedJsonData, observedTimestamp)
+        then: 'expected exception is thrown'
+            thrown(DataValidationException)
+    }
+
     def 'Update Bookstore node leaves' () {
         given: 'a DMI registry model'
             setupSchemaSetMocks('bookstore.yang')
diff --git a/docs/api/swagger/cps/openapi.yaml b/docs/api/swagger/cps/openapi.yaml
index edbf878..57b9962 100644
--- a/docs/api/swagger/cps/openapi.yaml
+++ b/docs/api/swagger/cps/openapi.yaml
@@ -1720,8 +1720,8 @@
       tags:
         - cps-data
       summary: Update node leaves
-      description: Update a data node leaves for a given dataspace and anchor and
-        a parent node xpath
+      description: Update a data node leaves for a given dataspace and anchor and a parent node xpath. This
+        operation is currently supported for one top level data node only.
       operationId: updateNodeLeaves
       parameters:
         - name: apiVersion
diff --git a/docs/release-notes.rst b/docs/release-notes.rst
index 12e485a..d52e729 100755
--- a/docs/release-notes.rst
+++ b/docs/release-notes.rst
@@ -39,7 +39,7 @@
 Bug Fixes
 ---------
 3.2.6
-    - None
+    - `CPS-1526 <https://jira.onap.org/browse/CPS-1526>`_ Fix response message for PATCH operation
 
 Features
 --------
@@ -229,6 +229,9 @@
 For upgrading, CPS uses Liquibase for database upgrades. CPS/NCMP currently only supports upgrading from Liquibase changelog 11 to Liquibase changelog 16.
 This is from commit CPS-506: List all known modules and revision to CPS-1312: Default CMHandles to READY during upgrade or from ONAP release Honolulu to Kohn.
 
+CPS core Patch operation currently supports updating data of one top level data node. When performing Patch on multiple top level data nodes at once
+a 400 Bad Request is sent as response. This is part of commit CPS-1526.
+
 ..      ====================
 ..      * * *   KOHN   * * *
 ..      ====================