From e557338803286d8aaa0f877aa25d52d18735f309 Mon Sep 17 00:00:00 2001 From: DylanB95EST Date: Thu, 27 Jan 2022 17:12:52 +0000 Subject: Create Endpoint For Get Cm Handles By Name Create endpoint and implement logic for get cm handle details by cm handle name Issue-ID: CPS-817 Change-Id: I83bd2da9219d13fac715a08b19108028ca6f6751 Signed-off-by: DylanB95EST --- cps-ncmp-rest/docs/openapi/components.yaml | 23 +++++++++++++++--- cps-ncmp-rest/docs/openapi/ncmp.yml | 27 ++++++++++++++++++++++ cps-ncmp-rest/docs/openapi/openapi.yml | 5 +++- .../rest/controller/NetworkCmProxyController.java | 27 +++++++++++++++++++++- .../cps/ncmp/rest/controller/RestInputMapper.java | 15 +++++------- .../NetworkCmProxyRestExceptionHandler.java | 18 ++++----------- .../controller/NetworkCmProxyControllerSpec.groovy | 25 ++++++++++++++++++++ .../rest/controller/RestInputMapperSpec.groovy | 4 ++-- .../NetworkCmProxyRestExceptionHandlerSpec.groovy | 16 ++++++++----- 9 files changed, 124 insertions(+), 36 deletions(-) (limited to 'cps-ncmp-rest') diff --git a/cps-ncmp-rest/docs/openapi/components.yaml b/cps-ncmp-rest/docs/openapi/components.yaml index fd02b6e56..d82813b87 100644 --- a/cps-ncmp-rest/docs/openapi/components.yaml +++ b/cps-ncmp-rest/docs/openapi/components.yaml @@ -50,7 +50,7 @@ components: createdCmHandles: type: array items: - $ref: '#/components/schemas/RestCmHandle' + $ref: '#/components/schemas/RestInputCmHandle' updatedCmHandles: type: array example: @@ -64,14 +64,14 @@ components: update-my-property: updated-property delete-my-property: '~' items: - $ref: '#/components/schemas/RestCmHandle' + $ref: '#/components/schemas/RestInputCmHandle' removedCmHandles: type: array items: type: string example: [my-cm-handle1, my-cm-handle2, my-cm-handle3] - RestCmHandle: + RestInputCmHandle: required: - cmHandle type: object @@ -146,6 +146,23 @@ components: type: string example: my-module-revision + RestOutputCmHandle: + type: object + title: CM handle Details + properties: + cmHandle: + type: string + example: my-cm-handle1 + publicCmHandleProperties: + $ref: '#/components/schemas/CmHandlePublicProperties' + CmHandlePublicProperties: + type: array + items: + type: object + additionalProperties: + type: string + example: Book Type + examples: dataSampleRequest: summary: Sample request diff --git a/cps-ncmp-rest/docs/openapi/ncmp.yml b/cps-ncmp-rest/docs/openapi/ncmp.yml index 3a71aba80..a267fb491 100755 --- a/cps-ncmp-rest/docs/openapi/ncmp.yml +++ b/cps-ncmp-rest/docs/openapi/ncmp.yml @@ -262,3 +262,30 @@ executeCmHandleSearch: $ref: 'components.yaml#/components/responses/Forbidden' 500: $ref: 'components.yaml#/components/responses/InternalServerError' + +retrieveCmHandleDetailsById: + get: + description: Retrieve CM handle details and properties by cm handle id + tags: + - network-cm-proxy + summary: Retrieve CM handle details + operationId: retrieveCmHandleDetailsById + parameters: + - $ref: 'components.yaml#/components/parameters/cmHandleInPath' + responses: + 200: + description: OK + content: + application/json: + schema: + $ref: 'components.yaml#/components/schemas/RestOutputCmHandle' + 400: + $ref: 'components.yaml#/components/responses/BadRequest' + 401: + $ref: 'components.yaml#/components/responses/Unauthorized' + 403: + $ref: 'components.yaml#/components/responses/Forbidden' + 404: + $ref: 'components.yaml#/components/responses/NotFound' + 500: + $ref: 'components.yaml#/components/responses/InternalServerError' \ No newline at end of file diff --git a/cps-ncmp-rest/docs/openapi/openapi.yml b/cps-ncmp-rest/docs/openapi/openapi.yml index 838a0d08e..12a8318ef 100755 --- a/cps-ncmp-rest/docs/openapi/openapi.yml +++ b/cps-ncmp-rest/docs/openapi/openapi.yml @@ -36,4 +36,7 @@ paths: $ref: 'ncmp.yml#/fetchModuleReferencesByCmHandle' /v1/ch/searches: - $ref: 'ncmp.yml#/executeCmHandleSearch' \ No newline at end of file + $ref: 'ncmp.yml#/executeCmHandleSearch' + + /v1/ch/{cm-handle}: + $ref: 'ncmp.yml#/retrieveCmHandleDetailsById' \ No newline at end of file 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 419f6e926..86f4460ea 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 @@ -1,7 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2021 Pantheon.tech - * Modifications (C) 2021-2022 Nordix Foundation + * Modifications Copyright (C) 2021-2022 Nordix Foundation * Modification Copyright (C) 2021 highstreet technologies GmbH * Modifications (C) 2021 Bell Canada * ================================================================================ @@ -10,6 +10,7 @@ * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -38,15 +39,18 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.modelmapper.ModelMapper; import org.onap.cps.ncmp.api.NetworkCmProxyDataService; +import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle; import org.onap.cps.ncmp.rest.api.NetworkCmProxyApi; import org.onap.cps.ncmp.rest.model.CmHandleProperties; import org.onap.cps.ncmp.rest.model.CmHandleProperty; +import org.onap.cps.ncmp.rest.model.CmHandlePublicProperties; import org.onap.cps.ncmp.rest.model.CmHandles; import org.onap.cps.ncmp.rest.model.ConditionProperties; import org.onap.cps.ncmp.rest.model.Conditions; import org.onap.cps.ncmp.rest.model.ModuleNameAsJsonObject; import org.onap.cps.ncmp.rest.model.ModuleNamesAsJsonArray; import org.onap.cps.ncmp.rest.model.ModuleReference; +import org.onap.cps.ncmp.rest.model.RestOutputCmHandle; import org.onap.cps.utils.JsonObjectMapper; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -185,6 +189,18 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { return ResponseEntity.ok(cmHandles); } + /** + * Search for Cm Handle and Properties by Name. + * @param cmHandleId cm-handle identifier + * @return cm handle and its properties + */ + @Override + public ResponseEntity retrieveCmHandleDetailsById(final String cmHandleId) { + final NcmpServiceCmHandle ncmpServiceCmHandle = networkCmProxyDataService.getNcmpServiceCmHandle(cmHandleId); + final RestOutputCmHandle restOutputCmHandle = toRestOutputCmHandle(ncmpServiceCmHandle); + return ResponseEntity.ok(restOutputCmHandle); + } + /** * Return module references for a cm handle. * @@ -233,4 +249,13 @@ public class NetworkCmProxyController implements NetworkCmProxyApi { } return cmHandleProperties; } + + private RestOutputCmHandle toRestOutputCmHandle(final NcmpServiceCmHandle ncmpServiceCmHandle) { + final RestOutputCmHandle restOutputCmHandle = new RestOutputCmHandle(); + final CmHandlePublicProperties cmHandlePublicProperties = new CmHandlePublicProperties(); + restOutputCmHandle.setCmHandle(ncmpServiceCmHandle.getCmHandleID()); + cmHandlePublicProperties.add(ncmpServiceCmHandle.getPublicProperties()); + restOutputCmHandle.setPublicCmHandleProperties(cmHandlePublicProperties); + return restOutputCmHandle; + } } diff --git a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/RestInputMapper.java b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/RestInputMapper.java index d38204cf1..a1d046ece 100644 --- a/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/RestInputMapper.java +++ b/cps-ncmp-rest/src/main/java/org/onap/cps/ncmp/rest/controller/RestInputMapper.java @@ -22,13 +22,12 @@ package org.onap.cps.ncmp.rest.controller; import org.mapstruct.Mapper; import org.mapstruct.Mapping; -import org.mapstruct.Mappings; import org.mapstruct.NullValueMappingStrategy; import org.mapstruct.NullValuePropertyMappingStrategy; -import org.onap.cps.ncmp.api.models.CmHandle; import org.onap.cps.ncmp.api.models.DmiPluginRegistration; -import org.onap.cps.ncmp.rest.model.RestCmHandle; +import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle; import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration; +import org.onap.cps.ncmp.rest.model.RestInputCmHandle; @Mapper(componentModel = "spring", nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT, nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) @@ -36,11 +35,9 @@ public interface RestInputMapper { DmiPluginRegistration toDmiPluginRegistration(final RestDmiPluginRegistration restDmiPluginRegistration); - @Mappings({ - @Mapping(source = "cmHandle", target = "cmHandleID"), - @Mapping(source = "cmHandleProperties", target = "dmiProperties"), - @Mapping(source = "publicCmHandleProperties", target = "publicProperties") - }) - CmHandle toCmHandle(final RestCmHandle restCmHandle); + @Mapping(source = "cmHandle", target = "cmHandleID") + @Mapping(source = "cmHandleProperties", target = "dmiProperties") + @Mapping(source = "publicCmHandleProperties", target = "publicProperties") + NcmpServiceCmHandle toNcmpServiceCmHandle(final RestInputCmHandle restInputCmHandle); } 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 fd01096e1..5aaf1c31f 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 @@ -59,23 +59,13 @@ public class NetworkCmProxyRestExceptionHandler { return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception); } - @ExceptionHandler({CpsException.class}) - public static ResponseEntity handleAnyOtherCpsExceptions(final CpsException exception) { + @ExceptionHandler({CpsException.class, ServerNcmpException.class}) + public static ResponseEntity handleAnyOtherCpsExceptions(final Exception exception) { return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception); } - @ExceptionHandler({ServerNcmpException.class}) - public static ResponseEntity handleServerNcmpExceptions(final ServerNcmpException exception) { - return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception); - } - - @ExceptionHandler({DmiRequestException.class}) - public static ResponseEntity handleDmiRequestExceptions(final DmiRequestException exception) { - return buildErrorResponse(HttpStatus.BAD_REQUEST, exception); - } - - @ExceptionHandler({DataValidationException.class, HttpMessageNotReadableException.class}) - public static ResponseEntity handleDataValidatedExceptions(final Exception exception) { + @ExceptionHandler({DmiRequestException.class, DataValidationException.class, HttpMessageNotReadableException.class}) + public static ResponseEntity handleDmiRequestExceptions(final Exception exception) { return buildErrorResponse(HttpStatus.BAD_REQUEST, 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 0c8b2227d..c99771443 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 @@ -22,6 +22,9 @@ package org.onap.cps.ncmp.rest.controller + +import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle + import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.PATCH import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get @@ -180,6 +183,28 @@ class NetworkCmProxyControllerSpec extends Specification { response.contentAsString == '{"cmHandles":[{"cmHandleId":"some-cmhandle-id1"},{"cmHandleId":"some-cmhandle-id2"}]}' } + def 'Get Cm Handle details by Cm Handle id.' () { + given: 'an endpoint and a cm handle' + def cmHandleDetailsEndpoint = "$ncmpBasePathV1/ch/Some-Cm-Handle" + and: 'an existing ncmp service cm handle' + def cmHandleId = 'Some-Cm-Handle' + def dmiProperties = [ prop:'some DMI property' ] + def publicProperties = [ "public prop":'some public property' ] + def ncmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleID: cmHandleId, dmiProperties: dmiProperties, publicProperties: publicProperties) + and: 'the service method is invoked with the cm handle id' + 1 * mockNetworkCmProxyDataService.getNcmpServiceCmHandle('Some-Cm-Handle') >> ncmpServiceCmHandle + when: 'the cm handle details api is invoked' + def response = mvc.perform(get(cmHandleDetailsEndpoint)).andReturn().response + then: 'the correct response is returned' + response.status == HttpStatus.OK.value() + and: 'the response returns public properties and the correct properties' + response.contentAsString.contains('publicCmHandleProperties') + response.contentAsString.contains('public prop') + response.contentAsString.contains('some public property') + and: 'the content does not contain dmi properties' + !response.contentAsString.contains("some DMI property") + } + def 'Call execute cm handle searches with unrecognized condition name.'() { given: 'an endpoint and json data' def searchesEndpoint = "$ncmpBasePathV1/ch/searches" diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/RestInputMapperSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/RestInputMapperSpec.groovy index c48a8ed36..ed938810c 100644 --- a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/RestInputMapperSpec.groovy +++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/controller/RestInputMapperSpec.groovy @@ -21,8 +21,8 @@ package org.onap.cps.ncmp.rest.controller import org.mapstruct.factory.Mappers -import org.onap.cps.ncmp.rest.model.RestCmHandle import org.onap.cps.ncmp.rest.model.RestDmiPluginRegistration +import org.onap.cps.ncmp.rest.model.RestInputCmHandle import spock.lang.Specification class RestInputMapperSpec extends Specification { @@ -31,7 +31,7 @@ class RestInputMapperSpec extends Specification { def 'Convert a created REST CM Handle Input to an NCMP Service CM Handle with #scenario'() { given: 'a rest cm handle input' - def inputRestCmHandle = new RestCmHandle(cmHandle : 'example-id', cmHandleProperties: dmiProperties, + def inputRestCmHandle = new RestInputCmHandle(cmHandle : 'example-id', cmHandleProperties: dmiProperties, publicCmHandleProperties: publicProperties) def restDmiPluginRegistration = new RestDmiPluginRegistration( createdCmHandles: [inputRestCmHandle]) 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 306f546f3..8004328bc 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 @@ -29,6 +29,7 @@ import org.onap.cps.ncmp.api.impl.exception.DmiRequestException import org.onap.cps.ncmp.api.impl.exception.ServerNcmpException import org.onap.cps.ncmp.rest.controller.RestInputMapper import org.onap.cps.spi.exceptions.CpsException +import org.onap.cps.spi.exceptions.DataNodeNotFoundException import org.onap.cps.spi.exceptions.DataValidationException import org.onap.cps.utils.JsonObjectMapper import org.spockframework.spring.SpringBean @@ -78,6 +79,8 @@ class NetworkCmProxyRestExceptionHandlerSpec extends Specification { def errorMessage = 'some error message' @Shared def errorDetails = 'some error details' + @Shared + def dataNodeNotFoundErrorMessage = 'DataNode not found' def setup() { dataNodeBaseEndpointNcmp = "$basePathNcmp/v1" @@ -89,13 +92,14 @@ class NetworkCmProxyRestExceptionHandlerSpec extends Specification { setupTestException(exception, NCMP) def response = performTestRequest(NCMP) then: 'an HTTP response is returned with correct message and details' - assertTestResponse(response, expectedErrorCode, errorMessage, expectedErrorDetails) + assertTestResponse(response, expectedErrorCode, expectedErrorMessage, expectedErrorDetails) where: - scenario | exception || expectedErrorDetails | expectedErrorCode - 'CPS' | new CpsException(errorMessage, errorDetails) || errorDetails | INTERNAL_SERVER_ERROR - 'NCMP-server' | new ServerNcmpException(errorMessage, errorDetails) || null | INTERNAL_SERVER_ERROR - 'NCMP-client' | new DmiRequestException(errorMessage, errorDetails) || null | BAD_REQUEST - 'other' | new IllegalStateException(errorMessage) || null | INTERNAL_SERVER_ERROR + 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 } def 'Post request with exception returns correct HTTP Status.'() { -- cgit 1.2.3-korg