From 6369af0f6cb53619daa253d5da0f360f2bf67fc3 Mon Sep 17 00:00:00 2001 From: DylanB95EST Date: Wed, 20 Apr 2022 10:35:11 +0100 Subject: Watchdog-process that changes CM Handles state Add a fixed delay scheduler to switch cm-handles found in an ADVISED state to a READY state Scheduler currently runs every 30 seconds Will only update a single cm-handle at a time Queries CM-Handle with Advised States Only using CPS Path. Will choose cm handle at random Issue-ID: CPS-875 Change-Id: Ie1b49c89a0350d20e14748a65f9c1d260d8502d2 Signed-off-by: DylanB95EST --- .../impl/NetworkCmProxyDataServiceImplSpec.groovy | 6 +- .../impl/operations/DmiOperationsBaseSpec.groovy | 2 +- .../YangModelCmHandleRetrieverSpec.groovy | 4 +- .../ncmp/api/inventory/sync/ModuleSyncSpec.groovy | 46 +++++++++++++ .../ncmp/api/inventory/sync/SyncUtilsSpec.groovy | 78 ++++++++++++++++++++++ 5 files changed, 130 insertions(+), 6 deletions(-) create mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncSpec.groovy create mode 100644 cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/SyncUtilsSpec.groovy (limited to 'cps-ncmp-service/src/test/groovy/org') diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy index 7629500db..65f007d14 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy @@ -74,7 +74,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { def cmHandleXPath = "/dmi-registry/cm-handles[@id='testCmHandle']" - def dataNode = new DataNode(leaves: ['dmi-service-name': 'testDmiService']) + 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 #scenario cm handle properties.'() { given: 'cpsDataService returns valid datanode' @@ -285,7 +285,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { def dmiProperties = [new YangModelCmHandle.Property('Book', 'Romance Novel')] def publicProperties = [new YangModelCmHandle.Property('Public Book', 'Public Romance Novel')] def yangModelCmHandle = new YangModelCmHandle(id:'Some-Cm-Handle', dmiServiceName: dmiServiceName, dmiProperties: dmiProperties, publicProperties: publicProperties) - 1 * mockYangModelCmHandleRetriever.getDmiServiceNamesAndProperties('Some-Cm-Handle') >> yangModelCmHandle + 1 * mockYangModelCmHandleRetriever.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 returns the correct data' @@ -301,7 +301,7 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { then: 'an exception is thrown' thrown(DataValidationException) and: 'the yang model cm handle retriever is not invoked' - 0 * mockYangModelCmHandleRetriever.getDmiServiceNamesAndProperties(_) + 0 * mockYangModelCmHandleRetriever.getYangModelCmHandle(_) } def 'Update resource data for pass-through running from dmi using POST #scenario DMI properties.'() { diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy index 563116f40..dae2bcc0a 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/DmiOperationsBaseSpec.groovy @@ -56,6 +56,6 @@ abstract class DmiOperationsBaseSpec extends Specification { yangModelCmHandle.dmiServiceName = dmiServiceName yangModelCmHandle.dmiProperties = dmiProperties yangModelCmHandle.id = cmHandleId - mockCmHandlePropertiesRetriever.getDmiServiceNamesAndProperties(cmHandleId) >> yangModelCmHandle + mockCmHandlePropertiesRetriever.getYangModelCmHandle(cmHandleId) >> yangModelCmHandle } } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetrieverSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetrieverSpec.groovy index bc30c9c77..beea1faad 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetrieverSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetrieverSpec.groovy @@ -54,7 +54,7 @@ class YangModelCmHandleRetrieverSpec extends Specification { def dataNode = new DataNode(childDataNodes:childDataNodes, leaves: leaves) mockCpsDataService.getDataNode('NCMP-Admin', 'ncmp-dmi-registry', xpath, INCLUDE_ALL_DESCENDANTS) >> dataNode when: 'retrieving the yang modelled cm handle' - def result = objectUnderTest.getDmiServiceNamesAndProperties(cmHandleId) + def result = objectUnderTest.getYangModelCmHandle(cmHandleId) then: 'the result has the correct id and service names' result.id == cmHandleId result.dmiServiceName == 'common service name' @@ -73,7 +73,7 @@ class YangModelCmHandleRetrieverSpec extends Specification { def "Retrieve CmHandle using datanode with invalid CmHandle id."() { when: 'retrieving the yang modelled cm handle with an invalid id' - def result = objectUnderTest.getDmiServiceNamesAndProperties('cm handle id with spaces') + def result = objectUnderTest.getYangModelCmHandle('cm handle id with spaces') then: 'a data validation exception is thrown' thrown(DataValidationException) and: 'the result is not returned' diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncSpec.groovy new file mode 100644 index 000000000..bcc6bb467 --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncSpec.groovy @@ -0,0 +1,46 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.api.inventory.sync + + +import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle +import spock.lang.Specification + +class ModuleSyncSpec extends Specification { + + def mockSyncUtils = Mock(SyncUtils) + + def objectUnderTest = new ModuleSyncWatchdog(mockSyncUtils) + + def 'Schedule a Cm-Handle Sync for ADVISED Cm-Handles'() { + given: 'a cm handle' + def yangModelCmHandle1 = new YangModelCmHandle() + def yangModelCmHandle2 = new YangModelCmHandle() + and: 'sync utilities return a cm handle twice' + mockSyncUtils.getAnAdvisedCmHandle() >>> [yangModelCmHandle1, yangModelCmHandle2, null] + when: 'module sync poll is executed' + objectUnderTest.executeAdvisedCmHandlePoll() + then: 'each cm handle is updated to state "READY"' + 1 * mockSyncUtils.updateCmHandleState(yangModelCmHandle1, 'READY') + 1 * mockSyncUtils.updateCmHandleState(yangModelCmHandle2, 'READY') + } + +} diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/SyncUtilsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/SyncUtilsSpec.groovy new file mode 100644 index 000000000..04b2d5513 --- /dev/null +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/SyncUtilsSpec.groovy @@ -0,0 +1,78 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.api.inventory.sync + +import com.fasterxml.jackson.databind.ObjectMapper +import org.onap.cps.api.CpsDataService +import org.onap.cps.ncmp.api.impl.operations.YangModelCmHandleRetriever +import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle +import org.onap.cps.spi.CpsDataPersistenceService +import org.onap.cps.spi.FetchDescendantsOption +import org.onap.cps.spi.model.DataNode +import org.onap.cps.utils.JsonObjectMapper +import spock.lang.Shared +import spock.lang.Specification + +import java.time.OffsetDateTime + +class SyncUtilsSpec extends Specification{ + + def mockCpsDataService = Mock(CpsDataService) + def mockCpsDataPersistenceService = Mock(CpsDataPersistenceService) + def spiedJsonObjectMapper = Spy(new JsonObjectMapper(new ObjectMapper())) + def mockYangModelCmHandleRetriever = Mock(YangModelCmHandleRetriever) + + def objectUnderTest = new SyncUtils(mockCpsDataService, mockCpsDataPersistenceService, spiedJsonObjectMapper, mockYangModelCmHandleRetriever) + + @Shared + def dataNode = new DataNode(leaves: ['id': 'cm-handle-123']) + + + + def 'Get an advised Cm-Handle where ADVISED cm handle #scenario'() { + given: 'the cps (persistence service) returns a collection of data nodes' + mockCpsDataPersistenceService.queryDataNodes('NCMP-Admin', + 'ncmp-dmi-registry', '//cm-handles[@state=\"ADVISED\"]', + FetchDescendantsOption.OMIT_DESCENDANTS) >> dataNodeCollection + when: 'get advised cm handle is called' + objectUnderTest.getAnAdvisedCmHandle() + then: 'the returned data node collection is the correct size' + dataNodeCollection.size() == expectedDataNodeSize + and: 'get yang model cm handles is invoked the correct number of times' + expectedCallsToGetYangModelCmHandle * mockYangModelCmHandleRetriever.getYangModelCmHandle('cm-handle-123') + where: 'the following scenarios are used' + scenario | dataNodeCollection || expectedCallsToGetYangModelCmHandle | expectedDataNodeSize + 'exists' | [ dataNode ] || 1 | 1 + 'does not exist' | [ ] || 0 | 0 + + } + + def 'Update cm handle state from Advised to Ready'() { + given: 'a yang model cm handle and the expected json data' + def yangModelCmHandle = new YangModelCmHandle('id': 'Some-Cm-Handle', 'cmHandleState': 'ADVISED') + def expectedJsonData = '{"cm-handles":[{"id":"Some-Cm-Handle","state":"READY"}]}' + when: 'update cm handle state is called' + objectUnderTest.updateCmHandleState(yangModelCmHandle, 'READY') + then: 'update data note leaves is invoked with the correct params' + 1 * mockCpsDataService.updateNodeLeaves('NCMP-Admin', 'ncmp-dmi-registry', '/dmi-registry', expectedJsonData, _ as OffsetDateTime) + } + +} -- cgit 1.2.3-korg