From e9ed581de0a6090c513e6fca0052b69396cb3cc8 Mon Sep 17 00:00:00 2001 From: kissand Date: Thu, 12 May 2022 15:59:18 +0200 Subject: Merge 2 'query' end points in NCMP - merge two endpoint for a same backend - use xPath query instead of sql query - modify searches endpoint to return a cmHandle object with all public properties - handle old (deprecated) queries - handle public property queries - create useful examples - use more verbose error messages - simplify openapi yamls - create new query service - change second endpoint name to a better matched name - modify legacy tests with new requirements - create new tests for the new scenarios Issue-ID: CPS-1016 Change-Id: I7476e9dbd510ec93b5b48ce85d477ecb2dadffff Signed-off-by: kissand --- .../controller/NetworkCmProxyControllerSpec.groovy | 35 ++++++++++---- .../NetworkCmProxyRestExceptionHandlerSpec.groovy | 5 +- .../ncmp/rest/util/DeprecationHelperSpec.groovy | 54 ++++++++++++++++++++++ 3 files changed, 84 insertions(+), 10 deletions(-) create mode 100644 cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util/DeprecationHelperSpec.groovy (limited to 'cps-ncmp-rest/src/test') 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 60ea736d7..036928fe3 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 @@ -29,6 +29,7 @@ import org.onap.cps.ncmp.api.inventory.CompositeState import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle import org.onap.cps.ncmp.rest.mapper.RestOutputCmHandleStateMapper import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor +import org.onap.cps.ncmp.rest.util.DeprecationHelper import spock.lang.Shared import java.time.OffsetDateTime @@ -86,6 +87,9 @@ class NetworkCmProxyControllerSpec extends Specification { @SpringBean CpsNcmpTaskExecutor spiedCpsTaskExecutor = Spy() + @SpringBean + DeprecationHelper stubbedDeprecationHelper = Stub() + @Value('${rest.api.ncmp-base-path}/v1') def ncmpBasePathV1 @@ -239,8 +243,14 @@ class NetworkCmProxyControllerSpec extends Specification { given: 'an endpoint and json data' def searchesEndpoint = "$ncmpBasePathV1/ch/searches" String jsonString = TestUtils.getResourceFileContent('cmhandle-search.json') - and: 'the service method is invoked with module names and returns two cm handle ids' - mockNetworkCmProxyDataService.executeCmHandleHasAllModulesSearch(['module1', 'module2']) >> ['some-cmhandle-id1', 'some-cmhandle-id2'] + and: 'the service method is invoked with module names and returns two cm handles' + def cmHandle1 = new NcmpServiceCmHandle() + cmHandle1.cmHandleId = 'some-cmhandle-id1' + cmHandle1.publicProperties = [color:'yellow'] + def cmHandle2 = new NcmpServiceCmHandle() + cmHandle2.cmHandleId = 'some-cmhandle-id2' + cmHandle2.publicProperties = [color:'green'] + mockNetworkCmProxyDataService.executeCmHandleSearch(_) >> [cmHandle1, cmHandle2] when: 'the searches api is invoked' def response = mvc.perform(post(searchesEndpoint) .contentType(MediaType.APPLICATION_JSON) @@ -248,7 +258,7 @@ class NetworkCmProxyControllerSpec extends Specification { then: 'response status returns OK' response.status == HttpStatus.OK.value() and: 'the expected response content is returned' - response.contentAsString == '{"cmHandles":[{"cmHandleId":"some-cmhandle-id1"},{"cmHandleId":"some-cmhandle-id2"}]}' + response.contentAsString == '[{"cmHandle":"some-cmhandle-id1","publicCmHandleProperties":[{"color":"yellow"}],"state":null},{"cmHandle":"some-cmhandle-id2","publicCmHandleProperties":[{"color":"green"}],"state":null}]' } def 'Get Cm Handle details by Cm Handle id.'() { @@ -290,31 +300,38 @@ class NetworkCmProxyControllerSpec extends Specification { given: 'an endpoint and json data' def searchesEndpoint = "$ncmpBasePathV1/ch/searches" String jsonString = TestUtils.getResourceFileContent('invalid-cmhandle-search.json') + and: 'the service method is invoked with module names and returns two cm handles' + def cmHandel1 = new NcmpServiceCmHandle() + cmHandel1.cmHandleId = 'some-cmhandle-id1' + cmHandel1.publicProperties = [color:'yellow'] + def cmHandel2 = new NcmpServiceCmHandle() + cmHandel2.cmHandleId = 'some-cmhandle-id2' + cmHandel2.publicProperties = [color:'green'] + mockNetworkCmProxyDataService.executeCmHandleSearch(_) >> [cmHandel1, cmHandel2] when: 'the searches api is invoked' def response = mvc.perform(post(searchesEndpoint) .contentType(MediaType.APPLICATION_JSON) .content(jsonString)).andReturn().response then: 'an empty cm handle identifier is returned' - response.contentAsString == '{"cmHandles":[]}' + response.contentAsString == '[{"cmHandle":"some-cmhandle-id1","publicCmHandleProperties":[{"color":"yellow"}],"state":null},{"cmHandle":"some-cmhandle-id2","publicCmHandleProperties":[{"color":"green"}],"state":null}]' } def 'Query for cm handles matching query parameters'() { given: 'an endpoint and json data' - def searchesEndpoint = "$ncmpBasePathV1/data/ch/searches" - String jsonString = '{"publicCmHandleProperties": {"name": "Contact", "value": "newemailforstore@bookstore.com"}}' + def searchesEndpoint = "$ncmpBasePathV1/ch/id-searches" and: 'the service method is invoked with module names and returns cm handle ids' - 1 * mockNetworkCmProxyDataService.queryCmHandles(_) >> ['some-cmhandle-id1', 'some-cmhandle-id2'] + 1 * mockNetworkCmProxyDataService.executeCmHandleIdSearch(_) >> ['some-cmhandle-id1', 'some-cmhandle-id2'] when: 'the searches api is invoked' def response = mvc.perform(post(searchesEndpoint) .contentType(MediaType.APPLICATION_JSON) - .content(jsonString)).andReturn().response + .content('{}')).andReturn().response then: 'cm handle ids are returned' response.contentAsString == '["some-cmhandle-id1","some-cmhandle-id2"]' } def 'Query for cm handles with invalid request payload'() { when: 'the searches api is invoked' - def searchesEndpoint = "$ncmpBasePathV1/data/ch/searches" + def searchesEndpoint = "$ncmpBasePathV1/ch/id-searches" def invalidInputData = '{invalidJson}' def response = mvc.perform(post(searchesEndpoint) .contentType(MediaType.APPLICATION_JSON) 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 45ed3d307..1563c75b3 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 @@ -31,6 +31,7 @@ import org.onap.cps.ncmp.api.impl.exception.ServerNcmpException import org.onap.cps.ncmp.rest.controller.NcmpRestInputMapper import org.onap.cps.ncmp.rest.mapper.RestOutputCmHandleStateMapper import org.onap.cps.ncmp.rest.executor.CpsNcmpTaskExecutor +import org.onap.cps.ncmp.rest.util.DeprecationHelper import org.onap.cps.spi.exceptions.CpsException import org.onap.cps.spi.exceptions.DataNodeNotFoundException import org.onap.cps.spi.exceptions.DataValidationException @@ -47,7 +48,6 @@ import spock.lang.Specification import static org.onap.cps.ncmp.rest.exceptions.NetworkCmProxyRestExceptionHandlerSpec.ApiType.NCMP import static org.onap.cps.ncmp.rest.exceptions.NetworkCmProxyRestExceptionHandlerSpec.ApiType.NCMPINVENTORY -import static org.springframework.http.HttpStatus.BAD_GATEWAY 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 @@ -75,6 +75,9 @@ class NetworkCmProxyRestExceptionHandlerSpec extends Specification { @SpringBean CpsNcmpTaskExecutor stubbedCpsTaskExecutor = Stub() + @SpringBean + DeprecationHelper stubbedDeprecationHelper = Stub() + @Value('${rest.api.ncmp-base-path}') def basePathNcmp diff --git a/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util/DeprecationHelperSpec.groovy b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util/DeprecationHelperSpec.groovy new file mode 100644 index 000000000..8c212d353 --- /dev/null +++ b/cps-ncmp-rest/src/test/groovy/org/onap/cps/ncmp/rest/util/DeprecationHelperSpec.groovy @@ -0,0 +1,54 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.rest.util + +import com.fasterxml.jackson.databind.ObjectMapper +import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters +import org.onap.cps.ncmp.api.models.ConditionApiProperties +import org.onap.cps.ncmp.rest.model.CmHandleQueryParameters +import org.onap.cps.ncmp.rest.model.ConditionProperties +import org.onap.cps.ncmp.rest.model.ModuleNameAsJsonObject +import org.onap.cps.ncmp.rest.model.OldConditionProperties +import org.onap.cps.utils.JsonObjectMapper +import spock.lang.Specification + +class DeprecationHelperSpec extends Specification { + + DeprecationHelper deprecationHelper = new DeprecationHelper(new JsonObjectMapper(new ObjectMapper())) + + def 'Map deprecated condition properties - #scenario.'() { + given: 'a deprecated condition properties' + def cmHandleQueryParameters = new CmHandleQueryParameters() + cmHandleQueryParameters.conditions = oldConditionPropertiesArray + cmHandleQueryParameters.cmHandleQueryParameters = cmHandleQueryParametersArray + when: 'converted into the new format' + def result = deprecationHelper.mapOldConditionProperties(cmHandleQueryParameters) + then: 'result is the expected' + assert result == new CmHandleQueryApiParameters(cmHandleQueryParameters: expectedCmHandleQueryApiParametersArray) + where: + scenario | oldConditionPropertiesArray | cmHandleQueryParametersArray || expectedCmHandleQueryApiParametersArray + 'mapping old query' | [new OldConditionProperties(name: 'hasAllModule', conditionParameters: [new ModuleNameAsJsonObject(moduleName: 'module-1')])] | [] || [new ConditionApiProperties(conditionName: 'hasAllModule', conditionParameters: [[moduleName:'module-1']])] + 'old condition is null' | null | [] || [] + 'old condition parameters is null' | [new OldConditionProperties(name: 'hasAllModule', conditionParameters: null)] | [] || [] + 'old condition name is null' | [new OldConditionProperties(name: null, conditionParameters: [new ModuleNameAsJsonObject(moduleName: 'module-1')])] | [] || [] + 'new query parameters are filled' | [new OldConditionProperties(name: 'hasAllModule', conditionParameters: [new ModuleNameAsJsonObject(moduleName: 'module-1')])] | [new ConditionProperties(conditionName: 'hasAllModule', conditionParameters: [[moduleName:'module-2']])] || [new ConditionApiProperties(conditionName: 'hasAllModule', conditionParameters: [[moduleName:'module-2']])] + } +} -- cgit 1.2.3-korg