From 1f2e66e720678f00682e6429aab7fa62251baf29 Mon Sep 17 00:00:00 2001 From: sourabh_sourabh Date: Wed, 16 Feb 2022 21:53:41 +0530 Subject: Async: NCMP Rest impl. including Request ID generation - Based on topic api can be sync or async - RequestId is generated using UUID - Used UriComponentBuilder to populate dmi service url. - New test cases are introduced to validate service url generation. Issue-ID: CPS-828 Signed-off-by: sourabh_sourabh Change-Id: I2696d5cb012d9274b0c1265f16aa9b2369657f05 --- .../impl/NetworkCmProxyDataServiceImplSpec.groovy | 159 ++++++++++++++++----- .../impl/operations/DmiDataOperationsSpec.groovy | 45 +++--- .../impl/operations/DmiModelOperationsSpec.groovy | 13 +- .../impl/operations/DmiOperationsBaseSpec.groovy | 5 + .../ncmp/api/utils/DmiServiceUrlBuilderSpec.groovy | 79 ++++++++++ .../src/test/resources/application.yml | 4 +- 6 files changed, 244 insertions(+), 61 deletions(-) create mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/utils/DmiServiceUrlBuilderSpec.groovy (limited to 'cps-ncmp-service/src/test') diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy index b2a3d77cac..e6d18d9156 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy @@ -24,6 +24,7 @@ package org.onap.cps.ncmp.api.impl import org.onap.cps.ncmp.api.impl.operations.YangModelCmHandleRetriever import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle +import spock.lang.Shared import static org.onap.cps.ncmp.api.impl.operations.DmiOperations.DataStoreEnum.PASSTHROUGH_OPERATIONAL import static org.onap.cps.ncmp.api.impl.operations.DmiOperations.DataStoreEnum.PASSTHROUGH_RUNNING @@ -56,6 +57,10 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { def mockDmiDataOperations = Mock(DmiDataOperations) def nullNetworkCmProxyDataServicePropertyHandler = null def mockYangModelCmHandleRetriever = Mock(YangModelCmHandleRetriever) + def NO_TOPIC = null + def NO_REQUEST_ID = null + @Shared + def OPTIONS_PARAM = '(a=1,b=2)' def objectUnderTest = new NetworkCmProxyDataServiceImpl(mockCpsDataService, spiedJsonObjectMapper, mockDmiDataOperations, mockDmiModelOperations, mockCpsModuleService, mockCpsAdminService, nullNetworkCmProxyDataServicePropertyHandler, mockYangModelCmHandleRetriever) @@ -64,7 +69,6 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { def dataNode = new DataNode(leaves: ['dmi-service-name': 'testDmiService']) - def 'Write resource data for pass-through running from DMI using POST #scenario cm handle properties.'() { given: 'cpsDataService returns valid datanode' mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', @@ -104,18 +108,21 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode and: 'get resource data from DMI is called' mockDmiDataOperations.getResourceDataFromDmi( - 'testCmHandle', - 'testResourceId', - '(a=1,b=2)', - 'testAcceptParam' , - PASSTHROUGH_OPERATIONAL) >> new ResponseEntity<>('result-json', HttpStatus.OK) + 'testCmHandle', + 'testResourceId', + OPTIONS_PARAM, + 'testAcceptParam', + PASSTHROUGH_OPERATIONAL, + NO_REQUEST_ID, + NO_TOPIC) >> new ResponseEntity<>('dmi-response', HttpStatus.OK) when: 'get resource data operational for cm-handle is called' def response = objectUnderTest.getResourceDataOperationalForCmHandle('testCmHandle', - 'testResourceId', - 'testAcceptParam', - '(a=1,b=2)') + 'testResourceId', + 'testAcceptParam', + OPTIONS_PARAM, + NO_TOPIC) then: 'DMI returns a json response' - response == 'result-json' + response == 'dmi-response' } def 'Get resource data for pass-through operational from DMI with Json Processing Exception.'() { @@ -129,9 +136,10 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { >> new ResponseEntity<>('NOK-json', HttpStatus.NOT_FOUND) when: 'get resource data is called' objectUnderTest.getResourceDataOperationalForCmHandle('testCmHandle', - 'testResourceId', - 'testAcceptParam', - '(a=1,b=2)') + 'testResourceId', + 'testAcceptParam', + OPTIONS_PARAM, + NO_TOPIC) then: 'exception is thrown with the expected details' def exceptionThrown = thrown(ServerNcmpException.class) exceptionThrown.details == 'DMI status code: 404, DMI response body: NOK-json' @@ -143,16 +151,19 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode and: 'DMI returns NOK response' mockDmiDataOperations.getResourceDataFromDmi('testCmHandle', - 'testResourceId', - '(a=1,b=2)', - 'testAcceptParam', - PASSTHROUGH_OPERATIONAL) - >> new ResponseEntity<>('NOK-json', HttpStatus.NOT_FOUND) + 'testResourceId', + OPTIONS_PARAM, + 'testAcceptParam', + PASSTHROUGH_OPERATIONAL, + NO_REQUEST_ID, + NO_TOPIC) + >> new ResponseEntity<>('NOK-json', HttpStatus.NOT_FOUND) when: 'get resource data is called' objectUnderTest.getResourceDataOperationalForCmHandle('testCmHandle', - 'testResourceId', - 'testAcceptParam', - '(a=1,b=2)') + 'testResourceId', + 'testAcceptParam', + OPTIONS_PARAM, + NO_TOPIC) then: 'exception is thrown' def exceptionThrown = thrown(ServerNcmpException.class) and: 'details contains the original response' @@ -165,17 +176,20 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode and: 'DMI returns valid response and data' mockDmiDataOperations.getResourceDataFromDmi('testCmHandle', - 'testResourceId', - '(a=1,b=2)', - 'testAcceptParam', - PASSTHROUGH_RUNNING) >> new ResponseEntity<>('{result-json}', HttpStatus.OK) + 'testResourceId', + OPTIONS_PARAM, + 'testAcceptParam', + PASSTHROUGH_RUNNING, + NO_REQUEST_ID, + NO_TOPIC) >> new ResponseEntity<>('{dmi-response}', HttpStatus.OK) when: 'get resource data is called' def response = objectUnderTest.getResourceDataPassThroughRunningForCmHandle('testCmHandle', - 'testResourceId', - 'testAcceptParam', - '(a=1,b=2)') + 'testResourceId', + 'testAcceptParam', + OPTIONS_PARAM, + NO_TOPIC) then: 'get resource data returns expected response' - response == '{result-json}' + response == '{dmi-response}' } def 'Get resource data for pass-through running from DMI return NOK response.'() { @@ -184,22 +198,91 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode and: 'DMI returns NOK response' mockDmiDataOperations.getResourceDataFromDmi('testCmHandle', - 'testResourceId', - '(a=1,b=2)', - 'testAcceptParam', - PASSTHROUGH_RUNNING) - >> new ResponseEntity<>('NOK-json', HttpStatus.NOT_FOUND) + 'testResourceId', + OPTIONS_PARAM, + 'testAcceptParam', + PASSTHROUGH_RUNNING, + NO_REQUEST_ID, + NO_TOPIC) + >> new ResponseEntity<>('NOK-json', HttpStatus.NOT_FOUND) when: 'get resource data is called' objectUnderTest.getResourceDataPassThroughRunningForCmHandle('testCmHandle', - 'testResourceId', - 'testAcceptParam', - '(a=1,b=2)') + 'testResourceId', + 'testAcceptParam', + OPTIONS_PARAM, + NO_TOPIC) then: 'exception is thrown' def exceptionThrown = thrown(ServerNcmpException.class) and: 'details contains the original response' exceptionThrown.details.contains('NOK-json') } + def 'Get resource data for operational from DMI with empty topic sync request.'() { + given: 'cps data service returns valid data node' + mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', + cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode + and: 'dmi data operation returns valid response and data' + mockDmiDataOperations.getResourceDataFromDmi(_, _, _, _, _, NO_REQUEST_ID, NO_TOPIC) + >> new ResponseEntity<>('{dmi-response}', HttpStatus.OK) + when: 'get resource data is called data operational with blank topic' + def responseData = objectUnderTest.getResourceDataOperationalForCmHandle('', '', + '', '', emptyTopic) + then: '(synchronous) the dmi response is expected' + assert responseData == '{dmi-response}' + where: 'the following parameters are used' + scenario | emptyTopic + 'No topic in url' | '' + 'Null topic in url' | null + 'Empty topic in url' | '\"\"' + 'Blank topic in url' | ' ' + } + + def 'Get resource data for data operational from DMI with valid topic i.e. async request.'() { + given: 'cps data service returns valid data node' + mockCpsDataService.getDataNode(*_) >> dataNode + and: 'dmi data operation returns valid response and data' + mockDmiDataOperations.getResourceDataFromDmi(_, _, _, _, _, _, 'my-topic-name') + >> new ResponseEntity<>('{dmi-response}', HttpStatus.OK) + when: 'get resource data is called for data operational with valid topic' + def responseData = objectUnderTest.getResourceDataOperationalForCmHandle('', '', '', '', 'my-topic-name') + then: 'non empty request id is generated' + assert responseData.body.requestId.length() > 0 + } + + def 'Get resource data for pass through running from DMI with valid topic async request.'() { + given: 'cps data service returns valid data node' + mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', + cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode + and: 'dmi data operation returns valid response and data' + mockDmiDataOperations.getResourceDataFromDmi(_, _, _, _, _, _, 'my-topic-name') + >> new ResponseEntity<>('{dmi-response}', HttpStatus.OK) + when: 'get resource data is called for data operational with valid topic' + def responseData = objectUnderTest.getResourceDataPassThroughRunningForCmHandle('', + '', '', OPTIONS_PARAM, 'my-topic-name') + then: 'non empty request id is generated' + assert responseData.body.requestId.length() > 0 + } + + def 'Get resource data for pass through running from DMI sync request where #scenario.'() { + given: 'cps data service returns valid data node' + mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', + cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode + and: 'dmi data operation returns valid response and data' + mockDmiDataOperations.getResourceDataFromDmi(_, _, _, _, _, NO_REQUEST_ID, NO_TOPIC) + >> new ResponseEntity<>('{dmi-response}', HttpStatus.OK) + when: 'get resource data is called for data operational with valid topic' + def responseData = objectUnderTest.getResourceDataPassThroughRunningForCmHandle('', + '', '', '', emptyTopic) + then: '(synchronous) the dmi response is expected' + assert responseData == '{dmi-response}' + where: 'the following parameters are used' + scenario | emptyTopic + 'No topic in url' | '' + 'Null topic in url' | null + 'Empty topic in url' | '\"\"' + 'Blank topic in url' | ' ' + } + def 'Getting Yang Resources.'() { when: 'yang resources is called' objectUnderTest.getYangResourcesModuleReferences('some cm handle') @@ -255,7 +338,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { givenOperation, '{some-json}', 'application/json') - then: 'an exception is thrown with the expected error message detailsd with correct operation' + then: 'an exception is thrown with the expected error message details with correct operation' def exceptionThrown = thrown(ServerNcmpException.class) exceptionThrown.getMessage().contains(expectedResponseMessage) where: diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy index e585825ca3..3df862ac5c 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiDataOperationsSpec.groovy @@ -22,12 +22,15 @@ package org.onap.cps.ncmp.api.impl.operations import com.fasterxml.jackson.databind.ObjectMapper import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration +import org.onap.cps.ncmp.api.impl.utils.DmiServiceUrlBuilder import org.onap.cps.utils.JsonObjectMapper import org.spockframework.spring.SpringBean import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.http.ResponseEntity import org.springframework.test.context.ContextConfiguration +import org.springframework.util.MultiValueMap +import spock.lang.Shared import static org.onap.cps.ncmp.api.impl.operations.DmiOperations.DataStoreEnum.PASSTHROUGH_OPERATIONAL import static org.onap.cps.ncmp.api.impl.operations.DmiOperations.DataStoreEnum.PASSTHROUGH_RUNNING @@ -40,43 +43,54 @@ import org.springframework.http.HttpStatus class DmiDataOperationsSpec extends DmiOperationsBaseSpec { @SpringBean - JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper()) + DmiServiceUrlBuilder dmiServiceUrlBuilder = Mock() + def dmiServiceBaseUrl = "${dmiServiceName}/dmi/v1/ch/${cmHandleId}/data/ds/ncmp-datastore:" + def NO_TOPIC = null + def NO_REQUEST_ID = null + @Shared + def OPTIONS_PARAM = '(a=1,b=2)' + + @SpringBean + JsonObjectMapper spiedJsonObjectMapper = Spy(new JsonObjectMapper(new ObjectMapper())) @Autowired DmiDataOperations objectUnderTest - def 'call get resource data for #expectedDatastoreInUrl from DMI #scenario.'() { + def 'call get resource data for #expectedDatastoreInUrl from DMI without topic #scenario.'() { given: 'a cm handle for #cmHandleId' mockYangModelCmHandleRetrieval(dmiProperties) and: 'a positive response from DMI service when it is called with the expected parameters' def responseFromDmi = new ResponseEntity(HttpStatus.OK) - mockDmiRestClient.postOperationWithJsonData( - "${dmiServiceName}/dmi/v1/ch/${cmHandleId}/data/ds/ncmp-datastore:${expectedDatastoreInUrl}?resourceIdentifier=${resourceIdentifier}${expectedOptionsInUrl}", - expectedJson, [Accept:['sample accept header']]) >> responseFromDmi + def expectedUrl = dmiServiceBaseUrl + "${expectedDatastoreInUrl}?resourceIdentifier=${resourceIdentifier}${expectedOptionsInUrl}" + mockDmiRestClient.postOperationWithJsonData(expectedUrl, + expectedJson, [Accept: ['sample accept header']]) >> responseFromDmi + dmiServiceUrlBuilder.getDmiDatastoreUrl(_, _) >> expectedUrl when: 'get resource data is invoked' - def result = objectUnderTest.getResourceDataFromDmi(cmHandleId,resourceIdentifier, options,'sample accept header', dataStore) + def result = objectUnderTest.getResourceDataFromDmi(cmHandleId, resourceIdentifier, + options, 'sample accept header', dataStore, NO_REQUEST_ID, NO_TOPIC) then: 'the result is the response from the DMI service' assert result == responseFromDmi where: 'the following parameters are used' - scenario | dmiProperties | dataStore | options || expectedJson | expectedDatastoreInUrl | expectedOptionsInUrl - 'without properties' | [] | PASSTHROUGH_OPERATIONAL | '(a=1,b=2)' || '{"operation":"read","cmHandleProperties":{}}' | 'passthrough-operational' | '&options=(a=1,b=2)' - 'with properties' | [yangModelCmHandleProperty] | PASSTHROUGH_OPERATIONAL | '(a=1,b=2)' || '{"operation":"read","cmHandleProperties":{"prop1":"val1"}}' | 'passthrough-operational' | '&options=(a=1,b=2)' - 'null options' | [yangModelCmHandleProperty] | PASSTHROUGH_OPERATIONAL | null || '{"operation":"read","cmHandleProperties":{"prop1":"val1"}}' | 'passthrough-operational' | '' - 'empty options' | [yangModelCmHandleProperty] | PASSTHROUGH_OPERATIONAL | '' || '{"operation":"read","cmHandleProperties":{"prop1":"val1"}}' | 'passthrough-operational' | '' - 'datastore running' | [] | PASSTHROUGH_RUNNING | '(a=1,b=2)' || '{"operation":"read","cmHandleProperties":{}}' | 'passthrough-running' | '&options=(a=1,b=2)' + scenario | dmiProperties | dataStore | options || expectedJson | expectedDatastoreInUrl | expectedOptionsInUrl + 'without properties' | [] | PASSTHROUGH_OPERATIONAL | OPTIONS_PARAM || '{"operation":"read","cmHandleProperties":{}}' | 'passthrough-operational' | '&options=(a=1,b=2)' + 'with properties' | [yangModelCmHandleProperty] | PASSTHROUGH_OPERATIONAL | OPTIONS_PARAM || '{"operation":"read","cmHandleProperties":{"prop1":"val1"}}' | 'passthrough-operational' | '&options=(a=1,b=2)' + 'null options' | [yangModelCmHandleProperty] | PASSTHROUGH_OPERATIONAL | null || '{"operation":"read","cmHandleProperties":{"prop1":"val1"}}' | 'passthrough-operational' | '' + 'empty options' | [yangModelCmHandleProperty] | PASSTHROUGH_OPERATIONAL | '' || '{"operation":"read","cmHandleProperties":{"prop1":"val1"}}' | 'passthrough-operational' | '' + 'datastore running without properties' | [] | PASSTHROUGH_RUNNING | OPTIONS_PARAM || '{"operation":"read","cmHandleProperties":{}}' | 'passthrough-running' | '&options=(a=1,b=2)' + 'datastore running with properties' | [yangModelCmHandleProperty] | PASSTHROUGH_RUNNING | OPTIONS_PARAM || '{"operation":"read","cmHandleProperties":{"prop1":"val1"}}' | 'passthrough-running' | '&options=(a=1,b=2)' } def 'Write data for pass-through:running datastore in DMI.'() { given: 'a cm handle for #cmHandleId' mockYangModelCmHandleRetrieval([yangModelCmHandleProperty]) and: 'a positive response from DMI service when it is called with the expected parameters' - def expectedUrl = "${dmiServiceName}/dmi/v1/ch/${cmHandleId}/data/ds" + - "/ncmp-datastore:passthrough-running?resourceIdentifier=${resourceIdentifier}" + def expectedUrl = dmiServiceBaseUrl + "passthrough-running?resourceIdentifier=${resourceIdentifier}" def expectedJson = '{"operation":"' + expectedOperationInUrl + '","dataType":"some data type","data":"requestData","cmHandleProperties":{"prop1":"val1"}}' def responseFromDmi = new ResponseEntity(HttpStatus.OK) + dmiServiceUrlBuilder.getDmiDatastoreUrl(_, _) >> expectedUrl mockDmiRestClient.postOperationWithJsonData(expectedUrl, expectedJson, [:]) >> responseFromDmi when: 'write resource method is invoked' - def result = objectUnderTest.writeResourceDataPassThroughRunningFromDmi(cmHandleId,'parent/child', operation, 'requestData', 'some data type') + def result = objectUnderTest.writeResourceDataPassThroughRunningFromDmi(cmHandleId, 'parent/child', operation, 'requestData', 'some data type') then: 'the result is the response from the DMI service' assert result == responseFromDmi where: 'the following operation is performed' @@ -84,5 +98,4 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec { CREATE || 'create' UPDATE || 'update' } - } \ No newline at end of file diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiModelOperationsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiModelOperationsSpec.groovy index cd2cb7112c..d3fc17cc07 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiModelOperationsSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiModelOperationsSpec.groovy @@ -23,6 +23,7 @@ package org.onap.cps.ncmp.api.impl.operations import com.fasterxml.jackson.core.JsonProcessingException import com.fasterxml.jackson.databind.ObjectMapper import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration +import org.onap.cps.ncmp.api.impl.utils.DmiServiceUrlBuilder import org.onap.cps.spi.model.ModuleReference import org.onap.cps.utils.JsonObjectMapper import org.spockframework.spring.SpringBean @@ -31,6 +32,7 @@ import org.springframework.boot.test.context.SpringBootTest import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity import org.springframework.test.context.ContextConfiguration +import org.springframework.web.util.UriComponentsBuilder import spock.lang.Shared @SpringBootTest @@ -50,14 +52,15 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec { given: 'a cm handle' mockYangModelCmHandleRetrieval([]) and: 'a positive response from DMI service when it is called with the expected parameters' - def moduleReferencesAsLisOfMaps = [[moduleName:'mod1',revision:'A'],[moduleName:'mod2',revision:'X']] - def responseFromDmi = new ResponseEntity([schemas:moduleReferencesAsLisOfMaps], HttpStatus.OK) - mockDmiRestClient.postOperationWithJsonData("${dmiServiceName}/dmi/v1/ch/${cmHandleId}/modules", - '{"cmHandleProperties":{}}', [:]) >> responseFromDmi + def moduleReferencesAsLisOfMaps = [[moduleName: 'mod1', revision: 'A'], [moduleName: 'mod2', revision: 'X']] + def expectedUrl = "${dmiServiceName}/dmi/v1/ch/${cmHandleId}/modules" + def responseFromDmi = new ResponseEntity([schemas: moduleReferencesAsLisOfMaps], HttpStatus.OK) + mockDmiRestClient.postOperationWithJsonData(expectedUrl, '{"cmHandleProperties":{}}', [:]) + >> responseFromDmi when: 'get module references is called' def result = objectUnderTest.getModuleReferences(yangModelCmHandle) then: 'the result consists of expected module references' - assert result == [new ModuleReference(moduleName:'mod1',revision:'A'), new ModuleReference(moduleName:'mod2',revision:'X')] + assert result == [new ModuleReference(moduleName: 'mod1', revision: 'A'), new ModuleReference(moduleName: 'mod2', revision: 'X')] } def 'Retrieving module references edge case: #scenario.'() { diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy index dd0d64dd61..e6f63ce1a2 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy @@ -22,7 +22,9 @@ package org.onap.cps.ncmp.api.impl.operations import com.fasterxml.jackson.databind.ObjectMapper import org.onap.cps.ncmp.api.impl.client.DmiRestClient +import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle +import org.onap.cps.ncmp.api.impl.utils.DmiServiceUrlBuilder import org.spockframework.spring.SpringBean import spock.lang.Shared import spock.lang.Specification @@ -41,6 +43,9 @@ abstract class DmiOperationsBaseSpec extends Specification { @SpringBean ObjectMapper spyObjectMapper = Spy() + @SpringBean + DmiServiceUrlBuilder dmiServiceUrlBuilder = new DmiServiceUrlBuilder(new NcmpConfiguration.DmiProperties()) + def yangModelCmHandle = new YangModelCmHandle() def static dmiServiceName = 'some service name' def static cmHandleId = 'some cm handle' diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/utils/DmiServiceUrlBuilderSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/utils/DmiServiceUrlBuilderSpec.groovy new file mode 100644 index 0000000000..1615d055db --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/utils/DmiServiceUrlBuilderSpec.groovy @@ -0,0 +1,79 @@ +/* + * ============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.api.utils + +import static org.onap.cps.ncmp.api.impl.operations.DmiOperations.DataStoreEnum.PASSTHROUGH_RUNNING + +import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle +import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration +import org.onap.cps.ncmp.api.impl.utils.DmiServiceUrlBuilder +import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle +import spock.lang.Shared +import spock.lang.Specification + +class DmiServiceUrlBuilderSpec extends Specification { + + @Shared + YangModelCmHandle yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle("dmiServiceName", + "dmiDataServiceName", "dmiModuleServiceName", new NcmpServiceCmHandle()) + + NcmpConfiguration.DmiProperties dmiProperties = new NcmpConfiguration.DmiProperties(); + + def objectUnderTest = new DmiServiceUrlBuilder(dmiProperties) + + def 'Create the dmi service url with #scenario.'() { + given: 'uri variables' + dmiProperties.dmiBasePath = 'dmi'; + def uriVars = objectUnderTest.populateUriVariables(yangModelCmHandle, + "cmHandle", PASSTHROUGH_RUNNING); + and: 'query params' + def uriQueries = objectUnderTest.populateQueryParams(resourceId, + 'optionsParamInQuery', topicParamInQuery); + when: 'a dmi datastore service url is generated' + def dmiServiceUrl = objectUnderTest.getDmiDatastoreUrl(uriQueries, uriVars) + then: 'service url is generated as expected' + assert dmiServiceUrl == expectedDmiServiceUrl + where: 'the following parameters are used' + scenario | topicParamInQuery | resourceId || expectedDmiServiceUrl + 'With valid resourceId' | 'topicParamInQuery' | 'resourceId' || 'dmiServiceName/dmi/v1/ch/cmHandle/data/ds/ncmp-datastore:passthrough-running?resourceIdentifier=resourceId&options=optionsParamInQuery&topic=topicParamInQuery' + 'With Empty resourceId' | 'topicParamInQuery' | '' || 'dmiServiceName/dmi/v1/ch/cmHandle/data/ds/ncmp-datastore:passthrough-running?options=optionsParamInQuery&topic=topicParamInQuery' + 'With Empty dmi base path' | 'topicParamInQuery' | 'resourceId' || 'dmiServiceName/dmi/v1/ch/cmHandle/data/ds/ncmp-datastore:passthrough-running?resourceIdentifier=resourceId&options=optionsParamInQuery&topic=topicParamInQuery' + 'With Empty topicParamInQuery' | '' | 'resourceId' || 'dmiServiceName/dmi/v1/ch/cmHandle/data/ds/ncmp-datastore:passthrough-running?resourceIdentifier=resourceId&options=optionsParamInQuery' + } + + def 'Populate dmi data store url #scenario.'() { + given: 'uri variables are created' + dmiProperties.dmiBasePath = dmiBasePath; + def uriVars = objectUnderTest.populateUriVariables(yangModelCmHandle, + "cmHandle", PASSTHROUGH_RUNNING); + and: 'null query params' + def uriQueries = objectUnderTest.populateQueryParams(null, + null, null); + when: 'a dmi datastore service url is generated' + def dmiServiceUrl = objectUnderTest.getDmiDatastoreUrl(uriQueries, uriVars) + then: 'the created dmi service url matches the expected' + assert dmiServiceUrl == expectedDmiServiceUrl + where: 'the following parameters are used' + scenario | decription | dmiBasePath || expectedDmiServiceUrl + 'with base path / ' | 'Invalid base path as it starts with /' | '/dmi' || 'dmiServiceName//dmi/v1/ch/cmHandle/data/ds/ncmp-datastore:passthrough-running' + 'without base path / ' | 'Valid path as it does not starts with /' | 'dmi' || 'dmiServiceName/dmi/v1/ch/cmHandle/data/ds/ncmp-datastore:passthrough-running' + } +} diff --git a/cps-ncmp-service/src/test/resources/application.yml b/cps-ncmp-service/src/test/resources/application.yml index d8fbb64c5f..c23926e4eb 100644 --- a/cps-ncmp-service/src/test/resources/application.yml +++ b/cps-ncmp-service/src/test/resources/application.yml @@ -1,5 +1,5 @@ # ============LICENSE_START======================================================= -# Copyright (C) 2021 Nordix Foundation +# Copyright (C) 2021-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. @@ -21,5 +21,5 @@ dmi: username: some-user password: some-password api: - base-path: /dmi + base-path: dmi -- cgit 1.2.3-korg