From fd2e6ddde2c2260951e2dfd5e3fd7f4bd04976e1 Mon Sep 17 00:00:00 2001 From: niamhcore Date: Wed, 29 Sep 2021 16:43:35 +0100 Subject: Changing resource identifier to a query param *Update dmi operations to build dmi url using query param Issue-ID: CPS-679 Signed-off-by: niamhcore Change-Id: I2292507c5057837932f8e21f1a8e80721066b336 --- cps-ncmp-rest/docs/openapi/components.yaml | 20 +++++++++++++--- cps-ncmp-rest/docs/openapi/ncmproxy.yml | 6 ++--- cps-ncmp-rest/docs/openapi/openapi.yml | 4 ++-- .../rest/controller/NetworkCmProxyController.java | 15 ++++++------ .../controller/NetworkCmProxyControllerSpec.groovy | 28 ++++++++++++++-------- .../cps/ncmp/api/impl/operation/DmiOperations.java | 13 ++++------ .../api/impl/operation/DmiOperationsSpec.groovy | 12 +++++----- 7 files changed, 58 insertions(+), 40 deletions(-) diff --git a/cps-ncmp-rest/docs/openapi/components.yaml b/cps-ncmp-rest/docs/openapi/components.yaml index ffb8dde11..560c945dd 100644 --- a/cps-ncmp-rest/docs/openapi/components.yaml +++ b/cps-ncmp-rest/docs/openapi/components.yaml @@ -104,13 +104,27 @@ components: schema: type: string default: / - resourceIdentifierInPath: + resourceIdentifierInQuery: name: resourceIdentifier - in: path - description: Resource identifier to get/set the resource data + in: query + description: The format of resource identifier depend on the associated DMI Plugin implementation. For ONAP DMI Plugin it will be RESTConf paths but it can really be anything. required: true + allowReserved: true schema: type: string + examples: + sample1: + value: + resourceIdentifier: \parent\child + sample2: + value: + resourceIdentifier: \parent\listElement[key=value] + sample3: + value: + resourceIdentifier: \parent\listElement[key=value]\grandChild + sample4: + value: + resourceIdentifier: parent=1,child=abc acceptParamInHeader: name: Accept in: header diff --git a/cps-ncmp-rest/docs/openapi/ncmproxy.yml b/cps-ncmp-rest/docs/openapi/ncmproxy.yml index 2e5eba754..263c76c13 100755 --- a/cps-ncmp-rest/docs/openapi/ncmproxy.yml +++ b/cps-ncmp-rest/docs/openapi/ncmproxy.yml @@ -211,7 +211,7 @@ getResourceDataForPassthroughOperational: operationId: getResourceDataOperationalForCmHandle parameters: - $ref: 'components.yaml#/components/parameters/cmHandleInPath' - - $ref: 'components.yaml#/components/parameters/resourceIdentifierInPath' + - $ref: 'components.yaml#/components/parameters/resourceIdentifierInQuery' - $ref: 'components.yaml#/components/parameters/acceptParamInHeader' - $ref: 'components.yaml#/components/parameters/fieldsParamInQuery' - $ref: 'components.yaml#/components/parameters/depthParamInQuery' @@ -236,7 +236,7 @@ resourceDataForPassthroughRunning: operationId: getResourceDataRunningForCmHandle parameters: - $ref: 'components.yaml#/components/parameters/cmHandleInPath' - - $ref: 'components.yaml#/components/parameters/resourceIdentifierInPath' + - $ref: 'components.yaml#/components/parameters/resourceIdentifierInQuery' - $ref: 'components.yaml#/components/parameters/acceptParamInHeader' - $ref: 'components.yaml#/components/parameters/fieldsParamInQuery' - $ref: 'components.yaml#/components/parameters/depthParamInQuery' @@ -259,7 +259,7 @@ resourceDataForPassthroughRunning: operationId: createResourceDataRunningForCmHandle parameters: - $ref: 'components.yaml#/components/parameters/cmHandleInPath' - - $ref: 'components.yaml#/components/parameters/resourceIdentifierInPath' + - $ref: 'components.yaml#/components/parameters/resourceIdentifierInQuery' - $ref: 'components.yaml#/components/parameters/contentParamInHeader' requestBody: required: true diff --git a/cps-ncmp-rest/docs/openapi/openapi.yml b/cps-ncmp-rest/docs/openapi/openapi.yml index 12356b588..1620eba2f 100755 --- a/cps-ncmp-rest/docs/openapi/openapi.yml +++ b/cps-ncmp-rest/docs/openapi/openapi.yml @@ -41,10 +41,10 @@ paths: /v1/ch: $ref: 'ncmproxy.yml#/updateDmiRegistration' - /v1/ch/{cm-handle}/data/ds/ncmp-datastore:passthrough-operational/{resourceIdentifier}: + /v1/ch/{cm-handle}/data/ds/ncmp-datastore:passthrough-operational: $ref: 'ncmproxy.yml#/getResourceDataForPassthroughOperational' - /v1/ch/{cm-handle}/data/ds/ncmp-datastore:passthrough-running/{resourceIdentifier}: + /v1/ch/{cm-handle}/data/ds/ncmp-datastore:passthrough-running: $ref: 'ncmproxy.yml#/resourceDataForPassthroughRunning' /v1/ch/{cm-handle}/modules: diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java index a4d94cebf..0a1a6419e 100755 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java +++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/NetworkCmProxyController.java @@ -27,7 +27,6 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import java.util.Collection; import javax.validation.Valid; -import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import org.onap.cps.ncmp.api.NetworkCmProxyDataService; import org.onap.cps.ncmp.api.models.DmiPluginRegistration; @@ -167,8 +166,8 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { public ResponseEntity getResourceDataOperationalForCmHandle(final String cmHandle, final String resourceIdentifier, final String accept, - final @Valid String fields, - final @Min(1) @Valid Integer depth) { + final String fields, + final Integer depth) { final Object responseObject = networkCmProxyDataService.getResourceDataOperationalForCmHandle(cmHandle, resourceIdentifier, accept, @@ -191,8 +190,8 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { public ResponseEntity getResourceDataRunningForCmHandle(final String cmHandle, final String resourceIdentifier, final String accept, - final @Valid String fields, - final @Min(1) @Valid Integer depth) { + final String fields, + final Integer depth) { final Object responseObject = networkCmProxyDataService.getResourceDataPassThroughRunningForCmHandle(cmHandle, resourceIdentifier, accept, @@ -205,15 +204,15 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { * Create resource data in datastore pass through running * for given cm-handle. * - * @param cmHandle cm handle identifier * @param resourceIdentifier resource identifier + * @param cmHandle cm handle identifier * @param requestBody requestBody * @param contentType content type of body * @return {@code ResponseEntity} response from dmi plugi */ @Override - public ResponseEntity createResourceDataRunningForCmHandle(final String cmHandle, - final String resourceIdentifier, + public ResponseEntity createResourceDataRunningForCmHandle(final String resourceIdentifier, + final String cmHandle, final String requestBody, final String contentType) { networkCmProxyDataService.createResourceDataPassThroughRunningForCmHandle(cmHandle, diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy index 9f2b4e19a..d62ae93b0 100644 --- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy +++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/NetworkCmProxyControllerSpec.groovy @@ -193,7 +193,7 @@ class NetworkCmProxyControllerSpec extends Specification { def 'Get Resource Data from pass-through operational.' () { given: 'resource data url' def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-operational" + - "/testResourceIdentifier?fields=testFields&depth=5" + "?resourceIdentifier=parent/child&fields=testFields&depth=5" when: 'get data resource request is performed' def response = mvc.perform( get(getUrl) @@ -202,7 +202,7 @@ class NetworkCmProxyControllerSpec extends Specification { ).andReturn().response then: 'the NCMP data service is called with getResourceDataOperationalForCmHandle' 1 * mockNetworkCmProxyDataService.getResourceDataOperationalForCmHandle('testCmHandle', - 'testResourceIdentifier', + 'parent/child', 'application/json', 'testFields', 5) @@ -210,16 +210,16 @@ class NetworkCmProxyControllerSpec extends Specification { response.status == HttpStatus.OK.value() } - def 'Get Resource Data from pass-through running.' () { + def 'Get Resource Data from pass-through running with #scenario value in resource identifier param.' () { given: 'resource data url' def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running" + - "/testResourceIdentifier?fields=testFields&depth=5" + "?resourceIdentifier=" + resourceIdentifier + "&fields=testFields&depth=5" and: 'ncmp service returns json object' mockNetworkCmProxyDataService.getResourceDataPassThroughRunningForCmHandle('testCmHandle', - 'testResourceIdentifier', - 'application/json', - 'testFields', - 5) >> '{valid-json}' + resourceIdentifier, + 'application/json', + 'testFields', + 5) >> '{valid-json}' when: 'get data resource request is performed' def response = mvc.perform( get(getUrl) @@ -230,12 +230,20 @@ class NetworkCmProxyControllerSpec extends Specification { response.status == HttpStatus.OK.value() and: 'response contains valid object body' response.getContentAsString() == '{valid-json}' + where: 'tokens are used in the resource identifier parameter' + scenario | resourceIdentifier + '/' | 'id/with/slashes' + '?' | 'idWith?' + ',' | 'idWith,' + '=' | 'idWith=' + '[]' | 'idWith[]' + '? needs to be encoded as %3F' | 'idWith%3F' } def 'Create Resource Data from pass-through running with #scenario.' () { given: 'resource data url' def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-running" + - "/testResourceIdentifier" + "?resourceIdentifier=parent/child" when: 'get data resource request is performed' def response = mvc.perform( post(getUrl) @@ -244,7 +252,7 @@ class NetworkCmProxyControllerSpec extends Specification { ).andReturn().response then: 'ncmp service method to create resource called' 1 * mockNetworkCmProxyDataService.createResourceDataPassThroughRunningForCmHandle('testCmHandle', - 'testResourceIdentifier', requestBody, 'application/json;charset=UTF-8') + 'parent/child', requestBody, 'application/json;charset=UTF-8') and: 'resource is created' response.status == HttpStatus.CREATED.value() where: 'given request body' diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operation/DmiOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operation/DmiOperations.java index 71af3d4cf..c295e0328 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operation/DmiOperations.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operation/DmiOperations.java @@ -52,6 +52,8 @@ public class DmiOperations { private static final String DMI_CM_HANDLE_PATH = "/v1/ch/{cmHandle}"; private static final String DMI_CM_HANDLE_DATASTORE_PATH = DMI_CM_HANDLE_PATH + "/data/ds"; private static final String URL_SEPARATOR = "/"; + private static final String RESOURCE_IDENTIFIER = "resourceIdentifier"; + /** * Constructor for {@code DmiOperations}. This method also manipulates url properties. @@ -199,7 +201,7 @@ public class DmiOperations { stringBuilder.append(DMI_API_PATH); stringBuilder.append(DMI_CM_HANDLE_DATASTORE_PATH.replace("{cmHandle}", cmHandle)); stringBuilder.append(URL_SEPARATOR + dataStoreEnum.getValue()); - stringBuilder.append(URL_SEPARATOR + resourceId); + stringBuilder.append("?" + RESOURCE_IDENTIFIER + "=" + resourceId); return stringBuilder; } @@ -208,15 +210,10 @@ public class DmiOperations { final Integer depthQuery) { final var doesFieldExists = (fieldsQuery != null && !fieldsQuery.isEmpty()); if (doesFieldExists) { - stringBuilder.append("?").append("fields=").append(fieldsQuery); + stringBuilder.append("&").append("fields=").append(fieldsQuery); } if (depthQuery != null) { - if (doesFieldExists) { - stringBuilder.append("&"); - } else { - stringBuilder.append("?"); - } - stringBuilder.append("depth=").append(depthQuery); + stringBuilder.append("&").append("depth=").append(depthQuery); } } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operation/DmiOperationsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operation/DmiOperationsSpec.groovy index 6a1ce1a18..8af778106 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operation/DmiOperationsSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operation/DmiOperationsSpec.groovy @@ -42,11 +42,11 @@ class DmiOperationsSpec extends Specification { def 'call get resource data for pass-through:operational datastore from DMI.'() { given: 'expected url' def expectedUrl = 'testDmiBasePath/dmi/v1/ch/testCmhandle/data/ds' + - '/ncmp-datastore:passthrough-operational/testResourceId?fields=testFieldsQuery&depth=10' + '/ncmp-datastore:passthrough-operational?resourceIdentifier=parent/child&fields=testFieldsQuery&depth=10' when: 'get resource data is called to DMI' objectUnderTest.getResourceDataOperationalFromDmi('testDmiBasePath', 'testCmhandle', - 'testResourceId', + 'parent/child', 'testFieldsQuery', 10, 'testAcceptJson', @@ -57,11 +57,11 @@ class DmiOperationsSpec extends Specification { def 'call get resource data for pass-through:running datastore from DMI.'() { given: 'expected url' def expectedUrl = 'testDmiBasePath/dmi/v1/ch/testCmhandle/data/ds' + - '/ncmp-datastore:passthrough-running/testResourceId?fields=testFieldsQuery&depth=10' + '/ncmp-datastore:passthrough-running?resourceIdentifier=parent/child&fields=testFieldsQuery&depth=10' when: 'get resource data is called to DMI' objectUnderTest.getResourceDataPassThroughRunningFromDmi('testDmiBasePath', 'testCmhandle', - 'testResourceId', + 'parent/child', 'testFieldsQuery', 10, 'testAcceptJson', @@ -72,11 +72,11 @@ class DmiOperationsSpec extends Specification { def 'call create resource data for pass-through:running datastore from DMI.'() { given: 'expected url' def expectedUrl = 'testDmiBasePath/dmi/v1/ch/testCmhandle/data/ds' + - '/ncmp-datastore:passthrough-running/testResourceId' + '/ncmp-datastore:passthrough-running?resourceIdentifier=parent/child' when: 'get resource data is called to DMI' objectUnderTest.createResourceDataPassThroughRunningFromDmi('testDmiBasePath', 'testCmhandle', - 'testResourceId', + 'parent/child', 'testJsonbody') then: 'the put operation is executed with the correct URL' 1 * mockDmiRestClient.postOperationWithJsonData(expectedUrl, 'testJsonbody', _ as HttpHeaders) -- cgit 1.2.3-korg