aboutsummaryrefslogtreecommitdiffstats
path: root/cps-rest
diff options
context:
space:
mode:
authorArpit Singh <as00745003@techmahindra.com>2023-08-02 18:35:31 +0530
committerPriyank Maheshwari <priyank.maheshwari@est.tech>2023-11-14 16:42:42 +0000
commit0339c71815a4ca4cbab3d263d6c4586a112cda64 (patch)
tree89a3ed8006daa27542f464834071fc5191484668 /cps-rest
parent0fdda53aa0dde9ec3a4c1b287b3ff8da4a75da5c (diff)
CPS Delta API 1: Delta between 2 anchors
- CPS Delta Feature Part 1: To find delta between two anchors - created new endpoint deltaByDataspaceAndAnchors - endpoint to take dataspaceName, source anchor, target anchor, xpath, descendants as input - added new service CpsDeltaService - added method to find delta between DataNodes: getDeltaReport - added method to find removed data nodes: getRemovedDeltaReports - added method to get Added DataNodes: getAddedDeltaReports - added method to get Map of xpath to DataNode: convertToXPathToDataNodesMap - added a POJO for delta report - Added new JSON data for delta feature testing - Added groovy test files CpsDeltaServiceImplSpec and DeltaReportBuilderSpec - code related to update operation, will be added in separate commit Issue-ID: CPS-1824 Signed-off-by: Arpit Singh <as00745003@techmahindra.com> Change-Id: I313f0f71d04b03878be7643f709d8af1aa6df6ba
Diffstat (limited to 'cps-rest')
-rw-r--r--cps-rest/docs/openapi/components.yml26
-rw-r--r--cps-rest/docs/openapi/cpsDataV2.yml33
-rw-r--r--cps-rest/docs/openapi/openapi.yml3
-rwxr-xr-xcps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java18
-rwxr-xr-xcps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy21
5 files changed, 100 insertions, 1 deletions
diff --git a/cps-rest/docs/openapi/components.yml b/cps-rest/docs/openapi/components.yml
index a3016ce76..c1b111bfa 100644
--- a/cps-rest/docs/openapi/components.yml
+++ b/cps-rest/docs/openapi/components.yml
@@ -137,6 +137,24 @@ components:
name: SciFi
- code: 02
name: kids
+ deltaReportSample:
+ value:
+ - action: "ADD"
+ xpath: "/bookstore/categories/[@code=3]"
+ target-data:
+ code: 3,
+ name: "kidz"
+ - action: "REMOVE"
+ xpath: "/bookstore/categories/[@code=1]"
+ source-data:
+ code: 1,
+ name: "Fiction"
+ - action: "UPDATE"
+ xpath: "/bookstore/categories/[@code=2]"
+ source-data:
+ name: "Funny"
+ target-data:
+ name: "Comic"
parameters:
dataspaceNameInQuery:
@@ -187,6 +205,14 @@ components:
schema:
type: string
example: my-anchor
+ targetAnchorNameInQuery:
+ name: target-anchor-name
+ in: query
+ description: target-anchor-name
+ required: true
+ schema:
+ type: string
+ example: my-anchor
xpathInQuery:
name: xpath
in: query
diff --git a/cps-rest/docs/openapi/cpsDataV2.yml b/cps-rest/docs/openapi/cpsDataV2.yml
index ad0c299d7..c7629b70e 100644
--- a/cps-rest/docs/openapi/cpsDataV2.yml
+++ b/cps-rest/docs/openapi/cpsDataV2.yml
@@ -46,4 +46,37 @@ nodeByDataspaceAndAnchor:
$ref: 'components.yml#/components/responses/Forbidden'
'500':
$ref: 'components.yml#/components/responses/InternalServerError'
+ x-codegen-request-body-name: xpath
+
+deltaByDataspaceAndAnchors:
+ get:
+ description: Get delta between two anchors within a given dataspace
+ tags:
+ - cps-data
+ summary: Get delta between anchors in the same dataspace
+ operationId: getDeltaByDataspaceAndAnchors
+ parameters:
+ - $ref: 'components.yml#/components/parameters/dataspaceNameInPath'
+ - $ref: 'components.yml#/components/parameters/anchorNameInPath'
+ - $ref: 'components.yml#/components/parameters/targetAnchorNameInQuery'
+ - $ref: 'components.yml#/components/parameters/xpathInQuery'
+ - $ref: 'components.yml#/components/parameters/descendantsInQuery'
+ responses:
+ '200':
+ description: OK
+ content:
+ application/json:
+ schema:
+ type: object
+ examples:
+ dataSample:
+ $ref: 'components.yml#/components/examples/deltaReportSample'
+ '400':
+ $ref: 'components.yml#/components/responses/BadRequest'
+ '401':
+ $ref: 'components.yml#/components/responses/Unauthorized'
+ '403':
+ $ref: 'components.yml#/components/responses/Forbidden'
+ '500':
+ $ref: 'components.yml#/components/responses/InternalServerError'
x-codegen-request-body-name: xpath \ No newline at end of file
diff --git a/cps-rest/docs/openapi/openapi.yml b/cps-rest/docs/openapi/openapi.yml
index 4bbf9f0fb..f29335a0a 100644
--- a/cps-rest/docs/openapi/openapi.yml
+++ b/cps-rest/docs/openapi/openapi.yml
@@ -104,6 +104,9 @@ paths:
/{apiVersion}/dataspaces/{dataspace-name}/anchors/{anchor-name}/list-nodes:
$ref: 'cpsData.yml#/listElementByDataspaceAndAnchor'
+ /v2/dataspaces/{dataspace-name}/anchors/{anchor-name}/delta:
+ $ref: 'cpsDataV2.yml#/deltaByDataspaceAndAnchors'
+
/v1/dataspaces/{dataspace-name}/anchors/{anchor-name}/nodes/query:
$ref: 'cpsQueryV1Deprecated.yml#/nodesByDataspaceAndAnchorAndCpsPath'
diff --git a/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java b/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java
index 60e7fb6d2..4f9328b6c 100755
--- a/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java
+++ b/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java
@@ -38,6 +38,7 @@ import org.onap.cps.api.CpsDataService;
import org.onap.cps.rest.api.CpsDataApi;
import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.spi.model.DataNode;
+import org.onap.cps.spi.model.DeltaReport;
import org.onap.cps.utils.ContentType;
import org.onap.cps.utils.DataMapUtils;
import org.onap.cps.utils.JsonObjectMapper;
@@ -166,6 +167,23 @@ public class DataRestController implements CpsDataApi {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
+ @Override
+ @Timed(value = "cps.data.controller.get.delta",
+ description = "Time taken to get delta between anchors")
+ public ResponseEntity<Object> getDeltaByDataspaceAndAnchors(final String dataspaceName,
+ final String sourceAnchorName,
+ final String targetAnchorName,
+ final String xpath,
+ final String descendants) {
+ final FetchDescendantsOption fetchDescendantsOption =
+ FetchDescendantsOption.getFetchDescendantsOption(descendants);
+
+ final List<DeltaReport> deltaBetweenAnchors =
+ cpsDataService.getDeltaByDataspaceAndAnchors(dataspaceName, sourceAnchorName,
+ targetAnchorName, xpath, fetchDescendantsOption);
+ return new ResponseEntity<>(jsonObjectMapper.asJsonString(deltaBetweenAnchors), HttpStatus.OK);
+ }
+
private static boolean isRootXpath(final String xpath) {
return ROOT_XPATH.equals(xpath);
}
diff --git a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy
index 81262c80c..12c9c4c60 100755
--- a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy
+++ b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy
@@ -30,6 +30,7 @@ import org.onap.cps.api.CpsDataService
import org.onap.cps.spi.FetchDescendantsOption
import org.onap.cps.spi.model.DataNode
import org.onap.cps.spi.model.DataNodeBuilder
+import org.onap.cps.spi.model.DeltaReportBuilder
import org.onap.cps.utils.ContentType
import org.onap.cps.utils.DateTimeUtility
import org.onap.cps.utils.JsonObjectMapper
@@ -331,7 +332,25 @@ class DataRestControllerSpec extends Specification {
and: 'the response contains the root node identifier'
assert response.contentAsString.contains('parent')
and: 'the response contains child is true'
- assert response.contentAsString.contains('"child"') == true
+ assert response.contentAsString.contains('"child"')
+ }
+
+ def 'Get delta between two anchors'() {
+ given: 'the service returns a list containing delta reports'
+ def deltaReports = new DeltaReportBuilder().actionAdd().withXpath('/bookstore').withSourceData('bookstore-name': 'Easons').withTargetData('bookstore-name': 'Easons').build()
+ def xpath = 'some xpath'
+ def endpoint = "$dataNodeBaseEndpointV2/anchors/sourceAnchor/delta"
+ mockCpsDataService.getDeltaByDataspaceAndAnchors(dataspaceName, 'sourceAnchor', 'targetAnchor', xpath, OMIT_DESCENDANTS) >> [deltaReports]
+ when: 'get delta request is performed using REST API'
+ def response =
+ mvc.perform(get(endpoint)
+ .param('target-anchor-name', 'targetAnchor')
+ .param('xpath', xpath))
+ .andReturn().response
+ then: 'expected response code is returned'
+ assert response.status == HttpStatus.OK.value()
+ and: 'the response contains expected value'
+ assert response.contentAsString.contains("[{\"action\":\"add\",\"xpath\":\"/bookstore\",\"sourceData\":{\"bookstore-name\":\"Easons\"},\"targetData\":{\"bookstore-name\":\"Easons\"}}]")
}
def 'Update data node leaves: #scenario.'() {