diff options
Diffstat (limited to 'cps-ncmp-rest')
6 files changed, 94 insertions, 35 deletions
diff --git a/cps-ncmp-rest/docs/openapi/components.yaml b/cps-ncmp-rest/docs/openapi/components.yaml index 8343c1c26b..69225aed2d 100644 --- a/cps-ncmp-rest/docs/openapi/components.yaml +++ b/cps-ncmp-rest/docs/openapi/components.yaml @@ -53,23 +53,23 @@ components: $ref: '#/components/schemas/RestInputCmHandle' updatedCmHandles: type: array - example: - cmHandle: my-cm-handle - cmHandleProperties: - add-my-property: add-property - update-my-property: updated-property - delete-my-property: '~' - publicCmHandleProperties: - add-my-property: add-property - update-my-property: updated-property - delete-my-property: '~' items: $ref: '#/components/schemas/RestInputCmHandle' + example: + cmHandle: my-cm-handle + cmHandleProperties: + add-my-property: add-property + update-my-property: updated-property + delete-my-property: '~' + publicCmHandleProperties: + add-my-property: add-property + update-my-property: updated-property + delete-my-property: '~' removedCmHandles: type: array items: type: string - example: [my-cm-handle1, my-cm-handle2, my-cm-handle3] + example: [my-cm-handle1, my-cm-handle2, my-cm-handle3] RestInputCmHandle: required: @@ -329,6 +329,18 @@ components: sample 3: value: options: (depth=2,fields=book/authors) + topicParamInQuery: + name: topic + in: query + description: topic parameter in query. + required: false + schema: + type: string + allowReserved: true + examples: + sample 1: + value: + topic: my-topic-name contentParamInHeader: name: Content-Type in: header diff --git a/cps-ncmp-rest/docs/openapi/ncmp.yml b/cps-ncmp-rest/docs/openapi/ncmp.yml index c096898324..a9d08b7951 100755 --- a/cps-ncmp-rest/docs/openapi/ncmp.yml +++ b/cps-ncmp-rest/docs/openapi/ncmp.yml @@ -29,6 +29,7 @@ getResourceDataForPassthroughOperational: - $ref: 'components.yaml#/components/parameters/resourceIdentifierInQuery' - $ref: 'components.yaml#/components/parameters/acceptParamInHeader' - $ref: 'components.yaml#/components/parameters/optionsParamInQuery' + - $ref: 'components.yaml#/components/parameters/topicParamInQuery' responses: 200: description: OK @@ -60,6 +61,7 @@ resourceDataForPassthroughRunning: - $ref: 'components.yaml#/components/parameters/resourceIdentifierInQuery' - $ref: 'components.yaml#/components/parameters/acceptParamInHeader' - $ref: 'components.yaml#/components/parameters/optionsParamInQuery' + - $ref: 'components.yaml#/components/parameters/topicParamInQuery' responses: 200: description: OK 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 01b892218d..0201fad2b5 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 @@ -75,17 +75,20 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { * @param resourceIdentifier resource identifier * @param acceptParamInHeader accept header parameter * @param optionsParamInQuery options query parameter + * @param topicParamInQuery topic query parameter * @return {@code ResponseEntity} response from dmi plugin */ @Override public ResponseEntity<Object> getResourceDataOperationalForCmHandle(final String cmHandle, final @NotNull @Valid String resourceIdentifier, final String acceptParamInHeader, - final @Valid String optionsParamInQuery) { + final @Valid String optionsParamInQuery, + final @Valid String topicParamInQuery) { final Object responseObject = networkCmProxyDataService.getResourceDataOperationalForCmHandle(cmHandle, resourceIdentifier, acceptParamInHeader, - optionsParamInQuery); + optionsParamInQuery, + topicParamInQuery); return ResponseEntity.ok(responseObject); } @@ -96,17 +99,20 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { * @param resourceIdentifier resource identifier * @param acceptParamInHeader accept header parameter * @param optionsParamInQuery options query parameter + * @param topicParamInQuery topic query parameter * @return {@code ResponseEntity} response from dmi plugin */ @Override public ResponseEntity<Object> getResourceDataRunningForCmHandle(final String cmHandle, final @NotNull @Valid String resourceIdentifier, final String acceptParamInHeader, - final @Valid String optionsParamInQuery) { + final @Valid String optionsParamInQuery, + final @Valid String topicParamInQuery) { final Object responseObject = networkCmProxyDataService.getResourceDataPassThroughRunningForCmHandle(cmHandle, resourceIdentifier, acceptParamInHeader, - optionsParamInQuery); + optionsParamInQuery, + topicParamInQuery); return ResponseEntity.ok(responseObject); } diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.java index 5aaf1c31f0..2495f36426 100755 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.java +++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandler.java @@ -30,6 +30,7 @@ import org.onap.cps.ncmp.rest.controller.NetworkCmProxyController; import org.onap.cps.ncmp.rest.controller.NetworkCmProxyInventoryController; import org.onap.cps.ncmp.rest.model.ErrorMessage; import org.onap.cps.spi.exceptions.CpsException; +import org.onap.cps.spi.exceptions.DataNodeNotFoundException; import org.onap.cps.spi.exceptions.DataValidationException; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -69,6 +70,11 @@ public class NetworkCmProxyRestExceptionHandler { return buildErrorResponse(HttpStatus.BAD_REQUEST, exception); } + @ExceptionHandler({DataNodeNotFoundException.class}) + public static ResponseEntity<Object> handleNotFoundExceptions(final CpsException exception) { + return buildErrorResponse(HttpStatus.NOT_FOUND, exception); + } + private static ResponseEntity<Object> buildErrorResponse(final HttpStatus status, final Exception exception) { if (exception.getCause() != null || !(exception instanceof CpsException)) { log.error("Exception occurred", exception); 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 a506e6ae02..d5c3cd9f37 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 @@ -24,6 +24,7 @@ package org.onap.cps.ncmp.rest.controller import org.mapstruct.factory.Mappers import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle +import spock.lang.Shared import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.PATCH import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete @@ -69,7 +70,10 @@ class NetworkCmProxyControllerSpec extends Specification { def requestBody = '{"some-key":"some-value"}' - def 'Get Resource Data from pass-through operational.' () { + @Shared + def NO_TOPIC = null + + def 'Get Resource Data from pass-through operational.'() { given: 'resource data url' def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-operational" + "?resourceIdentifier=parent/child&options=(a=1,b=2)" @@ -83,12 +87,40 @@ class NetworkCmProxyControllerSpec extends Specification { 1 * mockNetworkCmProxyDataService.getResourceDataOperationalForCmHandle('testCmHandle', 'parent/child', 'application/json', - '(a=1,b=2)') + '(a=1,b=2)', + NO_TOPIC) + and: 'response status is Ok' + response.status == HttpStatus.OK.value() + } + + def 'Get Resource Data from pass-through operational with #scenario.'() { + given: 'resource data url' + def getUrl = "$ncmpBasePathV1/ch/testCmHandle/data/ds/ncmp-datastore:passthrough-operational" + + "?resourceIdentifier=parent/child&options=(a=1,b=2)${topicQueryParam}" + when: 'get data resource request is performed' + def response = mvc.perform( + get(getUrl) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON_VALUE) + ).andReturn().response + then: 'the NCMP data service is called with operational data for cm handle' + 1 * mockNetworkCmProxyDataService.getResourceDataOperationalForCmHandle('testCmHandle', + 'parent/child', + 'application/json', + '(a=1,b=2)', + expectedTopicName) and: 'response status is Ok' response.status == HttpStatus.OK.value() + where: 'the following parameters are used' + scenario | topicQueryParam || expectedTopicName + 'Url with valid topic' | "&topic=my-topic-name" || "my-topic-name" + 'No topic in url' | '' || NO_TOPIC + 'Null topic in url' | "&topic=null" || "null" + 'Empty topic in url' | "&topic=\"\"" || "\"\"" + 'Missing topic in url' | "&topic=" || "" } - def 'Get Resource Data from pass-through running with #scenario value in resource identifier param.' () { + 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" + "?resourceIdentifier=" + resourceIdentifier + "&options=(a=1,b=2)" @@ -96,7 +128,8 @@ class NetworkCmProxyControllerSpec extends Specification { mockNetworkCmProxyDataService.getResourceDataPassThroughRunningForCmHandle('testCmHandle', resourceIdentifier, 'application/json', - '(a=1,b=2)') >> '{valid-json}' + '(a=1,b=2)', + NO_TOPIC) >> '{valid-json}' when: 'get data resource request is performed' def response = mvc.perform( get(getUrl) diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy index 3c39a3307e..b642370154 100644 --- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy +++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/exceptions/NetworkCmProxyRestExceptionHandlerSpec.groovy @@ -47,6 +47,7 @@ import static org.onap.cps.ncmp.rest.exceptions.NetworkCmProxyRestExceptionHandl import static org.onap.cps.ncmp.rest.exceptions.NetworkCmProxyRestExceptionHandlerSpec.ApiType.NCMPINVENTORY import static org.springframework.http.HttpStatus.BAD_REQUEST import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR +import static org.springframework.http.HttpStatus.NOT_FOUND import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post @@ -75,40 +76,39 @@ class NetworkCmProxyRestExceptionHandlerSpec extends Specification { def dataNodeBaseEndpointNcmpInventory @Shared - def errorMessage = 'some error message' + def sampleErrorMessage = 'some error message' @Shared - def errorDetails = 'some error details' - @Shared - def dataNodeNotFoundErrorMessage = 'DataNode not found' + def sampleErrorDetails = 'some error details' def setup() { dataNodeBaseEndpointNcmp = "$basePathNcmp/v1" dataNodeBaseEndpointNcmpInventory = "$basePathNcmpInventory/v1" } - def 'Get request with generic #scenario exception returns correct HTTP Status.'() { + def 'Get request with generic #scenario exception returns correct HTTP Status with #scenario'() { when: 'an exception is thrown by the service' setupTestException(exception, NCMP) def response = performTestRequest(NCMP) then: 'an HTTP response is returned with correct message and details' assertTestResponse(response, expectedErrorCode, expectedErrorMessage, expectedErrorDetails) where: - scenario | exception || expectedErrorDetails | expectedErrorMessage | expectedErrorCode - 'CPS' | new CpsException(errorMessage, errorDetails) || errorDetails | errorMessage | INTERNAL_SERVER_ERROR - 'NCMP-server' | new ServerNcmpException(errorMessage, errorDetails) || null | errorMessage | INTERNAL_SERVER_ERROR - 'NCMP-client' | new DmiRequestException(errorMessage, errorDetails) || null | errorMessage | BAD_REQUEST - 'DataNode Validation' | new DataNodeNotFoundException(dataNodeNotFoundErrorMessage, errorDetails) || null | dataNodeNotFoundErrorMessage | BAD_REQUEST - 'other' | new IllegalStateException(errorMessage) || null | errorMessage | INTERNAL_SERVER_ERROR + scenario | exception || expectedErrorDetails | expectedErrorMessage | expectedErrorCode + 'CPS' | new CpsException(sampleErrorMessage, sampleErrorDetails) || sampleErrorDetails | sampleErrorMessage | INTERNAL_SERVER_ERROR + 'NCMP-server' | new ServerNcmpException(sampleErrorMessage, sampleErrorDetails) || null | sampleErrorMessage | INTERNAL_SERVER_ERROR + 'NCMP-client' | new DmiRequestException(sampleErrorMessage, sampleErrorDetails) || null | sampleErrorMessage | BAD_REQUEST + 'DataNode Validation' | new DataNodeNotFoundException('myDataspaceName', 'myAnchorName') || null | 'DataNode not found' | NOT_FOUND + 'other' | new IllegalStateException(sampleErrorMessage) || null | sampleErrorMessage | INTERNAL_SERVER_ERROR + 'Data Node Not Found' | new DataNodeNotFoundException('myDataspaceName', 'myAnchorName') || 'DataNode not found' | 'DataNode not found' | NOT_FOUND } def 'Post request with exception returns correct HTTP Status.'() { given: 'the service throws data validation exception' - def exception = new DataValidationException(errorMessage, errorDetails) + def exception = new DataValidationException(sampleErrorMessage, sampleErrorDetails) setupTestException(exception, NCMPINVENTORY) when: 'the HTTP request is made' def response = performTestRequest(NCMPINVENTORY) then: 'an HTTP response is returned with correct message and details' - assertTestResponse(response, BAD_REQUEST, errorMessage, errorDetails) + assertTestResponse(response, BAD_REQUEST, sampleErrorMessage, sampleErrorDetails) } def setupTestException(exception, apiType) { @@ -129,9 +129,9 @@ class NetworkCmProxyRestExceptionHandlerSpec extends Specification { static void assertTestResponse(response, expectedStatus , expectedErrorMessage , expectedErrorDetails) { assert response.status == expectedStatus.value() def content = new JsonSlurper().parseText(response.contentAsString) - assert content['status'] == expectedStatus.toString() - assert content['message'] == expectedErrorMessage - assert expectedErrorDetails == null || content['details'] == expectedErrorDetails + assert content['status'].toString().contains(expectedStatus.toString()) + assert content['message'].toString().contains(expectedErrorMessage) + assert expectedErrorDetails == null || content['details'].toString().contains(expectedErrorDetails) } enum ApiType { |