diff options
author | 2024-06-21 09:28:37 +0000 | |
---|---|---|
committer | 2024-06-21 09:28:37 +0000 | |
commit | 01b58388db5d6a16c8a3f946fbfb82100377cbda (patch) | |
tree | bd93079a38d1ef660b08f3f0fb5bd5a2a645a886 /cps-ncmp-service/src/test/groovy/org/onap | |
parent | e9893a3d2150bbb3256b09ecdab6d627fea95335 (diff) | |
parent | dbed81b6cece07c8950fa2f32f6f05eba3bb991e (diff) |
Merge "Introducing NCMP Facades"
Diffstat (limited to 'cps-ncmp-service/src/test/groovy/org/onap')
16 files changed, 566 insertions, 559 deletions
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandlerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/CmHandleRegistrationServicePropertyHandlerSpec.groovy index b0024b19b..5eac44b8f 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandlerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/CmHandleRegistrationServicePropertyHandlerSpec.groovy @@ -47,18 +47,18 @@ import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DA import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_ANCHOR import static org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse.Status -class NetworkCmProxyDataServicePropertyHandlerSpec extends Specification { +class CmHandleRegistrationServicePropertyHandlerSpec extends Specification { def mockInventoryPersistence = Mock(InventoryPersistence) def mockCpsDataService = Mock(CpsDataService) def jsonObjectMapper = new JsonObjectMapper(new ObjectMapper()) def mockAlternateIdChecker = Mock(AlternateIdChecker) - def objectUnderTest = new NetworkCmProxyDataServicePropertyHandler(mockInventoryPersistence, mockCpsDataService, jsonObjectMapper, mockAlternateIdChecker) + def objectUnderTest = new CmHandleRegistrationServicePropertyHandler(mockInventoryPersistence, mockCpsDataService, jsonObjectMapper, mockAlternateIdChecker) def logger = Spy(ListAppender<ILoggingEvent>) void setup() { - def setupLogger = ((Logger) LoggerFactory.getLogger(NetworkCmProxyDataServicePropertyHandler.class)) + def setupLogger = ((Logger) LoggerFactory.getLogger(CmHandleRegistrationServicePropertyHandler.class)) setupLogger.addAppender(logger) setupLogger.setLevel(Level.DEBUG) logger.start() @@ -67,7 +67,7 @@ class NetworkCmProxyDataServicePropertyHandlerSpec extends Specification { } void cleanup() { - ((Logger) LoggerFactory.getLogger(NetworkCmProxyDataServicePropertyHandler.class)).detachAndStopAllAppenders() + ((Logger) LoggerFactory.getLogger(CmHandleRegistrationServicePropertyHandler.class)).detachAndStopAllAppenders() } def static cmHandleId = 'myHandle1' @@ -242,12 +242,12 @@ class NetworkCmProxyDataServicePropertyHandlerSpec extends Specification { given: 'an existing cm handle with no data producer identifier' DataNode existingCmHandleDataNode = new DataNode(xpath: cmHandleXpath, leaves: ['id': 'cmHandleId','data-producer-identifier': oldDataProducerIdentifier]) and: 'an update request with a new data producer identifier' - def ncmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: cmHandleId, dataProducerIdentifier: 'someDataProducerIdentifier') + def ncmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: cmHandleId, dataProducerIdentifier: 'New Data Producer Identifier') when: 'data producer identifier updated' objectUnderTest.updateDataProducerIdentifier(existingCmHandleDataNode, ncmpServiceCmHandle) then: 'the update node leaves method is invoked once' 1 * mockCpsDataService.updateNodeLeaves('NCMP-Admin', 'ncmp-dmi-registry', '/dmi-registry', _, _, ContentType.JSON) >> { args -> - assert args[3].contains('someDataProducerIdentifier') + assert args[3].contains('New Data Producer Identifier') } and: 'correct information is logged' def lastLoggingEvent = logger.list[0] @@ -259,6 +259,17 @@ class NetworkCmProxyDataServicePropertyHandlerSpec extends Specification { 'blank to something' | '' } + def 'Update CM Handle data producer identifier with same value'() { + given: 'an existing cm handle with no data producer identifier' + DataNode existingCmHandleDataNode = new DataNode(xpath: cmHandleXpath, leaves: ['id': 'cmHandleId','data-producer-identifier': 'same id']) + and: 'an update request with a new data producer identifier' + def ncmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: cmHandleId, dataProducerIdentifier: 'same id') + when: 'data producer identifier updated' + objectUnderTest.updateDataProducerIdentifier(existingCmHandleDataNode, ncmpServiceCmHandle) + then: 'the update node leaves method is not invoked' + 0 * mockCpsDataService.updateNodeLeaves(*_) + } + def 'Update CM Handle data producer identifier from some data producer identifier to another data producer identifier'() { given: 'an existing cm handle with a data producer identifier' DataNode existingCmHandleDataNode = new DataNode(xpath: cmHandleXpath, leaves: ['id': 'cmHandleId', 'data-producer-identifier': 'someDataProducerIdentifier']) diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/CmHandleRegistrationServiceSpec.groovy index fbfbac59e..1c6e38420 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/CmHandleRegistrationServiceSpec.groovy @@ -21,49 +21,45 @@ package org.onap.cps.ncmp.api.impl -import static org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse.Status -import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLES_NOT_FOUND -import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_ALREADY_EXIST -import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_INVALID_ID -import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNKNOWN_ERROR - -import org.onap.cps.ncmp.api.impl.inventory.CompositeState -import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevelManager -import org.onap.cps.ncmp.api.impl.utils.AlternateIdChecker -import org.onap.cps.ncmp.api.models.UpgradedCmHandles -import com.fasterxml.jackson.databind.ObjectMapper import com.hazelcast.map.IMap import org.onap.cps.api.CpsDataService import org.onap.cps.api.CpsModuleService -import org.onap.cps.ncmp.api.NetworkCmProxyCmHandleQueryService import org.onap.cps.ncmp.api.impl.events.lcm.LcmEventsCmHandleStateHandler import org.onap.cps.ncmp.api.impl.exception.DmiRequestException -import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations -import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel -import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle -import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueries +import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueryService import org.onap.cps.ncmp.api.impl.inventory.CmHandleState +import org.onap.cps.ncmp.api.impl.inventory.CompositeState +import org.onap.cps.ncmp.api.impl.inventory.DataStoreSyncState import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence +import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel +import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevelManager +import org.onap.cps.ncmp.api.impl.utils.AlternateIdChecker +import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse import org.onap.cps.ncmp.api.models.DmiPluginRegistration import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle +import org.onap.cps.ncmp.api.models.UpgradedCmHandles import org.onap.cps.spi.exceptions.AlreadyDefinedException +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.spi.exceptions.SchemaSetNotFoundException -import org.onap.cps.utils.JsonObjectMapper import spock.lang.Specification -class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { +import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLES_NOT_FOUND +import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_ALREADY_EXIST +import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_INVALID_ID +import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNKNOWN_ERROR +import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME +import static org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse.Status + +class CmHandleRegistrationServiceSpec extends Specification { def ncmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: 'some-cm-handle-id') def mockCpsModuleService = Mock(CpsModuleService) - def spiedJsonObjectMapper = Spy(new JsonObjectMapper(new ObjectMapper())) - def mockDmiDataOperations = Mock(DmiDataOperations) - def mockNetworkCmProxyDataServicePropertyHandler = Mock(NetworkCmProxyDataServicePropertyHandler) + def mockNetworkCmProxyDataServicePropertyHandler = Mock(CmHandleRegistrationServicePropertyHandler) def mockInventoryPersistence = Mock(InventoryPersistence) - def mockCmHandleQueries = Mock(CmHandleQueries) - def stubbedNetworkCmProxyCmHandlerQueryService = Stub(NetworkCmProxyCmHandleQueryService) + def mockCmHandleQueries = Mock(CmHandleQueryService) def mockLcmEventsCmHandleStateHandler = Mock(LcmEventsCmHandleStateHandler) def mockCpsDataService = Mock(CpsDataService) def mockModuleSyncStartedOnCmHandles = Mock(IMap<String, Object>) @@ -71,10 +67,9 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { def mockTrustLevelManager = Mock(TrustLevelManager) def mockAlternateIdChecker = Mock(AlternateIdChecker) - def objectUnderTest = Spy(new NetworkCmProxyDataServiceImpl(spiedJsonObjectMapper, mockDmiDataOperations, - mockNetworkCmProxyDataServicePropertyHandler, mockInventoryPersistence, mockCmHandleQueries, - stubbedNetworkCmProxyCmHandlerQueryService, mockLcmEventsCmHandleStateHandler, mockCpsDataService, - mockModuleSyncStartedOnCmHandles, trustLevelPerDmiPlugin, mockTrustLevelManager, mockAlternateIdChecker)) + def objectUnderTest = Spy(new CmHandleRegistrationService( + mockNetworkCmProxyDataServicePropertyHandler, mockInventoryPersistence, mockCpsDataService, mockLcmEventsCmHandleStateHandler, + mockModuleSyncStartedOnCmHandles, trustLevelPerDmiPlugin , mockTrustLevelManager, mockAlternateIdChecker)) def setup() { // always accept all cm handles @@ -418,4 +413,46 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { 'an unexpected exception' | 'cmhandle' | new RuntimeException('Failed') || UNKNOWN_ERROR | 'Failed' } + def 'Set Cm Handle Data Sync Enabled Flag where data sync flag is #scenario'() { + given: 'an existing cm handle composite state' + def compositeState = new CompositeState(cmHandleState: CmHandleState.READY, dataSyncEnabled: initialDataSyncEnabledFlag, + dataStores: CompositeState.DataStores.builder() + .operationalDataStore(CompositeState.Operational.builder() + .dataStoreSyncState(initialDataSyncState) + .build()).build()) + and: 'get cm handle state returns the composite state for the given cm handle id' + mockInventoryPersistence.getCmHandleState('some-cm-handle-id') >> compositeState + when: 'set data sync enabled is called with the data sync enabled flag set to #dataSyncEnabledFlag' + objectUnderTest.setDataSyncEnabled('some-cm-handle-id', dataSyncEnabledFlag) + then: 'the data sync enabled flag is set to #dataSyncEnabled' + compositeState.dataSyncEnabled == dataSyncEnabledFlag + and: 'the data store sync state is set to #expectedDataStoreSyncState' + compositeState.dataStores.operationalDataStore.dataStoreSyncState == expectedDataStoreSyncState + and: 'the cps data service to delete data nodes is invoked the expected number of times' + deleteDataNodeExpectedNumberOfInvocation * mockCpsDataService.deleteDataNode(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, 'some-cm-handle-id', '/netconf-state', _) + and: 'the inventory persistence service to update node leaves is called with the correct values' + saveCmHandleStateExpectedNumberOfInvocations * mockInventoryPersistence.saveCmHandleState('some-cm-handle-id', compositeState) + where: 'the following data sync enabled flag is used' + scenario | dataSyncEnabledFlag | initialDataSyncEnabledFlag | initialDataSyncState || expectedDataStoreSyncState | deleteDataNodeExpectedNumberOfInvocation | saveCmHandleStateExpectedNumberOfInvocations + 'enabled' | true | false | DataStoreSyncState.NONE_REQUESTED || DataStoreSyncState.UNSYNCHRONIZED | 0 | 1 + 'disabled' | false | true | DataStoreSyncState.UNSYNCHRONIZED || DataStoreSyncState.NONE_REQUESTED | 0 | 1 + 'disabled where sync-state is currently SYNCHRONIZED' | false | true | DataStoreSyncState.SYNCHRONIZED || DataStoreSyncState.NONE_REQUESTED | 1 | 1 + 'is set to existing flag state' | true | true | DataStoreSyncState.UNSYNCHRONIZED || DataStoreSyncState.UNSYNCHRONIZED | 0 | 0 + } + + def 'Set cm Handle Data Sync Enabled flag with following cm handle not in ready state exception' () { + given: 'a cm handle composite state' + def compositeState = new CompositeState(cmHandleState: CmHandleState.ADVISED, dataSyncEnabled: false) + and: 'get cm handle state returns the composite state for the given cm handle id' + mockInventoryPersistence.getCmHandleState('some-cm-handle-id') >> compositeState + when: 'set data sync enabled is called with the data sync enabled flag set to true' + objectUnderTest.setDataSyncEnabled('some-cm-handle-id', true) + then: 'the expected exception is thrown' + thrown(CpsException) + and: 'the inventory persistence service to update node leaves is not invoked' + 0 * mockInventoryPersistence.saveCmHandleState(_, _) + } + + + } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NcmpCachedResourceRequestHandlerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NcmpCachedResourceRequestHandlerSpec.groovy new file mode 100644 index 000000000..781b6204a --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NcmpCachedResourceRequestHandlerSpec.groovy @@ -0,0 +1,64 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2024 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.impl + +import org.onap.cps.api.CpsDataService +import org.onap.cps.ncmp.api.NetworkCmProxyQueryService +import org.onap.cps.ncmp.api.models.CmResourceAddress +import org.onap.cps.spi.model.DataNode +import reactor.core.publisher.Mono +import spock.lang.Specification + +import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS +import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS + +class NcmpCachedResourceRequestHandlerSpec extends Specification { + + def cpsDataService = Mock(CpsDataService) + def networkCmProxyQueryService= Mock(NetworkCmProxyQueryService) + + def objectUnderTest = new NcmpCachedResourceRequestHandler(cpsDataService, networkCmProxyQueryService) + + def 'Execute a request with include descendants = #includeDescendants.'() { + when: 'executing a request' + objectUnderTest.executeRequest('ch-1', 'resource', includeDescendants) + then: 'it is delegated to the ncmp query service with the correct option' + 1 * networkCmProxyQueryService.queryResourceDataOperational('ch-1','resource', expectedFetchDescendantsOption) + where: 'the following options are used' + includeDescendants || expectedFetchDescendantsOption + true || INCLUDE_ALL_DESCENDANTS + false || OMIT_DESCENDANTS + } + + def 'Get resource data.'() { + given: 'the data service returns 2 nodes for the given resource address' + def cmResourceAddress = new CmResourceAddress('datastore','ch-1','resource') + def dataNode1 = new DataNode(xpath:'p1') + def dataNode2 = new DataNode(xpath:'p2') + cpsDataService.getDataNodes('datastore','ch-1','resource',OMIT_DESCENDANTS) >> [dataNode1, dataNode2] + when: 'getting the resource data' + def result = objectUnderTest.getResourceDataForCmHandle(cmResourceAddress, 'options', 'topic', 'request id', false, 'authorization') + then: 'the result is a "Mono" holding just the first data node' + assert result instanceof Mono + assert result.block() == dataNode1 + } + +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NcmpDatastoreRequestHandlerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NcmpDatastoreRequestHandlerSpec.groovy index b73f9a46d..9a845c0ba 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NcmpDatastoreRequestHandlerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NcmpDatastoreRequestHandlerSpec.groovy @@ -20,48 +20,44 @@ package org.onap.cps.ncmp.api.impl -import org.onap.cps.ncmp.api.NetworkCmProxyDataService import org.onap.cps.ncmp.api.impl.exception.InvalidDatastoreException import org.onap.cps.ncmp.api.impl.exception.InvalidOperationException +import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations import org.onap.cps.ncmp.api.models.CmResourceAddress import org.onap.cps.ncmp.api.models.DataOperationDefinition import org.onap.cps.ncmp.api.models.DataOperationRequest import org.onap.cps.ncmp.exceptions.OperationNotSupportedException import org.onap.cps.ncmp.exceptions.PayloadTooLargeException -import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity import reactor.core.publisher.Mono import spock.lang.Specification +import static org.springframework.http.HttpStatus.I_AM_A_TEAPOT + class NcmpDatastoreRequestHandlerSpec extends Specification { - def mockNetworkCmProxyDataService = Mock(NetworkCmProxyDataService) + def dmiDataOperations = Mock(DmiDataOperations) - def objectUnderTest = new NcmpPassthroughResourceRequestHandler(mockNetworkCmProxyDataService) + def objectUnderTest = new NcmpPassthroughResourceRequestHandler(dmiDataOperations) + def NO_TOPIC = null def NO_AUTH_HEADER = null - def setup() { - objectUnderTest.timeOutInMilliSeconds = 100 - } - def 'Attempt to execute async get request with #scenario.'() { given: 'notification feature is turned on/off' objectUnderTest.notificationFeatureEnabled = notificationFeatureEnabled and: 'a CM resource address' def cmResourceAddress = new CmResourceAddress('ds', 'ch1', 'resource1') - and: 'the (mocked) service when called with the correct parameters returns a response from dmi' - def resultFromDmi = new ResponseEntity('response from dmi',HttpStatus.I_AM_A_TEAPOT) - def synchronousResult = Mono.justOrEmpty(resultFromDmi) - mockNetworkCmProxyDataService.getResourceDataForCmHandle(cmResourceAddress, 'options', _, _, NO_AUTH_HEADER) >> synchronousResult + and: 'the (mocked) service when called with the correct parameters (with or without topic) returns a response from dmi' + def dmiResponse = Mono.justOrEmpty(new ResponseEntity('dmi response',I_AM_A_TEAPOT)) + dmiDataOperations.getResourceDataFromDmi(cmResourceAddress, 'options', NO_TOPIC, _, NO_AUTH_HEADER) >> dmiResponse + dmiDataOperations.getResourceDataFromDmi(cmResourceAddress, 'options', topic, _, NO_AUTH_HEADER) >> dmiResponse when: 'get request is executed with topic = #topic' def response = objectUnderTest.executeRequest(cmResourceAddress, 'options', topic, false, NO_AUTH_HEADER) then: 'a successful result with/without request id is returned' if (expectSynchronousResponse) { - assert response.toString().contains('response from dmi') - assert response.toString().contains("I'm a teapot") - } else { - // expect request id in a map + assert response == 'dmi response' + } else { // expect request id in a map assert response.keySet()[0] == 'requestId' } where: 'the following parameters are used' @@ -74,33 +70,20 @@ class NcmpDatastoreRequestHandlerSpec extends Specification { def 'Attempt to execute async data operation request with feature #scenario.'() { given: 'a extended request handler that supports bulk requests' - def objectUnderTest = new NcmpPassthroughResourceRequestHandler(mockNetworkCmProxyDataService) + def objectUnderTest = new NcmpPassthroughResourceRequestHandler(dmiDataOperations) and: 'notification feature is turned on/off' objectUnderTest.notificationFeatureEnabled = notificationFeatureEnabled when: 'data operation request is executed' - objectUnderTest.executeRequest('someTopic', new DataOperationRequest(), NO_AUTH_HEADER) + def dataOperationDefinition = new DataOperationDefinition(operation: 'read', datastore: 'ncmp-datastore:passthrough-running', cmHandleIds: ['ch']) + def result = objectUnderTest.executeAsynchronousRequest('someTopic', new DataOperationRequest(dataOperationDefinitions:[dataOperationDefinition]), NO_AUTH_HEADER) then: 'the task is executed in an async fashion or not' - expectedCalls * mockNetworkCmProxyDataService.executeDataOperationForCmHandles('someTopic', _, _, null) + expectedCalls * dmiDataOperations.requestResourceDataFromDmi('someTopic', _, _, NO_AUTH_HEADER) + and: + result.keySet()[0] == expectedKeyInMap where: 'the following parameters are used' - scenario | notificationFeatureEnabled || expectedCalls - 'on' | true || 1 - 'off' | false || 0 - } - - def 'Execute async data operation request with datastore #datastore.'() { - given: 'notification feature is turned on' - objectUnderTest.notificationFeatureEnabled = true - and: 'a data operation request with datastore: #datastore' - def dataOperationDefinition = new DataOperationDefinition(operation: 'read', datastore: datastore) - def dataOperationRequest = new DataOperationRequest(dataOperationDefinitions: [dataOperationDefinition]) - when: 'data operation request is executed' - def response = objectUnderTest.executeRequest('myTopic', dataOperationRequest, NO_AUTH_HEADER) - and: 'a map with request id is returned' - assert response.keySet()[0] == 'requestId' - then: 'the network service is invoked' - 1 * mockNetworkCmProxyDataService.executeDataOperationForCmHandles('myTopic', dataOperationRequest, _, NO_AUTH_HEADER) - where: 'the following datastores are used' - datastore << ['ncmp-datastore:passthrough-running', 'ncmp-datastore:passthrough-operational'] + scenario | notificationFeatureEnabled || expectedCalls || expectedKeyInMap + 'on' | true || 1 || 'requestId' + 'off' | false || 0 || 'status' } def 'Attempt to execute async data operation request with error #scenario'() { @@ -108,7 +91,7 @@ class NcmpDatastoreRequestHandlerSpec extends Specification { def dataOperationDefinition = new DataOperationDefinition(operation: 'read', datastore: datastore) when: 'data operation request is executed' def dataOperationRequest = new DataOperationRequest(dataOperationDefinitions: [dataOperationDefinition]) - objectUnderTest.executeRequest('myTopic', dataOperationRequest, NO_AUTH_HEADER) + objectUnderTest.executeAsynchronousRequest('myTopic', dataOperationRequest, NO_AUTH_HEADER) then: 'the correct error is thrown' def thrown = thrown(InvalidDatastoreException) assert thrown.message.contains(expectedErrorMessage) @@ -122,7 +105,7 @@ class NcmpDatastoreRequestHandlerSpec extends Specification { given: 'a data operation definition with operation: #operation' def dataOperationDefinition = new DataOperationDefinition(operation: operation, datastore: 'ncmp-datastore:passthrough-running') when: 'data operation request is executed' - objectUnderTest.executeRequest('someTopic', new DataOperationRequest(dataOperationDefinitions:[dataOperationDefinition]), NO_AUTH_HEADER) + objectUnderTest.executeAsynchronousRequest('someTopic', new DataOperationRequest(dataOperationDefinitions:[dataOperationDefinition]), NO_AUTH_HEADER) then: 'the expected type of exception is thrown' thrown(expectedException) where: 'the following operations are used' @@ -136,11 +119,11 @@ class NcmpDatastoreRequestHandlerSpec extends Specification { def 'Attempt to execute async data operation request with too many cm handles.'() { given: 'a data operation definition with too many cm handles' - def tooMany = objectUnderTest.MAXIMUM_CM_HANDLES_PER_OPERATION+1 + def tooMany = objectUnderTest.MAXIMUM_CM_HANDLES_PER_OPERATION + 1 def cmHandleIds = new String[tooMany] def dataOperationDefinition = new DataOperationDefinition(operationId: 'abc', operation: 'read', datastore: 'ncmp-datastore:passthrough-running', cmHandleIds: cmHandleIds) when: 'data operation request is executed' - objectUnderTest.executeRequest('someTopic', new DataOperationRequest(dataOperationDefinitions:[dataOperationDefinition]), NO_AUTH_HEADER) + objectUnderTest.executeAsynchronousRequest('someTopic', new DataOperationRequest(dataOperationDefinitions:[dataOperationDefinition]), NO_AUTH_HEADER) then: 'a payload too large exception is thrown' def exceptionThrown = thrown(PayloadTooLargeException) and: 'the error message contains the offending number of cm handles' 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 deleted file mode 100644 index d91c79d33..000000000 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy +++ /dev/null @@ -1,413 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021-2024 Nordix Foundation - * Modifications Copyright (C) 2021 Pantheon.tech - * Modifications Copyright (C) 2021-2022 Bell Canada - * Modifications Copyright (C) 2023 TechMahindra Ltd. - * ================================================================================ - * 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.impl - -import reactor.core.publisher.Mono - -import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME -import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME -import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_ANCHOR -import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.OPERATIONAL -import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_OPERATIONAL -import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_RUNNING -import static org.onap.cps.ncmp.api.impl.operations.OperationType.CREATE -import static org.onap.cps.ncmp.api.impl.operations.OperationType.UPDATE - -import org.onap.cps.ncmp.api.models.DmiPluginRegistrationResponse -import org.onap.cps.ncmp.api.models.CmResourceAddress -import org.onap.cps.ncmp.api.impl.utils.AlternateIdChecker -import com.hazelcast.map.IMap -import org.onap.cps.ncmp.api.NetworkCmProxyCmHandleQueryService -import org.onap.cps.ncmp.api.impl.events.lcm.LcmEventsCmHandleStateHandler -import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel -import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevelManager -import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle -import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueries -import org.onap.cps.ncmp.api.impl.inventory.CmHandleState -import org.onap.cps.ncmp.api.impl.inventory.CompositeState -import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence -import org.onap.cps.ncmp.api.impl.inventory.LockReasonCategory -import org.onap.cps.ncmp.api.impl.inventory.DataStoreSyncState -import org.onap.cps.ncmp.api.models.DataOperationDefinition -import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters -import org.onap.cps.ncmp.api.models.CmHandleQueryServiceParameters -import org.onap.cps.ncmp.api.models.ConditionApiProperties -import org.onap.cps.ncmp.api.models.DmiPluginRegistration -import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle -import org.onap.cps.ncmp.api.models.DataOperationRequest -import org.onap.cps.spi.exceptions.CpsException -import org.onap.cps.spi.model.ConditionProperties -import java.util.stream.Collectors -import org.onap.cps.utils.JsonObjectMapper -import com.fasterxml.jackson.databind.ObjectMapper -import org.onap.cps.api.CpsDataService -import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations -import org.onap.cps.spi.FetchDescendantsOption -import org.onap.cps.spi.model.DataNode -import org.springframework.http.HttpStatus -import org.springframework.http.ResponseEntity -import spock.lang.Specification - -class NetworkCmProxyDataServiceImplSpec extends Specification { - - def mockCpsDataService = Mock(CpsDataService) - def spiedJsonObjectMapper = Spy(new JsonObjectMapper(new ObjectMapper())) - def mockDmiDataOperations = Mock(DmiDataOperations) - def nullNetworkCmProxyDataServicePropertyHandler = null - def mockInventoryPersistence = Mock(InventoryPersistence) - def mockCmHandleQueries = Mock(CmHandleQueries) - def mockDmiPluginRegistration = Mock(DmiPluginRegistration) - def mockCpsCmHandlerQueryService = Mock(NetworkCmProxyCmHandleQueryService) - def mockLcmEventsCmHandleStateHandler = Mock(LcmEventsCmHandleStateHandler) - def stubModuleSyncStartedOnCmHandles = Stub(IMap<String, Object>) - def stubTrustLevelPerDmiPlugin = Stub(Map<String, TrustLevel>) - def mockTrustLevelManager = Mock(TrustLevelManager) - def mockAlternateIdChecker = Mock(AlternateIdChecker) - - def NO_TOPIC = null - def NO_REQUEST_ID = null - def NO_AUTH_HEADER = null - def OPTIONS_PARAM = '(a=1,b=2)' - def ncmpServiceCmHandle = new NcmpServiceCmHandle(cmHandleId: 'test-cm-handle-id') - - def objectUnderTest = new NetworkCmProxyDataServiceImpl( - spiedJsonObjectMapper, - mockDmiDataOperations, - nullNetworkCmProxyDataServicePropertyHandler, - mockInventoryPersistence, - mockCmHandleQueries, - mockCpsCmHandlerQueryService, - mockLcmEventsCmHandleStateHandler, - mockCpsDataService, - stubModuleSyncStartedOnCmHandles, - stubTrustLevelPerDmiPlugin, - mockTrustLevelManager, - mockAlternateIdChecker) - - def cmHandleXPath = "/dmi-registry/cm-handles[@id='testCmHandle']" - - def dataNode = [new DataNode(leaves: ['id': 'some-cm-handle', 'dmi-service-name': 'testDmiService'])] - - def 'Write resource data for pass-through running from DMI using POST.'() { - given: 'cpsDataService returns valid datanode' - mockDataNode() - when: 'write resource data is called' - objectUnderTest.writeResourceDataPassThroughRunningForCmHandle('testCmHandle', - 'testResourceId', CREATE, - '{some-json}', 'application/json', null) - then: 'DMI called with correct data' - 1 * mockDmiDataOperations.writeResourceDataPassThroughRunningFromDmi('testCmHandle', 'testResourceId', - CREATE, '{some-json}', 'application/json', null) - >> { new ResponseEntity<>(HttpStatus.CREATED) } - } - - def 'Get resource data from DMI.'() { - given: 'cpsDataService returns valid data node' - mockDataNode() - and: 'some cm resource address' - def cmResourceAddress = new CmResourceAddress('some datastore', 'some CM Handle', 'some resource Id') - and: 'get resource data from DMI is called' - mockDmiDataOperations.getResourceDataFromDmi(cmResourceAddress, OPTIONS_PARAM, NO_TOPIC, NO_REQUEST_ID, NO_AUTH_HEADER) >> - Mono.just(new ResponseEntity<>('dmi-response', HttpStatus.OK)) - when: 'get resource data operational for the given cm resource address is called' - def response = objectUnderTest.getResourceDataForCmHandle(cmResourceAddress, OPTIONS_PARAM, NO_TOPIC, NO_REQUEST_ID, NO_AUTH_HEADER).block() - then: 'DMI returns a json response' - assert response == 'dmi-response' - } - - def 'Get resource data for operational (cached) data.'() { - given: 'CPS Data service returns some object(s)' - mockCpsDataService.getDataNodes(OPERATIONAL.datastoreName, 'testCmHandle', 'testResourceId', FetchDescendantsOption.OMIT_DESCENDANTS) >> ['First Object', 'other Object'] - and: 'a cm resource address for the same datastore, cm handle and resource id' - def cmResourceAddress = new CmResourceAddress(OPERATIONAL.datastoreName, 'testCmHandle', 'testResourceId') - when: 'get resource data is called' - def response = objectUnderTest.getResourceDataForCmHandle(cmResourceAddress, FetchDescendantsOption.OMIT_DESCENDANTS) - then: 'get resource data returns teh first object from the data service' - assert response == 'First Object' - } - - def 'Execute (async) data operation for #datastoreName from DMI.'() { - given: 'cpsDataService returns valid data node' - def dataOperationRequest = getDataOperationRequest(datastoreName) - when: 'request resource data for data operation is called' - objectUnderTest.executeDataOperationForCmHandles('some topic', dataOperationRequest, 'requestId', NO_AUTH_HEADER) - then: 'request resource data for data operation returns expected response' - 1 * mockDmiDataOperations.requestResourceDataFromDmi('some topic', dataOperationRequest, 'requestId', NO_AUTH_HEADER) - where: 'the following data stores are used' - datastoreName << [PASSTHROUGH_RUNNING.datastoreName, PASSTHROUGH_OPERATIONAL.datastoreName] - } - - def 'Getting Yang Resources.'() { - when: 'yang resources is called' - objectUnderTest.getYangResourcesModuleReferences('some-cm-handle') - then: 'CPS module services is invoked for the correct dataspace and cm handle' - 1 * mockInventoryPersistence.getYangResourcesModuleReferences('some-cm-handle') - } - - def 'Get a cm handle.'() { - given: 'the system returns a yang modelled cm handle' - def dmiServiceName = 'some service name' - def compositeState = new CompositeState(cmHandleState: CmHandleState.ADVISED, - lockReason: CompositeState.LockReason.builder().lockReasonCategory(LockReasonCategory.MODULE_SYNC_FAILED).details("lock details").build(), - lastUpdateTime: 'some-timestamp', - dataSyncEnabled: false, - dataStores: dataStores()) - def dmiProperties = [new YangModelCmHandle.Property('Book', 'Romance Novel')] - def publicProperties = [new YangModelCmHandle.Property('Public Book', 'Public Romance Novel')] - def moduleSetTag = 'some-module-set-tag' - def alternateId = 'some-alternate-id' - def yangModelCmHandle = new YangModelCmHandle(id: 'some-cm-handle', dmiServiceName: dmiServiceName, - dmiProperties: dmiProperties, publicProperties: publicProperties, compositeState: compositeState, - moduleSetTag: moduleSetTag, alternateId: alternateId) - 1 * mockInventoryPersistence.getYangModelCmHandle('some-cm-handle') >> yangModelCmHandle - when: 'getting cm handle details for a given cm handle id from ncmp service' - def result = objectUnderTest.getNcmpServiceCmHandle('some-cm-handle') - then: 'the result is a ncmpServiceCmHandle' - result.class == NcmpServiceCmHandle.class - and: 'the cm handle contains the cm handle id' - result.cmHandleId == 'some-cm-handle' - and: 'the cm handle contains the alternate id' - result.alternateId == 'some-alternate-id' - and: 'the cm handle contains the module-set-tag' - result.moduleSetTag == 'some-module-set-tag' - and: 'the cm handle contains the DMI Properties' - result.dmiProperties ==[ Book:'Romance Novel' ] - and: 'the cm handle contains the public Properties' - result.publicProperties == [ "Public Book":'Public Romance Novel' ] - and: 'the cm handle contains the cm handle composite state' - result.compositeState == compositeState - } - - def 'Get cm handle public properties'() { - given: 'a yang modelled cm handle' - def dmiProperties = [new YangModelCmHandle.Property('prop', 'some DMI property')] - def publicProperties = [new YangModelCmHandle.Property('public prop', 'some public prop')] - def yangModelCmHandle = new YangModelCmHandle(id:'some-cm-handle', dmiServiceName: 'some service name', dmiProperties: dmiProperties, publicProperties: publicProperties) - and: 'the system returns this yang modelled cm handle' - 1 * mockInventoryPersistence.getYangModelCmHandle('some-cm-handle') >> yangModelCmHandle - when: 'getting cm handle public properties for a given cm handle id from ncmp service' - def result = objectUnderTest.getCmHandlePublicProperties('some-cm-handle') - then: 'the result returns the correct data' - result == [ 'public prop' : 'some public prop' ] - } - - def 'Execute cm handle id search for inventory'() { - given: 'a ConditionApiProperties object' - def conditionProperties = new ConditionProperties() - conditionProperties.conditionName = 'hasAllProperties' - conditionProperties.conditionParameters = [ [ 'some-key' : 'some-value' ] ] - def conditionServiceProps = new CmHandleQueryServiceParameters() - conditionServiceProps.cmHandleQueryParameters = [conditionProperties] as List<ConditionProperties> - and: 'the system returns an set of cmHandle ids' - mockCpsCmHandlerQueryService.queryCmHandleIdsForInventory(*_) >> [ 'cmHandle1', 'cmHandle2' ] - when: 'getting cm handle id set for a given dmi property' - def result = objectUnderTest.executeCmHandleIdSearchForInventory(conditionServiceProps) - then: 'the result returns the correct 2 elements' - assert result.size() == 2 - assert result.contains('cmHandle1') - assert result.contains('cmHandle2') - } - - def 'Get cm handle composite state'() { - given: 'a yang modelled cm handle' - def compositeState = new CompositeState(cmHandleState: CmHandleState.ADVISED, - lockReason: CompositeState.LockReason.builder().lockReasonCategory(LockReasonCategory.MODULE_SYNC_FAILED).details("lock details").build(), - lastUpdateTime: 'some-timestamp', - dataSyncEnabled: false, - dataStores: dataStores()) - def dmiProperties = [new YangModelCmHandle.Property('prop', 'some DMI property')] - def publicProperties = [new YangModelCmHandle.Property('public prop', 'some public prop')] - def yangModelCmHandle = new YangModelCmHandle(id:'some-cm-handle', dmiServiceName: 'some service name', dmiProperties: dmiProperties, publicProperties: publicProperties, compositeState: compositeState) - and: 'the system returns this yang modelled cm handle' - 1 * mockInventoryPersistence.getYangModelCmHandle('some-cm-handle') >> yangModelCmHandle - when: 'getting cm handle composite state for a given cm handle id from ncmp service' - def result = objectUnderTest.getCmHandleCompositeState('some-cm-handle') - then: 'the result returns the correct data' - result == compositeState - } - - def 'Update resource data for pass-through running from dmi using POST #scenario DMI properties.'() { - given: 'cpsDataService returns valid datanode' - mockCpsDataService.getDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode - when: 'get resource data is called' - objectUnderTest.writeResourceDataPassThroughRunningForCmHandle('testCmHandle', - 'testResourceId', UPDATE, - '{some-json}', 'application/json', NO_AUTH_HEADER) - then: 'DMI called with correct data' - 1 * mockDmiDataOperations.writeResourceDataPassThroughRunningFromDmi('testCmHandle', 'testResourceId', - UPDATE, '{some-json}', 'application/json', NO_AUTH_HEADER) - >> { new ResponseEntity<>(HttpStatus.OK) } - } - - def 'Verify modules and create anchor params.'() { - given: 'dmi plugin registration return created cm handles' - def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'service1', dmiModelPlugin: 'service1', - dmiDataPlugin: 'service2') - dmiPluginRegistration.createdCmHandles = [ncmpServiceCmHandle] - mockDmiPluginRegistration.getCreatedCmHandles() >> [ncmpServiceCmHandle] - and: 'no rejected cm handles because of alternate ids' - mockAlternateIdChecker.getIdsOfCmHandlesWithRejectedAlternateId(*_) >> [] - when: 'parse and create cm handle in dmi registration then sync module' - mockDmiPluginRegistration.createdCmHandles = ['test-cm-handle-id'] - objectUnderTest.processCreatedCmHandles(mockDmiPluginRegistration, new DmiPluginRegistrationResponse()) - then: 'system persists the cm handle state' - 1 * mockLcmEventsCmHandleStateHandler.initiateStateAdvised(_) >> { - args -> { - def cmHandleStatePerCmHandle = (args[0] as Collection) - cmHandleStatePerCmHandle.each { - assert it.id == 'test-cm-handle-id' - } - } - } - } - - def 'Execute cm handle id search'() { - given: 'valid CmHandleQueryApiParameters input' - def cmHandleQueryApiParameters = new CmHandleQueryApiParameters() - def conditionApiProperties = new ConditionApiProperties() - conditionApiProperties.conditionName = 'hasAllModules' - conditionApiProperties.conditionParameters = [[moduleName: 'module-name-1']] - cmHandleQueryApiParameters.cmHandleQueryParameters = [conditionApiProperties] - and: 'query cm handle method return with a data node list' - mockCpsCmHandlerQueryService.queryCmHandleIds( - spiedJsonObjectMapper.convertToValueType(cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class)) - >> ['cm-handle-id-1'] - when: 'execute cm handle search is called' - def result = objectUnderTest.executeCmHandleIdSearch(cmHandleQueryApiParameters) - then: 'result is the same collection as returned by the CPS Data Service' - assert result == ['cm-handle-id-1'] - } - - def 'Getting module definitions by module'() { - when: 'get module definitions is performed with module name' - objectUnderTest.getModuleDefinitionsByCmHandleAndModule('some-cm-handle', 'some-module', '2021-08-04') - then: 'ncmp inventory persistence service is invoked once with correct parameters' - 1 * mockInventoryPersistence.getModuleDefinitionsByCmHandleAndModule('some-cm-handle', 'some-module', '2021-08-04') - } - - def 'Getting module definitions by cm handle id'() { - when: 'get module definitions is performed with cm handle id' - objectUnderTest.getModuleDefinitionsByCmHandleId('some-cm-handle') - then: 'ncmp inventory persistence service is invoked once with correct parameter' - 1 * mockInventoryPersistence.getModuleDefinitionsByCmHandleId('some-cm-handle') - } - - def 'Execute cm handle search'() { - given: 'valid CmHandleQueryApiParameters input' - def cmHandleQueryApiParameters = new CmHandleQueryApiParameters() - def conditionApiProperties = new ConditionApiProperties() - conditionApiProperties.conditionName = 'hasAllModules' - conditionApiProperties.conditionParameters = [[moduleName: 'module-name-1']] - cmHandleQueryApiParameters.cmHandleQueryParameters = [conditionApiProperties] - and: 'query cm handle method return with a data node list' - mockCpsCmHandlerQueryService.queryCmHandles( - spiedJsonObjectMapper.convertToValueType(cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class)) - >> [new NcmpServiceCmHandle(cmHandleId: 'cm-handle-id-1')] - when: 'execute cm handle search is called' - def result = objectUnderTest.executeCmHandleSearch(cmHandleQueryApiParameters) - then: 'result is the same collection as returned by the CPS Data Service' - assert result.stream().map(d -> d.cmHandleId).collect(Collectors.toSet()) == ['cm-handle-id-1'] as Set - } - - def 'Set Cm Handle Data Sync Enabled Flag where data sync flag is #scenario'() { - given: 'an existing cm handle composite state' - def compositeState = new CompositeState(cmHandleState: CmHandleState.READY, dataSyncEnabled: initialDataSyncEnabledFlag, - dataStores: CompositeState.DataStores.builder() - .operationalDataStore(CompositeState.Operational.builder() - .dataStoreSyncState(initialDataSyncState) - .build()).build()) - and: 'get cm handle state returns the composite state for the given cm handle id' - mockInventoryPersistence.getCmHandleState('some-cm-handle-id') >> compositeState - when: 'set data sync enabled is called with the data sync enabled flag set to #dataSyncEnabledFlag' - objectUnderTest.setDataSyncEnabled('some-cm-handle-id', dataSyncEnabledFlag) - then: 'the data sync enabled flag is set to #dataSyncEnabled' - compositeState.dataSyncEnabled == dataSyncEnabledFlag - and: 'the data store sync state is set to #expectedDataStoreSyncState' - compositeState.dataStores.operationalDataStore.dataStoreSyncState == expectedDataStoreSyncState - and: 'the cps data service to delete data nodes is invoked the expected number of times' - deleteDataNodeExpectedNumberOfInvocation * mockCpsDataService.deleteDataNode(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, 'some-cm-handle-id', '/netconf-state', _) - and: 'the inventory persistence service to update node leaves is called with the correct values' - saveCmHandleStateExpectedNumberOfInvocations * mockInventoryPersistence.saveCmHandleState('some-cm-handle-id', compositeState) - where: 'the following data sync enabled flag is used' - scenario | dataSyncEnabledFlag | initialDataSyncEnabledFlag | initialDataSyncState || expectedDataStoreSyncState | deleteDataNodeExpectedNumberOfInvocation | saveCmHandleStateExpectedNumberOfInvocations - 'enabled' | true | false | DataStoreSyncState.NONE_REQUESTED || DataStoreSyncState.UNSYNCHRONIZED | 0 | 1 - 'disabled' | false | true | DataStoreSyncState.UNSYNCHRONIZED || DataStoreSyncState.NONE_REQUESTED | 0 | 1 - 'disabled where sync-state is currently SYNCHRONIZED' | false | true | DataStoreSyncState.SYNCHRONIZED || DataStoreSyncState.NONE_REQUESTED | 1 | 1 - 'is set to existing flag state' | true | true | DataStoreSyncState.UNSYNCHRONIZED || DataStoreSyncState.UNSYNCHRONIZED | 0 | 0 - } - - def 'Set cm Handle Data Sync Enabled flag with following cm handle not in ready state exception' () { - given: 'a cm handle composite state' - def compositeState = new CompositeState(cmHandleState: CmHandleState.ADVISED, dataSyncEnabled: false) - and: 'get cm handle state returns the composite state for the given cm handle id' - mockInventoryPersistence.getCmHandleState('some-cm-handle-id') >> compositeState - when: 'set data sync enabled is called with the data sync enabled flag set to true' - objectUnderTest.setDataSyncEnabled('some-cm-handle-id', true) - then: 'the expected exception is thrown' - thrown(CpsException) - and: 'the inventory persistence service to update node leaves is not invoked' - 0 * mockInventoryPersistence.saveCmHandleState(_, _) - } - - def 'Get all cm handle IDs by DMI plugin identifier.' () { - given: 'cm handle queries service returns cm handles' - 1 * mockCmHandleQueries.getCmHandleIdsByDmiPluginIdentifier('some-dmi-plugin-identifier') >> ['cm-handle-1','cm-handle-2'] - when: 'cm handle Ids are requested with dmi plugin identifier' - def result = objectUnderTest.getAllCmHandleIdsByDmiPluginIdentifier('some-dmi-plugin-identifier') - then: 'the result size is correct' - assert result.size() == 2 - and: 'the result returns the correct details' - assert result.containsAll('cm-handle-1','cm-handle-2') - } - - def dataStores() { - CompositeState.DataStores.builder() - .operationalDataStore(CompositeState.Operational.builder() - .dataStoreSyncState(DataStoreSyncState.NONE_REQUESTED) - .lastSyncTime('some-timestamp').build()).build() - } - - def mockDataNode() { - mockCpsDataService.getDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, cmHandleXPath, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> dataNode - } - - def getDataOperationRequest(datastore) { - def dataOperationRequest = new DataOperationRequest() - def dataOperationDefinitions = new ArrayList() - dataOperationDefinitions.add(getDataOperationDefinition(datastore)) - dataOperationRequest.setDataOperationDefinitions(dataOperationDefinitions) - return dataOperationRequest - } - - def getDataOperationDefinition(datastore) { - def dataOperationDefinition = new DataOperationDefinition() - dataOperationDefinition.setOperation("read") - dataOperationDefinition.setOperationId("operational-12") - dataOperationDefinition.setDatastore(datastore) - def targetIds = new ArrayList() - targetIds.add("some-cm-handle") - dataOperationDefinition.setCmHandleIds(targetIds) - return dataOperationDefinition - } -} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyFacadeSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyFacadeSpec.groovy new file mode 100644 index 000000000..f79e0ee2e --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyFacadeSpec.groovy @@ -0,0 +1,108 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2021-2024 Nordix Foundation + * Modifications Copyright (C) 2021 Pantheon.tech + * Modifications Copyright (C) 2021-2022 Bell Canada + * Modifications Copyright (C) 2023 TechMahindra Ltd. + * ================================================================================ + * 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.impl + +import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations +import org.onap.cps.ncmp.api.models.CmResourceAddress +import org.onap.cps.ncmp.api.models.DataOperationRequest +import org.onap.cps.spi.model.DataNode +import reactor.core.publisher.Mono +import spock.lang.Specification + +import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.OPERATIONAL +import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_OPERATIONAL +import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_RUNNING +import static org.onap.cps.ncmp.api.impl.operations.OperationType.CREATE +import static org.onap.cps.ncmp.api.impl.operations.OperationType.UPDATE + +class NetworkCmProxyFacadeSpec extends Specification { + + def mockDmiDataOperations = Mock(DmiDataOperations) + def mockNcmpCachedResourceRequestHandler = Mock(NcmpCachedResourceRequestHandler) + def mockNcmpPassthroughResourceRequestHandler = Mock(NcmpPassthroughResourceRequestHandler) + + def objectUnderTest = new NetworkCmProxyFacade(mockNcmpCachedResourceRequestHandler, mockNcmpPassthroughResourceRequestHandler, mockDmiDataOperations) + + def NO_TOPIC = null + + def 'Execute Data Operation for CM Handles (delegation).'() { + given: 'a data operation request' + def dataOperationRequest = Mock(DataOperationRequest) + and: ' a response from the (mocked) pass-through request handler for the given parameters' + def responseFromHandler = [attr:'value'] + mockNcmpPassthroughResourceRequestHandler.executeAsynchronousRequest('topic', dataOperationRequest, 'authorization') >> responseFromHandler + expect: 'the response form the handler' + assert objectUnderTest.executeDataOperationForCmHandles('topic', dataOperationRequest, 'authorization') == responseFromHandler + } + + def 'Query Resource Data for cm handle (delegation).'() { + given: 'a response from the (mocked) cached data handler for the given parameters' + def responseFromHandler = [Mock(DataNode)] + mockNcmpCachedResourceRequestHandler.executeRequest('ch-1', 'some cps path', true) >> responseFromHandler + expect: 'the response form the handler' + assert objectUnderTest.queryResourceDataForCmHandle('ch-1','some cps path',true) == responseFromHandler + } + + def 'Choosing Data Request Handler.'() { + expect: '(a mock of) #expectedHandler' + assert objectUnderTest.getNcmpDatastoreRequestHandler(datastore.datastoreName).class.name.startsWith(expectedHandler.name) + where: + datastore || expectedHandler + OPERATIONAL || NcmpCachedResourceRequestHandler.class + PASSTHROUGH_RUNNING || NcmpPassthroughResourceRequestHandler.class + PASSTHROUGH_OPERATIONAL || NcmpPassthroughResourceRequestHandler.class + } + + def 'Write resource data for pass-through running from DMI using POST (delegation).'() { + when: 'write resource data is called' + objectUnderTest.writeResourceDataPassThroughRunningForCmHandle('testCmHandle', + 'testResourceId', CREATE, + '{some-json}', 'application/json', null) + then: 'DMI called with correct data' + 1 * mockDmiDataOperations.writeResourceDataPassThroughRunningFromDmi('testCmHandle', 'testResourceId', CREATE, '{some-json}', 'application/json', null) + } + + def 'Get resource data from DMI (delegation).'() { + given: 'a cm resource address for datastore operational' + def cmResourceAddress = new CmResourceAddress('ncmp-datastore:operational', 'some CM Handle', 'some resource Id') + and: 'get resource data from DMI is called' + mockNcmpCachedResourceRequestHandler.executeRequest(cmResourceAddress, 'options', NO_TOPIC, false, 'authorization') >> + Mono.just('dmi response') + when: 'get resource data operational for the given cm resource address is called' + def response = objectUnderTest.getResourceDataForCmHandle(cmResourceAddress, 'options', NO_TOPIC, false, 'authorization').block() + then: 'DMI returns a json response' + assert response == 'dmi response' + } + + def 'Update resource data for pass-through running from dmi (delegation).'() { + when: 'get resource data is called' + objectUnderTest.writeResourceDataPassThroughRunningForCmHandle('testCmHandle', + 'testResourceId', UPDATE, + '{some-json}', 'application/json', 'authorization') + then: 'DMI called with correct data' + 1 * mockDmiDataOperations.writeResourceDataPassThroughRunningFromDmi('testCmHandle', 'testResourceId', UPDATE, '{some-json}', 'application/json', 'authorization') + } + + +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyInventoryFacadeSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyInventoryFacadeSpec.groovy new file mode 100644 index 000000000..f704dbb3d --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyInventoryFacadeSpec.groovy @@ -0,0 +1,226 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2021-2024 Nordix Foundation + * Modifications Copyright (C) 2021 Pantheon.tech + * Modifications Copyright (C) 2021-2022 Bell Canada + * Modifications Copyright (C) 2023 TechMahindra Ltd. + * ================================================================================ + * 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.impl + +import com.fasterxml.jackson.databind.ObjectMapper +import org.onap.cps.ncmp.api.ParameterizedCmHandleQueryService +import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueryService +import org.onap.cps.ncmp.api.impl.inventory.CmHandleState +import org.onap.cps.ncmp.api.impl.inventory.CompositeState +import org.onap.cps.ncmp.api.impl.inventory.DataStoreSyncState +import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence +import org.onap.cps.ncmp.api.impl.inventory.LockReasonCategory +import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle +import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters +import org.onap.cps.ncmp.api.models.CmHandleQueryServiceParameters +import org.onap.cps.ncmp.api.models.ConditionApiProperties +import org.onap.cps.ncmp.api.models.DmiPluginRegistration +import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle +import org.onap.cps.spi.model.ConditionProperties +import org.onap.cps.utils.JsonObjectMapper +import spock.lang.Specification + +import java.util.stream.Collectors + +class NetworkCmProxyInventoryFacadeSpec extends Specification { + + def mockCmHandleRegistrationService = Mock(CmHandleRegistrationService) + def mockCmHandleQueryService = Mock(CmHandleQueryService) + def mockParameterizedCmHandleQueryService = Mock(ParameterizedCmHandleQueryService) + def spiedJsonObjectMapper = Spy(new JsonObjectMapper(new ObjectMapper())) + def mockInventoryPersistence = Mock(InventoryPersistence) + + def objectUnderTest = new NetworkCmProxyInventoryFacade(mockCmHandleRegistrationService, mockCmHandleQueryService, mockParameterizedCmHandleQueryService, mockInventoryPersistence, spiedJsonObjectMapper) + + def 'Update DMI Registration'() { + given: 'an (updated) dmi plugin registration' + def dmiPluginRegistration = Mock(DmiPluginRegistration) + when: 'the registration is submitted ' + objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration) + then: 'the call is delegated to the cm handle registration service' + 1 * mockCmHandleRegistrationService.updateDmiRegistrationAndSyncModule(dmiPluginRegistration) + } + + def 'Execute cm handle id search for inventory'() { + given: 'a ConditionApiProperties object' + def conditionProperties = new ConditionProperties() + conditionProperties.conditionName = 'hasAllProperties' + conditionProperties.conditionParameters = [ [ 'some-key' : 'some-value' ] ] + def cmHandleQueryServiceParameters = new CmHandleQueryServiceParameters() + cmHandleQueryServiceParameters.cmHandleQueryParameters = [conditionProperties] as List<ConditionProperties> + and: 'the system returns an set of cmHandle ids' + mockParameterizedCmHandleQueryService.queryCmHandleIdsForInventory(*_) >> [ 'cmHandle1', 'cmHandle2' ] + when: 'executing the search' + def result = objectUnderTest.executeParameterizedCmHandleIdSearch(cmHandleQueryServiceParameters) + then: 'the result returns the correct 2 elements' + assert result.size() == 2 + assert result.contains('cmHandle1') + assert result.contains('cmHandle2') + } + + def 'Get all cm handle IDs by DMI plugin identifier.' () { + given: 'cm handle queries service returns cm handles' + 1 * mockCmHandleQueryService.getCmHandleIdsByDmiPluginIdentifier('some-dmi-plugin-identifier') >> ['cm-handle-1','cm-handle-2'] + when: 'cm handle Ids are requested with dmi plugin identifier' + def result = objectUnderTest.getAllCmHandleIdsByDmiPluginIdentifier('some-dmi-plugin-identifier') + then: 'the result size is correct' + assert result.size() == 2 + and: 'the result returns the correct details' + assert result.containsAll('cm-handle-1','cm-handle-2') + } + + def 'Getting Yang Resources.'() { + when: 'yang resources is called' + objectUnderTest.getYangResourcesModuleReferences('some-cm-handle') + then: 'CPS module services is invoked for the correct dataspace and cm handle' + 1 * mockInventoryPersistence.getYangResourcesModuleReferences('some-cm-handle') + } + + def 'Get a cm handle.'() { + given: 'the system returns a yang modelled cm handle' + def dmiServiceName = 'some service name' + def compositeState = new CompositeState(cmHandleState: CmHandleState.ADVISED, + lockReason: CompositeState.LockReason.builder().lockReasonCategory(LockReasonCategory.MODULE_SYNC_FAILED).details("lock details").build(), + lastUpdateTime: 'some-timestamp', + dataSyncEnabled: false, + dataStores: dataStores()) + def dmiProperties = [new YangModelCmHandle.Property('Book', 'Romance Novel')] + def publicProperties = [new YangModelCmHandle.Property('Public Book', 'Public Romance Novel')] + def moduleSetTag = 'some-module-set-tag' + def alternateId = 'some-alternate-id' + def yangModelCmHandle = new YangModelCmHandle(id: 'some-cm-handle', dmiServiceName: dmiServiceName, + dmiProperties: dmiProperties, publicProperties: publicProperties, compositeState: compositeState, + moduleSetTag: moduleSetTag, alternateId: alternateId) + 1 * mockInventoryPersistence.getYangModelCmHandle('some-cm-handle') >> yangModelCmHandle + when: 'getting cm handle details for a given cm handle id from ncmp service' + def result = objectUnderTest.getNcmpServiceCmHandle('some-cm-handle') + then: 'the result is a ncmpServiceCmHandle' + result.class == NcmpServiceCmHandle.class + and: 'the cm handle contains the cm handle id' + result.cmHandleId == 'some-cm-handle' + and: 'the cm handle contains the alternate id' + result.alternateId == 'some-alternate-id' + and: 'the cm handle contains the module-set-tag' + result.moduleSetTag == 'some-module-set-tag' + and: 'the cm handle contains the DMI Properties' + result.dmiProperties ==[ Book:'Romance Novel' ] + and: 'the cm handle contains the public Properties' + result.publicProperties == [ "Public Book":'Public Romance Novel' ] + and: 'the cm handle contains the cm handle composite state' + result.compositeState == compositeState + } + + def 'Get cm handle public properties'() { + given: 'a yang modelled cm handle' + def dmiProperties = [new YangModelCmHandle.Property('prop', 'some DMI property')] + def publicProperties = [new YangModelCmHandle.Property('public prop', 'some public prop')] + def yangModelCmHandle = new YangModelCmHandle(id:'some-cm-handle', dmiServiceName: 'some service name', dmiProperties: dmiProperties, publicProperties: publicProperties) + and: 'the system returns this yang modelled cm handle' + 1 * mockInventoryPersistence.getYangModelCmHandle('some-cm-handle') >> yangModelCmHandle + when: 'getting cm handle public properties for a given cm handle id from ncmp service' + def result = objectUnderTest.getCmHandlePublicProperties('some-cm-handle') + then: 'the result returns the correct data' + result == [ 'public prop' : 'some public prop' ] + } + + def 'Get cm handle composite state'() { + given: 'a yang modelled cm handle' + def compositeState = new CompositeState(cmHandleState: CmHandleState.ADVISED, + lockReason: CompositeState.LockReason.builder().lockReasonCategory(LockReasonCategory.MODULE_SYNC_FAILED).details("lock details").build(), + lastUpdateTime: 'some-timestamp', + dataSyncEnabled: false, + dataStores: dataStores()) + def dmiProperties = [new YangModelCmHandle.Property('prop', 'some DMI property')] + def publicProperties = [new YangModelCmHandle.Property('public prop', 'some public prop')] + def yangModelCmHandle = new YangModelCmHandle(id:'some-cm-handle', dmiServiceName: 'some service name', dmiProperties: dmiProperties, publicProperties: publicProperties, compositeState: compositeState) + and: 'the system returns this yang modelled cm handle' + 1 * mockInventoryPersistence.getYangModelCmHandle('some-cm-handle') >> yangModelCmHandle + when: 'getting cm handle composite state for a given cm handle id from ncmp service' + def result = objectUnderTest.getCmHandleCompositeState('some-cm-handle') + then: 'the result returns the correct data' + result == compositeState + } + + def 'Execute cm handle id search'() { + given: 'valid CmHandleQueryApiParameters input' + def cmHandleQueryApiParameters = new CmHandleQueryApiParameters() + def conditionApiProperties = new ConditionApiProperties() + conditionApiProperties.conditionName = 'hasAllModules' + conditionApiProperties.conditionParameters = [[moduleName: 'module-name-1']] + cmHandleQueryApiParameters.cmHandleQueryParameters = [conditionApiProperties] + and: 'query cm handle method return with a data node list' + mockParameterizedCmHandleQueryService.queryCmHandleIds( + spiedJsonObjectMapper.convertToValueType(cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class)) + >> ['cm-handle-id-1'] + when: 'execute cm handle search is called' + def result = objectUnderTest.executeCmHandleIdSearch(cmHandleQueryApiParameters) + then: 'result is the same collection as returned by the CPS Data Service' + assert result == ['cm-handle-id-1'] + } + + def 'Getting module definitions by module'() { + when: 'get module definitions is performed with module name' + objectUnderTest.getModuleDefinitionsByCmHandleAndModule('some-cm-handle', 'some-module', '2021-08-04') + then: 'ncmp inventory persistence service is invoked once with correct parameters' + 1 * mockInventoryPersistence.getModuleDefinitionsByCmHandleAndModule('some-cm-handle', 'some-module', '2021-08-04') + } + + def 'Getting module definitions by cm handle id'() { + when: 'get module definitions is performed with cm handle id' + objectUnderTest.getModuleDefinitionsByCmHandleId('some-cm-handle') + then: 'ncmp inventory persistence service is invoked once with correct parameter' + 1 * mockInventoryPersistence.getModuleDefinitionsByCmHandleId('some-cm-handle') + } + + def 'Execute cm handle search'() { + given: 'valid CmHandleQueryApiParameters input' + def cmHandleQueryApiParameters = new CmHandleQueryApiParameters() + def conditionApiProperties = new ConditionApiProperties() + conditionApiProperties.conditionName = 'hasAllModules' + conditionApiProperties.conditionParameters = [[moduleName: 'module-name-1']] + cmHandleQueryApiParameters.cmHandleQueryParameters = [conditionApiProperties] + and: 'query cm handle method return with a data node list' + mockParameterizedCmHandleQueryService.queryCmHandles( + spiedJsonObjectMapper.convertToValueType(cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class)) + >> [new NcmpServiceCmHandle(cmHandleId: 'cm-handle-id-1')] + when: 'execute cm handle search is called' + def result = objectUnderTest.executeCmHandleSearch(cmHandleQueryApiParameters) + then: 'result is the same collection as returned by the CPS Data Service' + assert result.stream().map(cmHandle -> cmHandle.cmHandleId).collect(Collectors.toSet()) == ['cm-handle-id-1'] as Set + } + + def 'Set Cm Handle Data Sync flag.'() { + when: 'setting data sync enabled flag' + objectUnderTest.setDataSyncEnabled('ch-1',true) + then: 'call is delegated to the cm handle registration service' + mockCmHandleRegistrationService.setDataSyncEnabled('ch-1', true) + } + + def dataStores() { + CompositeState.DataStores.builder() + .operationalDataStore(CompositeState.Operational.builder() + .dataStoreSyncState(DataStoreSyncState.NONE_REQUESTED) + .lastSyncTime('some-timestamp').build()).build() + } +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandleQueryServiceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/ParameterizedCmHandleQueryServiceSpec.groovy index 7c410cc58..a928a0432 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandleQueryServiceSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/ParameterizedCmHandleQueryServiceSpec.groovy @@ -24,8 +24,7 @@ import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DM import org.onap.cps.cpspath.parser.PathParsingException import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle -import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueries -import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueriesImpl +import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueryService import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence import org.onap.cps.ncmp.api.models.CmHandleQueryServiceParameters import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle @@ -36,16 +35,16 @@ import org.onap.cps.spi.model.ConditionProperties import org.onap.cps.spi.model.DataNode import spock.lang.Specification -class NetworkCmProxyCmHandleQueryServiceSpec extends Specification { +class ParameterizedCmHandleQueryServiceSpec extends Specification { - def cmHandleQueries = Mock(CmHandleQueries) - def partiallyMockedCmHandleQueries = Spy(CmHandleQueries) + def cmHandleQueries = Mock(CmHandleQueryService) + def partiallyMockedCmHandleQueries = Spy(CmHandleQueryService) def mockInventoryPersistence = Mock(InventoryPersistence) def dmiRegistry = new DataNode(xpath: NCMP_DMI_REGISTRY_PARENT, childDataNodes: createDataNodeList(['PNFDemo1', 'PNFDemo2', 'PNFDemo3', 'PNFDemo4'])) - def objectUnderTest = new NetworkCmProxyCmHandleQueryServiceImpl(cmHandleQueries, mockInventoryPersistence) - def objectUnderTestWithPartiallyMockedQueries = new NetworkCmProxyCmHandleQueryServiceImpl(partiallyMockedCmHandleQueries, mockInventoryPersistence) + def objectUnderTest = new ParameterizedCmHandleQueryServiceImpl(cmHandleQueries, mockInventoryPersistence) + def objectUnderTestWithPartiallyMockedQueries = new ParameterizedCmHandleQueryServiceImpl(partiallyMockedCmHandleQueries, mockInventoryPersistence) def 'Query cm handle ids with cpsPath.'() { given: 'a cmHandleWithCpsPath condition property' diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy index 2c2212773..bb73c6879 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/client/DmiRestClientSpec.groovy @@ -21,33 +21,32 @@ package org.onap.cps.ncmp.api.impl.client -import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNKNOWN_ERROR -import static org.onap.cps.ncmp.api.impl.operations.OperationType.CREATE -import static org.onap.cps.ncmp.api.impl.operations.OperationType.PATCH -import static org.onap.cps.ncmp.api.impl.operations.OperationType.READ -import static org.onap.cps.ncmp.api.impl.operations.RequiredDmiService.DATA -import static org.springframework.http.HttpStatus.SERVICE_UNAVAILABLE -import static org.onap.cps.ncmp.api.NcmpResponseStatus.DMI_SERVICE_NOT_RESPONDING -import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNABLE_TO_READ_RESOURCE_DATA - import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.node.ObjectNode +import org.onap.cps.ncmp.api.impl.config.DmiProperties import org.onap.cps.ncmp.api.impl.exception.DmiClientRequestException import org.onap.cps.ncmp.api.impl.exception.InvalidDmiResourceUrlException -import org.onap.cps.ncmp.api.impl.config.DmiProperties import org.onap.cps.ncmp.utils.TestUtils import org.onap.cps.utils.JsonObjectMapper import org.springframework.http.HttpHeaders import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity -import org.springframework.web.client.HttpServerErrorException import org.springframework.web.reactive.function.client.WebClient -import org.springframework.web.reactive.function.client.WebClientResponseException import org.springframework.web.reactive.function.client.WebClientRequestException +import org.springframework.web.reactive.function.client.WebClientResponseException import reactor.core.publisher.Mono import spock.lang.Specification +import static org.onap.cps.ncmp.api.NcmpResponseStatus.DMI_SERVICE_NOT_RESPONDING +import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNABLE_TO_READ_RESOURCE_DATA +import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNKNOWN_ERROR +import static org.onap.cps.ncmp.api.impl.operations.OperationType.CREATE +import static org.onap.cps.ncmp.api.impl.operations.OperationType.PATCH +import static org.onap.cps.ncmp.api.impl.operations.OperationType.READ +import static org.onap.cps.ncmp.api.impl.operations.RequiredDmiService.DATA +import static org.onap.cps.ncmp.api.impl.operations.RequiredDmiService.MODEL + class DmiRestClientSpec extends Specification { static final NO_AUTH_HEADER = null @@ -61,7 +60,6 @@ class DmiRestClientSpec extends Specification { def mockRequestBody = Mock(WebClient.RequestBodyUriSpec) def mockResponse = Mock(WebClient.ResponseSpec) - def responseBody = [message: 'Success'] def mockDmiProperties = Mock(DmiProperties) JsonObjectMapper jsonObjectMapper = new JsonObjectMapper(new ObjectMapper()) @@ -75,34 +73,31 @@ class DmiRestClientSpec extends Specification { mockRequestBody.retrieve() >> mockResponse } - def 'DMI POST Operation with JSON for status #httpStatusCode'() { - given: 'the web client returns a valid response entity for the expected parameters' + def 'DMI POST Operation with JSON for DMI Data Service '() { + given: 'the Data web client returns a valid response entity for the expected parameters' mockDataServicesWebClient.post() >> mockRequestBody - mockResponse.toEntity(Object.class) >> Mono.just(new ResponseEntity<>(responseBody, httpStatusCode)) - when: 'POST operation is invoked' - def response = objectUnderTest.postOperationWithJsonData(DATA, '/my/url', 'some json', READ, NO_AUTH_HEADER) + mockResponse.toEntity(Object.class) >> Mono.just(new ResponseEntity<>('from Data service', HttpStatus.I_AM_A_TEAPOT)) + when: 'POST operation is invoked fro Data Service' + def response = objectUnderTest.synchronousPostOperationWithJsonData(DATA, '/my/url', 'some json', READ, NO_AUTH_HEADER) then: 'the output of the method is equal to the output from the test template' - assert response.statusCode == httpStatusCode - assert response.body == responseBody - where: 'the following status codes are used' - httpStatusCode << [HttpStatus.OK, HttpStatus.CREATED, HttpStatus.ACCEPTED] + assert response.statusCode == HttpStatus.I_AM_A_TEAPOT + assert response.body == 'from Data service' } - def 'Failing DMI POST operation for server error'() { - given: 'the web client throws an exception' - mockDataServicesWebClient.post() >> { throw new HttpServerErrorException(SERVICE_UNAVAILABLE, null, null, null) } - when: 'POST operation is invoked' - objectUnderTest.postOperationWithJsonData(DATA, '/some', 'some json', READ, NO_AUTH_HEADER) - then: 'a http client exception is thrown' - def thrown = thrown(DmiClientRequestException) - and: 'the exception has the relevant details from the error response' - thrown.ncmpResponseStatus.code == '102' - thrown.httpStatusCode == 503 + def 'DMI POST Operation with JSON for DMI Model Service '() { + given: 'the Model web client returns a valid response entity for the expected parameters' + mockModelServicesWebClient.post() >> mockRequestBody + mockResponse.toEntity(Object.class) >> Mono.just(new ResponseEntity<>('from Model service', HttpStatus.I_AM_A_TEAPOT)) + when: 'POST operation is invoked for Model Service' + def response = objectUnderTest.synchronousPostOperationWithJsonData(MODEL, '/my/url', 'some json', READ, NO_AUTH_HEADER) + then: 'the output of the method is equal to the output from the test template' + assert response.statusCode == HttpStatus.I_AM_A_TEAPOT + assert response.body == 'from Model service' } def 'Failing DMI POST operation due to invalid dmi resource url.'() { when: 'POST operation is invoked with invalid dmi resource url' - objectUnderTest.postOperationWithJsonData(DATA, '/invalid dmi url', null, null, NO_AUTH_HEADER) + objectUnderTest.synchronousPostOperationWithJsonData(DATA, '/invalid dmi url', null, null, NO_AUTH_HEADER) then: 'invalid dmi resource url exception is thrown' def thrown = thrown(InvalidDmiResourceUrlException) and: 'the exception has the relevant details from the error response' @@ -117,7 +112,7 @@ class DmiRestClientSpec extends Specification { mockDataServicesWebClient.post() >> mockRequestBody mockResponse.toEntity(Object.class) >> Mono.error(exceptionType) when: 'POST operation is invoked' - objectUnderTest.postOperationWithJsonData(DATA, '/my/url', 'some json', READ, NO_AUTH_HEADER) + objectUnderTest.synchronousPostOperationWithJsonData(DATA, '/my/url', 'some json', READ, NO_AUTH_HEADER) then: 'a http client exception is thrown' def thrown = thrown(DmiClientRequestException) and: 'the exception has the relevant details from the error response' @@ -176,4 +171,4 @@ class DmiRestClientSpec extends Specification { 'DMI basic auth disabled, with NCMP bearer token' | false | BEARER_AUTH_HEADER || BEARER_AUTH_HEADER 'DMI basic auth disabled, with NCMP basic auth' | false | BASIC_AUTH_HEADER || NO_AUTH_HEADER } -}
\ No newline at end of file +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/CmHandleQueriesImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/CmHandleQueryServiceImplSpec.groovy index 2f9d26494..bdf431855 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/CmHandleQueriesImplSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/CmHandleQueryServiceImplSpec.groovy @@ -33,7 +33,7 @@ import org.onap.cps.spi.model.DataNode import spock.lang.Shared import spock.lang.Specification -class CmHandleQueriesImplSpec extends Specification { +class CmHandleQueryServiceImplSpec extends Specification { def mockCpsDataPersistenceService = Mock(CpsDataPersistenceService) @@ -43,7 +43,7 @@ class CmHandleQueriesImplSpec extends Specification { def mockCpsValidator = Mock(CpsValidator) - def objectUnderTest = new CmHandleQueriesImpl(mockCpsDataPersistenceService, trustLevelPerDmiPlugin, trustLevelPerCmHandle, mockCpsValidator) + def objectUnderTest = new CmHandleQueryServiceImpl(mockCpsDataPersistenceService, trustLevelPerDmiPlugin, trustLevelPerCmHandle, mockCpsValidator) @Shared def static sampleDataNodes = [new DataNode()] diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImplSpec.groovy index 66fd7d88e..775824bb0 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImplSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/InventoryPersistenceImplSpec.groovy @@ -61,7 +61,7 @@ class InventoryPersistenceImplSpec extends Specification { def mockCpsValidator = Mock(CpsValidator) - def mockCmHandleQueries = Mock(CmHandleQueries) + def mockCmHandleQueries = Mock(CmHandleQueryService) def objectUnderTest = new InventoryPersistenceImpl(spiedJsonObjectMapper, mockCpsDataService, mockCpsModuleService, mockCpsValidator, mockCpsAnchorService, mockCmHandleQueries) diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleOperationsUtilsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleOperationsUtilsSpec.groovy index 44bc18200..e9038ecfc 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleOperationsUtilsSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleOperationsUtilsSpec.groovy @@ -35,7 +35,7 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.ObjectMapper import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations -import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueries +import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueryService import org.onap.cps.ncmp.api.impl.inventory.CmHandleState import org.onap.cps.ncmp.api.impl.inventory.CompositeState import org.onap.cps.ncmp.api.impl.inventory.CompositeStateBuilder @@ -52,7 +52,7 @@ import java.util.stream.Collectors class ModuleOperationsUtilsSpec extends Specification{ - def mockCmHandleQueries = Mock(CmHandleQueries) + def mockCmHandleQueries = Mock(CmHandleQueryService) def mockDmiDataOperations = Mock(DmiDataOperations) @@ -202,7 +202,7 @@ class ModuleOperationsUtilsSpec extends Specification{ def jsonString = '{"stores:bookstore":{"categories":[{"code":"01"}]}}' JsonNode jsonNode = jsonObjectMapper.convertToJsonNode(jsonString); def responseEntity = new ResponseEntity<>(jsonNode, HttpStatus.OK) - mockDmiDataOperations.getResourceDataFromDmi(PASSTHROUGH_OPERATIONAL.datastoreName, 'cm-handle-123', _) >> responseEntity + mockDmiDataOperations.getAllResourceDataFromDmi('cm-handle-123', _) >> responseEntity when: 'get resource data is called' def result = objectUnderTest.getResourceData('cm-handle-123') then: 'the returned data is correct' diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncServiceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncServiceSpec.groovy index cb933fafb..9f7b95300 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncServiceSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncServiceSpec.groovy @@ -32,7 +32,7 @@ import org.onap.cps.api.CpsModuleService import org.onap.cps.spi.model.DataNodeBuilder import org.onap.cps.ncmp.api.impl.operations.DmiModelOperations import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle -import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueries +import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueryService import org.onap.cps.ncmp.api.impl.inventory.CompositeStateBuilder import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle import org.onap.cps.spi.CascadeDeleteAllowed @@ -46,7 +46,7 @@ class ModuleSyncServiceSpec extends Specification { def mockCpsModuleService = Mock(CpsModuleService) def mockDmiModelOperations = Mock(DmiModelOperations) def mockCpsAnchorService = Mock(CpsAnchorService) - def mockCmHandleQueries = Mock(CmHandleQueries) + def mockCmHandleQueries = Mock(CmHandleQueryService) def mockCpsDataService = Mock(CpsDataService) def mockJsonObjectMapper = Mock(JsonObjectMapper) 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 b286e9fb1..a0c6d0027 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 @@ -78,7 +78,7 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec { def responseFromDmi = Mono.just(new ResponseEntity<Object>('{some-key:some-value}', HttpStatus.OK)) def expectedUrl = "${dmiServiceBaseUrl}${expectedDatastoreInUrl}?resourceIdentifier=${resourceIdentifier}${expectedOptionsInUrl}" def expectedJson = '{"operation":"read","cmHandleProperties":' + expectedProperties + ',"moduleSetTag":""}' - mockDmiRestClient.postOperationWithJsonDataAsync(DATA, expectedUrl, expectedJson, READ, NO_AUTH_HEADER) >> responseFromDmi + mockDmiRestClient.asynchronousPostOperationWithJsonData(DATA, expectedUrl, expectedJson, READ, NO_AUTH_HEADER) >> responseFromDmi when: 'get resource data is invoked' def cmResourceAddress = new CmResourceAddress(dataStore.datastoreName, cmHandleId, resourceIdentifier) def result = objectUnderTest.getResourceDataFromDmi(cmResourceAddress, options, NO_TOPIC, NO_REQUEST_ID, NO_AUTH_HEADER).block() @@ -105,11 +105,11 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec { def responseFromDmi = Mono.just(new ResponseEntity<Object>(HttpStatus.ACCEPTED)) def expectedDmiBatchResourceDataUrl = "someServiceName/dmi/v1/data?requestId=requestId&topic=my-topic-name" def expectedBatchRequestAsJson = '{"operations":[{"operation":"read","operationId":"operational-14","datastore":"ncmp-datastore:passthrough-operational","options":"some option","resourceIdentifier":"some resource identifier","cmHandles":[{"id":"some-cm-handle","moduleSetTag":"","cmHandleProperties":{"prop1":"val1"}}]}]}' - mockDmiRestClient.postOperationWithJsonDataAsync(DATA, expectedDmiBatchResourceDataUrl, _, READ, NO_AUTH_HEADER) >> responseFromDmi + mockDmiRestClient.asynchronousPostOperationWithJsonData(DATA, expectedDmiBatchResourceDataUrl, _, READ, NO_AUTH_HEADER) >> responseFromDmi when: 'get resource data for group of cm handles is invoked' objectUnderTest.requestResourceDataFromDmi('my-topic-name', dataOperationRequest, 'requestId', NO_AUTH_HEADER) then: 'the post operation was called with the expected URL and JSON request body' - 1 * mockDmiRestClient.postOperationWithJsonDataAsync(DATA, expectedDmiBatchResourceDataUrl, expectedBatchRequestAsJson, READ, NO_AUTH_HEADER) + 1 * mockDmiRestClient.asynchronousPostOperationWithJsonData(DATA, expectedDmiBatchResourceDataUrl, expectedBatchRequestAsJson, READ, NO_AUTH_HEADER) } def 'Execute (async) data operation from DMI service with Exception.'() { @@ -122,7 +122,7 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec { def actualDataOperationCloudEvent = null eventsPublisher.publishCloudEvent('my-topic-name', 'my-request-id', _) >> { args -> actualDataOperationCloudEvent = args[2] } and: 'a DMI client request exception is thrown when DMI service is called' - mockDmiRestClient.postOperationWithJsonDataAsync(*_) >> { Mono.error(new DmiClientRequestException(123, '', '', UNKNOWN_ERROR)) } + mockDmiRestClient.asynchronousPostOperationWithJsonData(*_) >> { Mono.error(new DmiClientRequestException(123, '', '', UNKNOWN_ERROR)) } when: 'attempt to get resource data for group of cm handles is invoked' objectUnderTest.requestResourceDataFromDmi('my-topic-name', dataOperationRequest, 'my-request-id', NO_AUTH_HEADER) then: 'the event contains the expected error details' @@ -141,9 +141,9 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec { def responseFromDmi = new ResponseEntity<Object>(HttpStatus.OK) def expectedUrl = dmiServiceBaseUrl + "passthrough-operational?resourceIdentifier=/" def expectedJson = '{"operation":"read","cmHandleProperties":{"prop1":"val1"},"moduleSetTag":"my-module-set-tag"}' - mockDmiRestClient.postOperationWithJsonData(DATA, expectedUrl, expectedJson, READ, null) >> responseFromDmi + mockDmiRestClient.synchronousPostOperationWithJsonData(DATA, expectedUrl, expectedJson, READ, null) >> responseFromDmi when: 'get resource data is invoked' - def result = objectUnderTest.getResourceDataFromDmi( PASSTHROUGH_OPERATIONAL.datastoreName, cmHandleId, NO_REQUEST_ID) + def result = objectUnderTest.getAllResourceDataFromDmi(cmHandleId, NO_REQUEST_ID) then: 'the result is the response from the DMI service' assert result == responseFromDmi } @@ -155,7 +155,7 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec { def expectedUrl = "${dmiServiceBaseUrl}passthrough-running?resourceIdentifier=${resourceIdentifier}" def expectedJson = '{"operation":"' + expectedOperationInUrl + '","dataType":"some data type","data":"requestData","cmHandleProperties":{"prop1":"val1"},"moduleSetTag":""}' def responseFromDmi = new ResponseEntity<Object>(HttpStatus.OK) - mockDmiRestClient.postOperationWithJsonData(DATA, expectedUrl, expectedJson, operation, NO_AUTH_HEADER) >> responseFromDmi + mockDmiRestClient.synchronousPostOperationWithJsonData(DATA, expectedUrl, expectedJson, operation, NO_AUTH_HEADER) >> responseFromDmi when: 'write resource method is invoked' def result = objectUnderTest.writeResourceDataPassThroughRunningFromDmi(cmHandleId, 'parent/child', operation, 'requestData', 'some data type', NO_AUTH_HEADER) then: 'the result is the response from the DMI service' 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 db7f26f5f..9ab52b946 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 @@ -59,7 +59,7 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec { 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(MODEL, expectedUrl, '{"cmHandleProperties":{},"moduleSetTag":""}', READ, NO_AUTH_HEADER) >> responseFromDmi + mockDmiRestClient.synchronousPostOperationWithJsonData(MODEL, expectedUrl, '{"cmHandleProperties":{},"moduleSetTag":""}', READ, NO_AUTH_HEADER) >> responseFromDmi when: 'get module references is called' def result = objectUnderTest.getModuleReferences(yangModelCmHandle) then: 'the result consists of expected module references' @@ -72,7 +72,7 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec { and: 'any response from DMI service when it is called with the expected parameters' // TODO (toine): production code ignores any error code from DMI, this should be improved in future def responseFromDmi = new ResponseEntity(bodyAsMap, HttpStatus.NO_CONTENT) - mockDmiRestClient.postOperationWithJsonData(*_) >> responseFromDmi + mockDmiRestClient.synchronousPostOperationWithJsonData(*_) >> responseFromDmi when: 'get module references is called' def result = objectUnderTest.getModuleReferences(yangModelCmHandle) then: 'the result is empty' @@ -90,7 +90,7 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec { mockYangModelCmHandleRetrieval(dmiProperties) and: 'a positive response from DMI service when it is called with tha expected parameters' def responseFromDmi = new ResponseEntity<String>(HttpStatus.OK) - mockDmiRestClient.postOperationWithJsonData(MODEL, "${dmiServiceName}/dmi/v1/ch/${cmHandleId}/modules", + mockDmiRestClient.synchronousPostOperationWithJsonData(MODEL, "${dmiServiceName}/dmi/v1/ch/${cmHandleId}/modules", '{"cmHandleProperties":' + expectedAdditionalPropertiesInRequest + ',"moduleSetTag":""}', READ, NO_AUTH_HEADER) >> responseFromDmi when: 'a get module references is called' def result = objectUnderTest.getModuleReferences(yangModelCmHandle) @@ -109,7 +109,7 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec { def responseFromDmi = new ResponseEntity([[moduleName: 'mod1', revision: 'A', yangSource: 'some yang source'], [moduleName: 'mod2', revision: 'C', yangSource: 'other yang source']], HttpStatus.OK) def expectedModuleReferencesInRequest = '{"name":"mod1","revision":"A"},{"name":"mod2","revision":"X"}' - mockDmiRestClient.postOperationWithJsonData(MODEL, "${dmiServiceName}/dmi/v1/ch/${cmHandleId}/moduleResources", + mockDmiRestClient.synchronousPostOperationWithJsonData(MODEL, "${dmiServiceName}/dmi/v1/ch/${cmHandleId}/moduleResources", '{"data":{"modules":[' + expectedModuleReferencesInRequest + ']},"cmHandleProperties":{}}', READ, NO_AUTH_HEADER) >> responseFromDmi when: 'get new yang resources from DMI service' def result = objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, newModuleReferences) @@ -125,7 +125,7 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec { and: 'a positive response from DMI service when it is called with tha expected parameters' // TODO (toine): production code ignores any error code from DMI, this should be improved in future def responseFromDmi = new ResponseEntity(responseFromDmiBody, HttpStatus.NO_CONTENT) - mockDmiRestClient.postOperationWithJsonData(*_) >> responseFromDmi + mockDmiRestClient.synchronousPostOperationWithJsonData(*_) >> responseFromDmi when: 'get new yang resources from DMI service' def result = objectUnderTest.getNewYangResourcesFromDmi(yangModelCmHandle, newModuleReferences) then: 'the result is empty' @@ -141,7 +141,7 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec { mockYangModelCmHandleRetrieval(dmiProperties) and: 'a positive response from DMI service when it is called with the expected moduleSetTag, modules and properties' def responseFromDmi = new ResponseEntity<>([[moduleName: 'mod1', revision: 'A', yangSource: 'some yang source']], HttpStatus.OK) - mockDmiRestClient.postOperationWithJsonData(MODEL, "${dmiServiceName}/dmi/v1/ch/${cmHandleId}/moduleResources", + mockDmiRestClient.synchronousPostOperationWithJsonData(MODEL, "${dmiServiceName}/dmi/v1/ch/${cmHandleId}/moduleResources", '{"data":{"modules":[{"name":"mod1","revision":"A"},{"name":"mod2","revision":"X"}]},"cmHandleProperties":' + expectedAdditionalPropertiesInRequest + '}', READ, NO_AUTH_HEADER) >> responseFromDmi when: 'get new yang resources from DMI service' @@ -159,7 +159,7 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec { mockYangModelCmHandleRetrieval([], moduleSetTag) and: 'a positive response from DMI service when it is called with the expected moduleSetTag' def responseFromDmi = new ResponseEntity<>([[moduleName: 'mod1', revision: 'A', yangSource: 'some yang source']], HttpStatus.OK) - mockDmiRestClient.postOperationWithJsonData(MODEL, "${dmiServiceName}/dmi/v1/ch/${cmHandleId}/moduleResources", + mockDmiRestClient.synchronousPostOperationWithJsonData(MODEL, "${dmiServiceName}/dmi/v1/ch/${cmHandleId}/moduleResources", '{' + expectedModuleSetTagInRequest + '"data":{"modules":[{"name":"mod1","revision":"A"},{"name":"mod2","revision":"X"}]},"cmHandleProperties":{}}', READ, NO_AUTH_HEADER) >> responseFromDmi when: 'get new yang resources from DMI service' @@ -180,7 +180,7 @@ class DmiModelOperationsSpec extends DmiOperationsBaseSpec { then: 'no resources are returned' assert result == [:] and: 'no request is sent to DMI' - 0 * mockDmiRestClient.postOperationWithJsonData(*_) + 0 * mockDmiRestClient.synchronousPostOperationWithJsonData(*_) } def 'Retrieving yang resources from DMI with null DMI properties.'() { diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/trustlevel/dmiavailability/DmiPluginWatchDogSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/trustlevel/dmiavailability/DmiPluginWatchDogSpec.groovy index 446126be9..53057573f 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/trustlevel/dmiavailability/DmiPluginWatchDogSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/trustlevel/dmiavailability/DmiPluginWatchDogSpec.groovy @@ -20,8 +20,8 @@ package org.onap.cps.ncmp.api.impl.trustlevel.dmiavailability -import org.onap.cps.ncmp.api.NetworkCmProxyDataService import org.onap.cps.ncmp.api.impl.client.DmiRestClient +import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueryService import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevelManager import spock.lang.Specification @@ -29,15 +29,12 @@ import spock.lang.Specification class DmiPluginWatchDogSpec extends Specification { def mockDmiRestClient = Mock(DmiRestClient) - def mockNetworkCmProxyDataService = Mock(NetworkCmProxyDataService) + def mockCmHandleQueryService = Mock(CmHandleQueryService) def mockTrustLevelManager = Mock(TrustLevelManager) def trustLevelPerDmiPlugin = [:] - def objectUnderTest = new DmiPluginWatchDog(mockDmiRestClient, - mockNetworkCmProxyDataService, - mockTrustLevelManager, - trustLevelPerDmiPlugin) + def objectUnderTest = new DmiPluginWatchDog(mockDmiRestClient, mockCmHandleQueryService, mockTrustLevelManager, trustLevelPerDmiPlugin) def 'watch dmi plugin health status for #dmiHealhStatus'() { given: 'the cache has been initialised and "knows" about dmi-1' |