From: aditya puthuparambil Date: Fri, 3 Dec 2021 13:22:51 +0000 (+0000) Subject: Merge "Changing putOperationWithJson to postOperationWithJson" X-Git-Tag: mr/823/126723/7~26 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=f1e1acb92cb2b891b2a9e64b99ad85c26758fbe2;hp=14ace1a5da8dd770acd098cf2de575c16962ee78;p=cps.git Merge "Changing putOperationWithJson to postOperationWithJson" --- diff --git a/cps-rest/docs/openapi/components.yml b/cps-rest/docs/openapi/components.yml index 3d2eb57e4..ff2816af6 100644 --- a/cps-rest/docs/openapi/components.yml +++ b/cps-rest/docs/openapi/components.yml @@ -25,13 +25,13 @@ components: properties: name: type: string - example: my_anchor + example: my-anchor dataspaceName: type: string - example: my_dataspace + example: my-dataspace schemaSetName: type: string - example: my_schema_set + example: my-schema-set ErrorMessage: type: object @@ -39,13 +39,10 @@ components: properties: status: type: string - example: 400 message: type: string - example: Dataspace not found details: type: string - example: Dataspace with name D1 does not exist. MultipartFile: type: object @@ -56,7 +53,7 @@ components: type: string description: multipartFile format: binary - example: http://example.com/examples/example.yang + example: 'https://github.com/onap/cps/blob/master/cps-service/src/test/resources/bookstore.yang' ModuleReferences: type: object @@ -64,13 +61,13 @@ components: properties: name: type: string - example: module_reference_name + example: my-module-reference-name namespace: type: string - example: module_reference_namespace + example: my-module-reference-namespace revision: type: string - example: module_reference_revision + example: my-module-reference-revision SchemaSetDetails: type: object @@ -78,14 +75,35 @@ components: properties: dataspaceName: type: string - example: my_dataspace + example: my-dataspace moduleReferences: type: array items: $ref: '#/components/schemas/ModuleReferences' name: type: string - example: my_schema_set + example: my-schema-set + + examples: + dataSampleRequest: + value: + test:bookstore: + bookstore-name: Chapters + categories: + - code: 01 + name: SciFi + - code: 02 + name: kids + + dataSampleResponse: + summary: The data node returned does not include the root node. This is being investigated as a part of CPS-461 + value: + bookstore-name: Chapters + categories: + - code: 01 + name: SciFi + - code: 02 + name: kids parameters: dataspaceNameInQuery: @@ -95,6 +113,7 @@ components: required: true schema: type: string + example: my-dataspace dataspaceNameInPath: name: dataspace-name in: path @@ -102,6 +121,7 @@ components: required: true schema: type: string + example: my-dataspace anchorNameInPath: name: anchor-name in: path @@ -109,6 +129,7 @@ components: required: true schema: type: string + example: my-anchor schemaSetNameInQuery: name: schema-set-name in: query @@ -116,6 +137,7 @@ components: required: true schema: type: string + example: my-schema-set schemaSetNameInPath: name: schema-set-name in: path @@ -123,6 +145,7 @@ components: required: true schema: type: string + example: my-schema-set anchorNameInQuery: name: anchor-name in: query @@ -130,29 +153,45 @@ components: required: true schema: type: string + example: my-anchor xpathInQuery: name: xpath in: query - description: xpath + description: For more details on xpath, please refer https://docs.onap.org/projects/onap-cps/en/latest/cps-path.html required: false schema: type: string default: / + examples: + container xpath: + value: /shops/bookstore + list attributes xpath: + value: /shops/bookstore/categories[@code=1] requiredXpathInQuery: name: xpath in: query - description: xpath + description: For more details on xpath, please refer https://docs.onap.org/projects/onap-cps/en/latest/cps-path.html required: true schema: type: string + examples: + container xpath: + value: /shops/bookstore + list attributes xpath: + value: /shops/bookstore/categories[@code=1] cpsPathInQuery: name: cps-path in: query - description: cps-path + description: For more details on cps path, please refer https://docs.onap.org/projects/onap-cps/en/latest/cps-path.html required: false schema: type: string default: / + examples: + container cps path: + value: //bookstore + list attributes cps path: + value: //categories[@code=1] includeDescendantsOptionInQuery: name: include-descendants in: query @@ -161,6 +200,7 @@ components: schema: type: boolean default: false + example: false observedTimestampInQuery: name: observed-timestamp in: query @@ -177,43 +217,66 @@ components: application/json: schema: $ref: '#/components/schemas/ErrorMessage' + example: + status: 404 + message: Resource Not Found + details: The requested resource is not found Unauthorized: description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' + example: + status: 401 + message: Unauthorized request + details: This request is unauthorized Forbidden: description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' + example: + status: 403 + message: Request Forbidden + details: This request is forbidden BadRequest: description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' + example: + status: 400 + message: Bad Request + details: The provided request is not valid Conflict: description: Conflict content: application/json: schema: $ref: '#/components/schemas/ErrorMessage' + example: + status: 409 + message: Conflicting request + details: The request cannot be processed as the resource is in use. Ok: description: OK content: application/json: schema: type: object - example: { "key": "value" } + examples: + dataSampleResponse: + value: "" Created: description: Created content: text/plain: schema: type: string + example: my-resource NoContent: description: No Content content: {} diff --git a/cps-rest/docs/openapi/cpsData.yml b/cps-rest/docs/openapi/cpsData.yml index 2b65ae440..15f8a1c71 100644 --- a/cps-rest/docs/openapi/cpsData.yml +++ b/cps-rest/docs/openapi/cpsData.yml @@ -35,7 +35,9 @@ nodeByDataspaceAndAnchor: application/json: schema: type: object - example: { "child": my_child,"leafList": "leafListElement1, leafListElement2", "leaf": my_leaf } + examples: + dataSampleResponse: + $ref: 'components.yml#/components/examples/dataSampleResponse' '400': $ref: 'components.yml#/components/responses/BadRequest' '401': @@ -63,7 +65,10 @@ listElementByDataspaceAndAnchor: content: application/json: schema: - type: string + type: object + examples: + dataSampleRequest: + $ref: 'components.yml#/components/examples/dataSampleRequest' responses: '201': $ref: 'components.yml#/components/responses/Created' @@ -90,10 +95,13 @@ listElementByDataspaceAndAnchor: content: application/json: schema: - type: string + type: object + examples: + dataSampleRequest: + $ref: 'components.yml#/components/examples/dataSampleRequest' responses: '200': - $ref: 'components.yml#/components/responses/Created' + $ref: 'components.yml#/components/responses/Ok' '400': $ref: 'components.yml#/components/responses/BadRequest' '401': @@ -140,7 +148,10 @@ nodesByDataspaceAndAnchor: content: application/json: schema: - type: string + type: object + examples: + dataSampleRequest: + $ref: 'components.yml#/components/examples/dataSampleRequest' responses: '201': $ref: 'components.yml#/components/responses/Created' @@ -167,7 +178,10 @@ nodesByDataspaceAndAnchor: content: application/json: schema: - type: string + type: object + examples: + dataSampleRequest: + $ref: 'components.yml#/components/examples/dataSampleRequest' responses: '200': $ref: 'components.yml#/components/responses/Ok' @@ -216,7 +230,10 @@ nodesByDataspaceAndAnchor: content: application/json: schema: - type: string + type: object + examples: + dataSampleRequest: + $ref: 'components.yml#/components/examples/dataSampleRequest' responses: '200': $ref: 'components.yml#/components/responses/Ok' diff --git a/cps-rest/docs/openapi/cpsQuery.yml b/cps-rest/docs/openapi/cpsQuery.yml index f45f3f41a..4f938aa89 100644 --- a/cps-rest/docs/openapi/cpsQuery.yml +++ b/cps-rest/docs/openapi/cpsQuery.yml @@ -30,7 +30,14 @@ nodesByDataspaceAndAnchorAndCpsPath: - $ref: 'components.yml#/components/parameters/includeDescendantsOptionInQuery' responses: '200': - $ref: 'components.yml#/components/responses/Ok' + description: OK + content: + application/json: + schema: + type: object + examples: + dataSampleResponse: + $ref: 'components.yml#/components/examples/dataSampleResponse' '400': $ref: 'components.yml#/components/responses/BadRequest' '401': 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 e57fb3c8c..73c2c27c9 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 @@ -49,11 +49,12 @@ public class DataRestController implements CpsDataApi { @Override public ResponseEntity createNode(final String dataspaceName, final String anchorName, - final String jsonData, final String parentNodeXpath, final String observedTimestamp) { + final Object jsonData, final String parentNodeXpath, final String observedTimestamp) { if (isRootXpath(parentNodeXpath)) { - cpsDataService.saveData(dataspaceName, anchorName, jsonData, toOffsetDateTime(observedTimestamp)); + cpsDataService.saveData(dataspaceName, anchorName, jsonData.toString(), + toOffsetDateTime(observedTimestamp)); } else { - cpsDataService.saveData(dataspaceName, anchorName, parentNodeXpath, jsonData, + cpsDataService.saveData(dataspaceName, anchorName, parentNodeXpath, jsonData.toString(), toOffsetDateTime(observedTimestamp)); } return new ResponseEntity<>(HttpStatus.CREATED); @@ -61,7 +62,7 @@ public class DataRestController implements CpsDataApi { @Override public ResponseEntity deleteDataNode(final String dataspaceName, final String anchorName, - final String xpath, final String observedTimestamp) { + final String xpath, final String observedTimestamp) { cpsDataService.deleteDataNode(dataspaceName, anchorName, xpath, toOffsetDateTime(observedTimestamp)); return new ResponseEntity<>(HttpStatus.NO_CONTENT); @@ -69,8 +70,8 @@ public class DataRestController implements CpsDataApi { @Override public ResponseEntity addListElements(final String parentNodeXpath, - final String dataspaceName, final String anchorName, final String jsonData, final String observedTimestamp) { - cpsDataService.saveListElements(dataspaceName, anchorName, parentNodeXpath, jsonData, + final String dataspaceName, final String anchorName, final Object jsonData, final String observedTimestamp) { + cpsDataService.saveListElements(dataspaceName, anchorName, parentNodeXpath, jsonData.toString(), toOffsetDateTime(observedTimestamp)); return new ResponseEntity<>(HttpStatus.CREATED); } @@ -87,25 +88,26 @@ public class DataRestController implements CpsDataApi { @Override public ResponseEntity updateNodeLeaves(final String dataspaceName, - final String anchorName, final String jsonData, final String parentNodeXpath, final String observedTimestamp) { - cpsDataService.updateNodeLeaves(dataspaceName, anchorName, parentNodeXpath, jsonData, + final String anchorName, final Object jsonData, final String parentNodeXpath, final String observedTimestamp) { + cpsDataService.updateNodeLeaves(dataspaceName, anchorName, parentNodeXpath, jsonData.toString(), toOffsetDateTime(observedTimestamp)); return new ResponseEntity<>(HttpStatus.OK); } @Override public ResponseEntity replaceNode(final String dataspaceName, final String anchorName, - final String jsonData, final String parentNodeXpath, final String observedTimestamp) { + final Object jsonData, final String parentNodeXpath, final String observedTimestamp) { cpsDataService - .replaceNodeTree(dataspaceName, anchorName, parentNodeXpath, jsonData, toOffsetDateTime(observedTimestamp)); + .replaceNodeTree(dataspaceName, anchorName, parentNodeXpath, jsonData.toString(), + toOffsetDateTime(observedTimestamp)); return new ResponseEntity<>(HttpStatus.OK); } @Override - public ResponseEntity replaceListContent(final String parentNodeXpath, - final String dataspaceName, final String anchorName, final String jsonData, + public ResponseEntity replaceListContent(final String parentNodeXpath, + final String dataspaceName, final String anchorName, final Object jsonData, final String observedTimestamp) { - cpsDataService.replaceListContent(dataspaceName, anchorName, parentNodeXpath, jsonData, + cpsDataService.replaceListContent(dataspaceName, anchorName, parentNodeXpath, jsonData.toString(), toOffsetDateTime(observedTimestamp)); return new ResponseEntity<>(HttpStatus.OK); } 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 2c288344c..445b2a2bd 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 @@ -60,6 +60,8 @@ class DataRestControllerSpec extends Specification { def dataspaceName = 'my_dataspace' def anchorName = 'my_anchor' def noTimestamp = null + def jsonString = '{"some-key" : "some-value"}' + def jsonObject @Shared static DataNode dataNodeWithLeavesNoChildren = new DataNodeBuilder().withXpath('/xpath') @@ -71,24 +73,24 @@ class DataRestControllerSpec extends Specification { def setup() { dataNodeBaseEndpoint = "$basePath/v1/dataspaces/$dataspaceName" + jsonObject = groovy.json.JsonOutput.toJson(jsonString); } def 'Create a node: #scenario.'() { - given: 'some json to create a data node' + given: 'endpoint to create a node' def endpoint = "$dataNodeBaseEndpoint/anchors/$anchorName/nodes" - def json = 'some json (this is not validated)' when: 'post is invoked with datanode endpoint and json' def response = mvc.perform( post(endpoint) .contentType(MediaType.APPLICATION_JSON) .param('xpath', parentNodeXpath) - .content(json) + .content(jsonObject) ).andReturn().response then: 'a created response is returned' response.status == HttpStatus.CREATED.value() then: 'the java API was called with the correct parameters' - 1 * mockCpsDataService.saveData(dataspaceName, anchorName, json, noTimestamp) + 1 * mockCpsDataService.saveData(dataspaceName, anchorName, jsonString, noTimestamp) where: 'following xpath parameters are are used' scenario | parentNodeXpath 'no xpath parameter' | '' @@ -96,9 +98,8 @@ class DataRestControllerSpec extends Specification { } def 'Create a node with observed-timestamp'() { - given: 'some json to create a data node' + given: 'endpoint to create a node' def endpoint = "$dataNodeBaseEndpoint/anchors/$anchorName/nodes" - def json = 'some json (this is not validated)' when: 'post is invoked with datanode endpoint and json' def response = mvc.perform( @@ -106,12 +107,12 @@ class DataRestControllerSpec extends Specification { .contentType(MediaType.APPLICATION_JSON) .param('xpath', '') .param('observed-timestamp', observedTimestamp) - .content(json) + .content(jsonObject) ).andReturn().response then: 'a created response is returned' response.status == expectedHttpStatus.value() then: 'the java API was called with the correct parameters' - expectedApiCount * mockCpsDataService.saveData(dataspaceName, anchorName, json, + expectedApiCount * mockCpsDataService.saveData(dataspaceName, anchorName, jsonString, { it == DateTimeUtility.toOffsetDateTime(observedTimestamp) }) where: scenario | observedTimestamp || expectedApiCount | expectedHttpStatus @@ -120,16 +121,15 @@ class DataRestControllerSpec extends Specification { } def 'Create a child node'() { - given: 'some json to create a data node' + given: 'endpoint to create a node' def endpoint = "$dataNodeBaseEndpoint/anchors/$anchorName/nodes" - def json = 'some json (this is not validated)' and: 'parent node xpath' def parentNodeXpath = 'some xpath' when: 'post is invoked with datanode endpoint and json' def postRequestBuilder = post(endpoint) .contentType(MediaType.APPLICATION_JSON) .param('xpath', parentNodeXpath) - .content(json) + .content(jsonObject) if (observedTimestamp != null) postRequestBuilder.param('observed-timestamp', observedTimestamp) def response = @@ -137,7 +137,7 @@ class DataRestControllerSpec extends Specification { then: 'a created response is returned' response.status == HttpStatus.CREATED.value() then: 'the java API was called with the correct parameters' - 1 * mockCpsDataService.saveData(dataspaceName, anchorName, parentNodeXpath, json, + 1 * mockCpsDataService.saveData(dataspaceName, anchorName, parentNodeXpath, jsonString, DateTimeUtility.toOffsetDateTime(observedTimestamp)) where: scenario | observedTimestamp @@ -146,21 +146,20 @@ class DataRestControllerSpec extends Specification { } def 'Save list elements #scenario.'() { - given: 'parent node xpath and json data inputs' + given: 'parent node xpath ' def parentNodeXpath = 'parent node xpath' - def jsonData = 'json data' when: 'list-node endpoint is invoked with post (create) operation' def postRequestBuilder = post("$dataNodeBaseEndpoint/anchors/$anchorName/list-nodes") .contentType(MediaType.APPLICATION_JSON) .param('xpath', parentNodeXpath) - .content(jsonData) + .content(jsonObject) if (observedTimestamp != null) postRequestBuilder.param('observed-timestamp', observedTimestamp) def response = mvc.perform(postRequestBuilder).andReturn().response then: 'a created response is returned' response.status == expectedHttpStatus.value() then: 'the java API was called with the correct parameters' - expectedApiCount * mockCpsDataService.saveListElements(dataspaceName, anchorName, parentNodeXpath, jsonData, + expectedApiCount * mockCpsDataService.saveListElements(dataspaceName, anchorName, parentNodeXpath, jsonString, { it == DateTimeUtility.toOffsetDateTime(observedTimestamp) }) where: scenario | observedTimestamp || expectedApiCount | expectedHttpStatus @@ -210,19 +209,18 @@ class DataRestControllerSpec extends Specification { } def 'Update data node leaves: #scenario.'() { - given: 'json data' - def jsonData = 'json data' + given: 'endpoint to update a node ' def endpoint = "$dataNodeBaseEndpoint/anchors/$anchorName/nodes" when: 'patch request is performed' def response = mvc.perform( patch(endpoint) .contentType(MediaType.APPLICATION_JSON) - .content(jsonData) + .content(jsonObject) .param('xpath', inputXpath) ).andReturn().response then: 'the service method is invoked with expected parameters' - 1 * mockCpsDataService.updateNodeLeaves(dataspaceName, anchorName, xpathServiceParameter, jsonData, null) + 1 * mockCpsDataService.updateNodeLeaves(dataspaceName, anchorName, xpathServiceParameter, jsonString, null) and: 'response status indicates success' response.status == HttpStatus.OK.value() where: @@ -233,20 +231,19 @@ class DataRestControllerSpec extends Specification { } def 'Update data node leaves with observedTimestamp'() { - given: 'json data' - def jsonData = 'json data' + given: 'endpoint to update a node leaves ' def endpoint = "$dataNodeBaseEndpoint/anchors/$anchorName/nodes" when: 'patch request is performed' def response = mvc.perform( patch(endpoint) .contentType(MediaType.APPLICATION_JSON) - .content(jsonData) + .content(jsonObject) .param('xpath', '/') .param('observed-timestamp', observedTimestamp) ).andReturn().response then: 'the service method is invoked with expected parameters' - expectedApiCount * mockCpsDataService.updateNodeLeaves(dataspaceName, anchorName, '/', jsonData, + expectedApiCount * mockCpsDataService.updateNodeLeaves(dataspaceName, anchorName, '/', jsonString, { it == DateTimeUtility.toOffsetDateTime(observedTimestamp) }) and: 'response status indicates success' response.status == expectedHttpStatus.value() @@ -257,19 +254,18 @@ class DataRestControllerSpec extends Specification { } def 'Replace data node tree: #scenario.'() { - given: 'json data' - def jsonData = 'json data' + given: 'endpoint to replace node' def endpoint = "$dataNodeBaseEndpoint/anchors/$anchorName/nodes" when: 'put request is performed' def response = mvc.perform( put(endpoint) .contentType(MediaType.APPLICATION_JSON) - .content(jsonData) + .content(jsonObject) .param('xpath', inputXpath)) .andReturn().response then: 'the service method is invoked with expected parameters' - 1 * mockCpsDataService.replaceNodeTree(dataspaceName, anchorName, xpathServiceParameter, jsonData, noTimestamp) + 1 * mockCpsDataService.replaceNodeTree(dataspaceName, anchorName, xpathServiceParameter, jsonString, noTimestamp) and: 'response status indicates success' response.status == HttpStatus.OK.value() where: @@ -280,20 +276,19 @@ class DataRestControllerSpec extends Specification { } def 'Replace data node tree with observedTimestamp.'() { - given: 'json data' - def jsonData = 'json data' + given: 'endpoint to replace node' def endpoint = "$dataNodeBaseEndpoint/anchors/$anchorName/nodes" when: 'put request is performed' def response = mvc.perform( put(endpoint) .contentType(MediaType.APPLICATION_JSON) - .content(jsonData) + .content(jsonObject) .param('xpath', '') .param('observed-timestamp', observedTimestamp)) .andReturn().response then: 'the service method is invoked with expected parameters' - expectedApiCount * mockCpsDataService.replaceNodeTree(dataspaceName, anchorName, '/', jsonData, + expectedApiCount * mockCpsDataService.replaceNodeTree(dataspaceName, anchorName, '/', jsonString, { it == DateTimeUtility.toOffsetDateTime(observedTimestamp) }) and: 'response status indicates success' response.status == expectedHttpStatus.value() @@ -308,14 +303,14 @@ class DataRestControllerSpec extends Specification { def putRequestBuilder = put("$dataNodeBaseEndpoint/anchors/$anchorName/list-nodes") .contentType(MediaType.APPLICATION_JSON) .param('xpath', 'parent xpath') - .content('json data') + .content(jsonObject) if (observedTimestamp != null) putRequestBuilder.param('observed-timestamp', observedTimestamp) def response = mvc.perform(putRequestBuilder).andReturn().response then: 'a success response is returned' response.status == expectedHttpStatus.value() and: 'the java API was called with the correct parameters' - expectedApiCount * mockCpsDataService.replaceListContent(dataspaceName, anchorName, 'parent xpath', 'json data', + expectedApiCount * mockCpsDataService.replaceListContent(dataspaceName, anchorName, 'parent xpath', jsonString, { it == DateTimeUtility.toOffsetDateTime(observedTimestamp) }) where: scenario | observedTimestamp || expectedApiCount | expectedHttpStatus diff --git a/cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy b/cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy index f5968442d..658dcaa70 100644 --- a/cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy +++ b/cps-rest/src/test/groovy/org/onap/cps/rest/exceptions/CpsRestExceptionHandlerSpec.groovy @@ -163,7 +163,7 @@ class CpsRestExceptionHandlerSpec extends Specification { post("$basePath/v1/dataspaces/dataspace-name/anchors/anchor-name/nodes") .contentType(MediaType.APPLICATION_JSON) .param('xpath', 'parent node xpath') - .content('json data') + .content(groovy.json.JsonOutput.toJson('{"some-key" : "some-value"}')) ).andReturn().response then: 'response code indicates bad input parameters' response.status == BAD_REQUEST.value()