From 6ddbe4af2b73a306dec89e55b8350c09b8c5766b Mon Sep 17 00:00:00 2001 From: DylanB95EST Date: Tue, 19 Jul 2022 11:36:10 +0100 Subject: Enable/Disable Data Sync for Cm Handle -Create API Which will enable/disable data sync enabled flag -Default functionality of module sync watchdog is to set to false -Remove global config param -Will set initial sync state based on data sync enabled flag -Throws an Exception if the same data sync enabled flag tries to be set -Throws Exception if state is not in READY -Data Sync enabled must be true to complete data sync process - Delete all resource data within fragment table related to synced cm handle when data sync is set to false Issue-ID: CPS-1133 Change-Id: Ib47bbd8293f083c1d705d91bd0def74e6a105c72 Signed-off-by: DylanB95EST --- .../cps/ncmp/api/NetworkCmProxyDataService.java | 8 +++ .../api/impl/NetworkCmProxyDataServiceImpl.java | 37 ++++++++++++++ .../lcm/LcmEventsCmHandleStateHandlerImpl.java | 7 +-- .../ncmp/api/inventory/CompositeStateBuilder.java | 5 ++ .../ncmp/api/inventory/CompositeStateUtils.java | 26 ++++++++-- .../ncmp/api/inventory/sync/DataSyncWatchdog.java | 3 ++ .../api/inventory/sync/ModuleSyncWatchdog.java | 13 ++--- ...rkCmProxyDataServiceImplRegistrationSpec.groovy | 4 +- .../impl/NetworkCmProxyDataServiceImplSpec.groovy | 59 ++++++++++++++++++---- .../LcmEventsCmHandleStateHandlerImplSpec.groovy | 12 ++--- .../impl/event/lcm/LcmEventsPublisherSpec.groovy | 1 - .../ncmp/api/inventory/sync/DataSyncSpec.groovy | 24 ++++++--- .../inventory/sync/ModuleSyncWatchdogSpec.groovy | 11 ++-- 13 files changed, 158 insertions(+), 52 deletions(-) (limited to 'cps-ncmp-service') diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java index ea27d4a1e9..3295a6e2b4 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java @@ -154,4 +154,12 @@ public interface NetworkCmProxyDataService { * @return collection of cm handle ids */ Set executeCmHandleIdSearch(CmHandleQueryApiParameters cmHandleQueryApiParameters); + + /** + * Set the data sync enabled flag, along with the data sync state to true or false based on the cm handle id. + * + * @param cmHandleId cm handle id + * @param dataSyncEnabled data sync enabled flag + */ + void setDataSyncEnabled(String cmHandleId, boolean dataSyncEnabled); } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java index 8d32c1ade5..d5bf263bc7 100755 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java @@ -26,6 +26,7 @@ package org.onap.cps.ncmp.api.impl; import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum; import static org.onap.cps.utils.CmHandleQueryRestParametersValidator.validateCmHandleQueryParameters; +import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -35,6 +36,7 @@ import java.util.Set; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.onap.cps.api.CpsDataService; import org.onap.cps.ncmp.api.NetworkCmProxyCmHandlerQueryService; import org.onap.cps.ncmp.api.NetworkCmProxyDataService; import org.onap.cps.ncmp.api.impl.event.lcm.LcmEventsCmHandleStateHandler; @@ -44,6 +46,8 @@ import org.onap.cps.ncmp.api.impl.utils.YangDataConverter; import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle; import org.onap.cps.ncmp.api.inventory.CmHandleState; import org.onap.cps.ncmp.api.inventory.CompositeState; +import org.onap.cps.ncmp.api.inventory.CompositeStateUtils; +import org.onap.cps.ncmp.api.inventory.DataStoreSyncState; import org.onap.cps.ncmp.api.inventory.InventoryPersistence; import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters; import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse; @@ -52,6 +56,7 @@ import org.onap.cps.ncmp.api.models.DmiPluginRegistration; import org.onap.cps.ncmp.api.models.DmiPluginRegistrationResponse; import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle; 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.model.CmHandleQueryServiceParameters; @@ -79,6 +84,8 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService private final LcmEventsCmHandleStateHandler lcmEventsCmHandleStateHandler; + private final CpsDataService cpsDataService; + @Override public DmiPluginRegistrationResponse updateDmiRegistrationAndSyncModule( final DmiPluginRegistration dmiPluginRegistration) { @@ -181,6 +188,36 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService return networkCmProxyCmHandlerQueryService.queryCmHandleIds(cmHandleQueryServiceParameters); } + /** + * Set the data sync enabled flag, along with the data sync state + * based on the data sync enabled boolean for the cm handle id provided. + * + * @param cmHandleId cm handle id + * @param dataSyncEnabled data sync enabled flag + */ + @Override + public void setDataSyncEnabled(final String cmHandleId, final boolean dataSyncEnabled) { + CpsValidator.validateNameCharacters(cmHandleId); + final CompositeState compositeState = inventoryPersistence + .getCmHandleState(cmHandleId); + if (compositeState.getDataSyncEnabled().equals(dataSyncEnabled)) { + log.info("Data-Sync Enabled flag is already: {} ", dataSyncEnabled); + } else if (compositeState.getCmHandleState() != CmHandleState.READY) { + throw new CpsException("State mismatch exception.", "Cm-Handle not in READY state. Cm handle state is: " + + compositeState.getCmHandleState()); + } else { + final DataStoreSyncState dataStoreSyncState = compositeState.getDataStores() + .getOperationalDataStore().getDataStoreSyncState(); + if (!dataSyncEnabled && dataStoreSyncState == DataStoreSyncState.SYNCHRONIZED) { + cpsDataService.deleteDataNode("NFP-Operational", cmHandleId, + "/netconf-state", OffsetDateTime.now()); + } + CompositeStateUtils.setDataSyncEnabledFlagWithDataSyncState(dataSyncEnabled, compositeState); + inventoryPersistence.saveCmHandleState(cmHandleId, + compositeState); + } + } + /** * Retrieve cm handle details for a given cm handle. * diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCmHandleStateHandlerImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCmHandleStateHandlerImpl.java index bd47bea73a..9027a6eb0d 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCmHandleStateHandlerImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCmHandleStateHandlerImpl.java @@ -34,7 +34,6 @@ import org.onap.cps.ncmp.api.inventory.CompositeStateUtils; import org.onap.cps.ncmp.api.inventory.InventoryPersistence; import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle; import org.onap.ncmp.cmhandle.event.lcm.LcmEvent; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @Slf4j @@ -46,14 +45,10 @@ public class LcmEventsCmHandleStateHandlerImpl implements LcmEventsCmHandleState private final LcmEventsCreator lcmEventsCreator; private final LcmEventsService lcmEventsService; - @Value("${data-sync.cache.enabled:false}") - private boolean isGlobalDataSyncCacheEnabled; - @Override public void updateCmHandleState(final YangModelCmHandle yangModelCmHandle, final CmHandleState targetCmHandleState) { - if (yangModelCmHandle.getCompositeState().getCmHandleState() == targetCmHandleState) { log.debug("CmHandle with id : {} already in state : {}", yangModelCmHandle.getId(), targetCmHandleState); } else { @@ -67,7 +62,7 @@ public class LcmEventsCmHandleStateHandlerImpl implements LcmEventsCmHandleState final CmHandleState targetCmHandleState) { if (READY == targetCmHandleState) { - CompositeStateUtils.setCompositeStateToReadyWithInitialDataStoreSyncState(isGlobalDataSyncCacheEnabled) + CompositeStateUtils.setCompositeStateToReadyWithInitialDataStoreSyncState() .accept(yangModelCmHandle.getCompositeState()); inventoryPersistence.saveCmHandleState(yangModelCmHandle.getId(), yangModelCmHandle.getCompositeState()); } else if (ADVISED == targetCmHandleState) { diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeStateBuilder.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeStateBuilder.java index a0fc0c3a91..d6a33302d9 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeStateBuilder.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeStateBuilder.java @@ -32,6 +32,7 @@ public class CompositeStateBuilder { private LockReason lockReason; private DataStores datastores; private String lastUpdatedTime; + private Boolean dataSyncEnabled; /** * To create the {@link CompositeState}. @@ -44,6 +45,7 @@ public class CompositeStateBuilder { compositeState.setLockReason(lockReason); compositeState.setDataStores(datastores); compositeState.setLastUpdateTime(lastUpdatedTime); + compositeState.setDataSyncEnabled(dataSyncEnabled); return compositeState; } @@ -115,6 +117,9 @@ public class CompositeStateBuilder { this.cmHandleState = CmHandleState.valueOf((String) dataNode.getLeaves() .get("cm-handle-state")); this.lastUpdatedTime = (String) dataNode.getLeaves().get("last-update-time"); + if (this.cmHandleState == CmHandleState.READY) { + this.dataSyncEnabled = (Boolean) dataNode.getLeaves().get("data-sync-enabled"); + } for (final DataNode stateChildNode : dataNode.getChildDataNodes()) { if (stateChildNode.getXpath().endsWith("/lock-reason")) { this.lockReason = getLockReason(stateChildNode); diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeStateUtils.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeStateUtils.java index 506bd11627..54ca68a0e2 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeStateUtils.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeStateUtils.java @@ -49,10 +49,9 @@ public class CompositeStateUtils { * * @return Updated CompositeState */ - public static Consumer setCompositeStateToReadyWithInitialDataStoreSyncState( - final boolean isGlobalDataSyncCacheEnabled) { + public static Consumer setCompositeStateToReadyWithInitialDataStoreSyncState() { return compositeState -> { - compositeState.setDataSyncEnabled(isGlobalDataSyncCacheEnabled); + compositeState.setDataSyncEnabled(false); compositeState.setCmHandleState(CmHandleState.READY); final CompositeState.Operational operational = getInitialDataStoreSyncState(compositeState.getDataSyncEnabled()); @@ -62,6 +61,27 @@ public class CompositeStateUtils { }; } + /** + * Set the data sync enabled flag, along with the data store sync state based on this flag. + * + * @param dataSyncEnabled data sync enabled flag + * @param compositeState cm handle composite state + */ + public static void setDataSyncEnabledFlagWithDataSyncState(final boolean dataSyncEnabled, + final CompositeState compositeState) { + compositeState.setDataSyncEnabled(dataSyncEnabled); + final CompositeState.Operational operational = getInitialDataStoreSyncState(dataSyncEnabled); + final CompositeState.DataStores dataStores = + CompositeState.DataStores.builder().operationalDataStore(operational).build(); + compositeState.setDataStores(dataStores); + } + + /** + * Get initial data sync state based on data sync enabled boolean flag. + * + * @param dataSyncEnabled data sync enabled boolean flag + * @return the data store sync state + */ private static CompositeState.Operational getInitialDataStoreSyncState(final boolean dataSyncEnabled) { final DataStoreSyncState dataStoreSyncState = dataSyncEnabled ? DataStoreSyncState.UNSYNCHRONIZED : DataStoreSyncState.NONE_REQUESTED; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/DataSyncWatchdog.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/DataSyncWatchdog.java index adfa33ad81..395fb01f45 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/DataSyncWatchdog.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/DataSyncWatchdog.java @@ -58,6 +58,9 @@ public class DataSyncWatchdog { final String resourceData = syncUtils.getResourceData(cmHandleId); if (resourceData == null) { log.debug("Error accessing the node for Cm-Handle: {}", cmHandleId); + } else if (unSynchronizedReadyCmHandle.getCompositeState().getDataSyncEnabled().equals(false)) { + log.debug("Error: data sync enabled for {} must be true." + + "Data sync enabled is currently set to false", cmHandleId); } else { cpsDataService.saveData("NFP-Operational", cmHandleId, resourceData, OffsetDateTime.now()); diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java index c71f68f772..37bd1ed0fa 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java @@ -32,7 +32,6 @@ import org.onap.cps.ncmp.api.inventory.CompositeState; import org.onap.cps.ncmp.api.inventory.DataStoreSyncState; import org.onap.cps.ncmp.api.inventory.InventoryPersistence; import org.onap.cps.ncmp.api.inventory.LockReasonCategory; -import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @@ -47,9 +46,6 @@ public class ModuleSyncWatchdog { private final ModuleSyncService moduleSyncService; - @Value("${data-sync.cache.enabled:false}") - private boolean isGlobalDataSyncCacheEnabled; - private final ConcurrentMap moduleSyncSemaphoreMap; /** @@ -107,9 +103,9 @@ public class ModuleSyncWatchdog { private Consumer setCompositeStateToReadyWithInitialDataStoreSyncState() { return compositeState -> { - compositeState.setDataSyncEnabled(isGlobalDataSyncCacheEnabled); + compositeState.setDataSyncEnabled(false); compositeState.setCmHandleState(CmHandleState.READY); - final CompositeState.Operational operational = getDataStoreSyncState(compositeState.getDataSyncEnabled()); + final CompositeState.Operational operational = getDataStoreSyncState(); final CompositeState.DataStores dataStores = CompositeState.DataStores.builder() .operationalDataStore(operational) .build(); @@ -126,9 +122,8 @@ public class ModuleSyncWatchdog { compositeState.setLockReason(lockReason); } - private CompositeState.Operational getDataStoreSyncState(final boolean dataSyncEnabled) { - final DataStoreSyncState dataStoreSyncState = dataSyncEnabled - ? DataStoreSyncState.UNSYNCHRONIZED : DataStoreSyncState.NONE_REQUESTED; + private CompositeState.Operational getDataStoreSyncState() { + final DataStoreSyncState dataStoreSyncState = DataStoreSyncState.NONE_REQUESTED; return CompositeState.Operational.builder().dataStoreSyncState(dataStoreSyncState).build(); } 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/NetworkCmProxyDataServiceImplRegistrationSpec.groovy index 1ee1ad2f60..2aa08b8e7f 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/NetworkCmProxyDataServiceImplRegistrationSpec.groovy @@ -22,6 +22,7 @@ package org.onap.cps.ncmp.api.impl import com.fasterxml.jackson.databind.ObjectMapper +import org.onap.cps.api.CpsDataService import org.onap.cps.api.CpsModuleService import org.onap.cps.ncmp.api.NetworkCmProxyCmHandlerQueryService import org.onap.cps.ncmp.api.impl.event.lcm.LcmEventsCmHandleStateHandler @@ -60,6 +61,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { def mockInventoryPersistence = Mock(InventoryPersistence) def stubbedNetworkCmProxyCmHandlerQueryService = Stub(NetworkCmProxyCmHandlerQueryService) def mockLcmEventsCmHandleStateHandler = Mock(LcmEventsCmHandleStateHandler) + def mockCpsDataService = Mock(CpsDataService) def objectUnderTest = getObjectUnderTest() def 'DMI Registration: Create, Update & Delete operations are processed in the right order'() { @@ -351,6 +353,6 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { def getObjectUnderTest() { return Spy(new NetworkCmProxyDataServiceImpl(spiedJsonObjectMapper, mockDmiDataOperations, mockNetworkCmProxyDataServicePropertyHandler, mockInventoryPersistence, stubbedNetworkCmProxyCmHandlerQueryService, - mockLcmEventsCmHandleStateHandler)) + mockLcmEventsCmHandleStateHandler, mockCpsDataService)) } } 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 d112557671..a372defc66 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 @@ -34,6 +34,7 @@ import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters 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.exceptions.CpsException import org.onap.cps.spi.exceptions.DataValidationException import org.onap.cps.spi.model.CmHandleQueryServiceParameters import spock.lang.Shared @@ -79,7 +80,8 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { nullNetworkCmProxyDataServicePropertyHandler, mockInventoryPersistence, mockCpsCmHandlerQueryService, - mockLcmEventsCmHandleStateHandler) + mockLcmEventsCmHandleStateHandler, + mockCpsDataService) def cmHandleXPath = "/dmi-registry/cm-handles[@id='testCmHandle']" @@ -311,14 +313,6 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { 1 * mockInventoryPersistence.getModuleDefinitionsByCmHandleId('some-cm-handle') } - - def dataStores() { - CompositeState.DataStores.builder() - .operationalDataStore(CompositeState.Operational.builder() - .dataStoreSyncState(DataStoreSyncState.NONE_REQUESTED) - .lastSyncTime('some-timestamp').build()).build() - } - def 'Execute cm handle search'() { given: 'valid CmHandleQueryApiParameters input' def cmHandleQueryApiParameters = new CmHandleQueryApiParameters() @@ -335,4 +329,51 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { 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', '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 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/event/lcm/LcmEventsCmHandleStateHandlerImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCmHandleStateHandlerImplSpec.groovy index b4e57c78b5..b3436792de 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCmHandleStateHandlerImplSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsCmHandleStateHandlerImplSpec.groovy @@ -94,29 +94,25 @@ class LcmEventsCmHandleStateHandlerImplSpec extends Specification { 1 * mockLcmEventsService.publishLcmEvent(cmHandleId, _) } - def 'Update and Publish Events on State Change to READY with #scenario'() { + def 'Update and Publish Events on State Change to READY'() { given: 'Cm Handle represented as YangModelCmHandle' compositeState = new CompositeState(cmHandleState: ADVISED) yangModelCmHandle = new YangModelCmHandle(id: cmHandleId, dmiProperties: [], publicProperties: [], compositeState: compositeState) and: 'global sync flag is set' - objectUnderTest.isGlobalDataSyncCacheEnabled = dataSyncCacheEnabled + compositeState.setDataSyncEnabled(false) when: 'update cmhandle state is invoked' objectUnderTest.updateCmHandleState(yangModelCmHandle, READY) then: 'state is saved using inventory persistence with expected dataSyncState' 1 * mockInventoryPersistence.saveCmHandleState(cmHandleId, _) >> { args-> { def result = (args[1] as CompositeState) - assert result.dataSyncEnabled == dataSyncCacheEnabled - assert result.dataStores.operationalDataStore.dataStoreSyncState == expectedDataStoreSyncState + assert result.dataSyncEnabled == false + assert result.dataStores.operationalDataStore.dataStoreSyncState == DataStoreSyncState.NONE_REQUESTED } } and: 'event service is called to publish event' 1 * mockLcmEventsService.publishLcmEvent(cmHandleId, _) - where: - scenario | dataSyncCacheEnabled || expectedDataStoreSyncState - 'data sync cache enabled' | true || DataStoreSyncState.UNSYNCHRONIZED - 'data sync cache is not enabled' | false || DataStoreSyncState.NONE_REQUESTED } def 'Update cmHandle state to "DELETING"' (){ diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsPublisherSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsPublisherSpec.groovy index f2cd2b51f7..c7e6b6d354 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsPublisherSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/event/lcm/LcmEventsPublisherSpec.groovy @@ -22,7 +22,6 @@ package org.onap.cps.ncmp.api.impl.event.lcm import com.fasterxml.jackson.databind.ObjectMapper import org.apache.kafka.clients.consumer.KafkaConsumer -import org.onap.cps.ncmp.api.impl.event.lcm.LcmEventsPublisher import org.onap.cps.ncmp.api.utils.MessagingSpec import org.onap.cps.ncmp.utils.TestUtils import org.onap.cps.utils.JsonObjectMapper diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/DataSyncSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/DataSyncSpec.groovy index 20880ca3b3..650a779a42 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/DataSyncSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/DataSyncSpec.groovy @@ -26,6 +26,7 @@ import org.onap.cps.ncmp.api.inventory.CmHandleState import org.onap.cps.ncmp.api.inventory.CompositeState import org.onap.cps.ncmp.api.inventory.InventoryPersistence import org.onap.cps.ncmp.api.inventory.DataStoreSyncState +import spock.lang.Shared import spock.lang.Specification class DataSyncSpec extends Specification { @@ -36,6 +37,7 @@ class DataSyncSpec extends Specification { def mockSyncUtils = Mock(SyncUtils) + @Shared def jsonString = '{"stores:bookstore":{"categories":[{"code":"01"}]}}' def objectUnderTest = new DataSyncWatchdog(mockInventoryPersistence, mockCpsDataService, mockSyncUtils) @@ -48,7 +50,7 @@ class DataSyncSpec extends Specification { def 'Schedule Data Sync for Cm Handle State in READY and Operational Sync State in UNSYNCHRONIZED'() { given: 'sample resource data' - def resourceData = jsonString; + def resourceData = jsonString and: 'sync utilities return a cm handle twice' mockSyncUtils.getAnUnSynchronizedReadyCmHandle() >>> [yangModelCmHandle1, yangModelCmHandle2, null] when: 'data sync poll is executed' @@ -71,18 +73,24 @@ class DataSyncSpec extends Specification { 1 * mockInventoryPersistence.saveCmHandleState('some-cm-handle-2', compositeState) } - def 'Schedule Data Sync for Cm Handle State in READY and Operational Sync State in UNSYNCHRONIZED which return empty data from Node'() { - given: 'cm handles in an ready state and operational sync state in unsynchronized' - and: 'sync utilities return a cm handle twice' - mockSyncUtils.getAnUnSynchronizedReadyCmHandle() >>> [yangModelCmHandle1, null] + def 'Schedule Data Sync for Cm Handle State in READY and Operational Sync State in UNSYNCHRONIZED which return empty data from Node because #scenario'() { + given: 'a yang model cm handle' + def yangModelCmHandle = new YangModelCmHandle(id: 'some-cm-handle', compositeState: new CompositeState(dataSyncEnabled: dataSyncEnabled)) + and: 'sync utilities returns a single cm handle' + mockSyncUtils.getAnUnSynchronizedReadyCmHandle() >>> [yangModelCmHandle, null] when: 'data sync poll is executed' objectUnderTest.executeUnSynchronizedReadyCmHandlePoll() then: 'the inventory persistence cm handle returns a composite state for the first cm handle' - 1 * mockInventoryPersistence.getCmHandleState('some-cm-handle-1') >> compositeState + 1 * mockInventoryPersistence.getCmHandleState('some-cm-handle') >> compositeState and: 'the sync util returns first resource data' - 1 * mockSyncUtils.getResourceData('some-cm-handle-1') >> null + 1 * mockSyncUtils.getResourceData('some-cm-handle') >> resourceData and: 'the cm-handle data is not saved' 0 * mockCpsDataService.saveData('NFP-Operational', 'some-cm-handle-1', jsonString, _) + where: + scenario | dataSyncEnabled | resourceData + 'data sync is not enabled' | false | jsonString + 'resource data is null' | true | null + 'data sync is not enabled and resource data is null' | false | null } def createSampleYangModelCmHandle(cmHandleId) { @@ -92,7 +100,7 @@ class DataSyncSpec extends Specification { def getCompositeState() { def cmHandleState = CmHandleState.READY - def compositeState = new CompositeState(cmHandleState: cmHandleState) + def compositeState = new CompositeState(cmHandleState: cmHandleState, dataSyncEnabled: true) compositeState.setDataStores(CompositeState.DataStores.builder() .operationalDataStore(CompositeState.Operational.builder().dataStoreSyncState(DataStoreSyncState.SYNCHRONIZED) .build()).build()) diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdogSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdogSpec.groovy index 7455438cc2..41f2160bc0 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdogSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdogSpec.groovy @@ -47,13 +47,12 @@ class ModuleSyncWatchdogSpec extends Specification { def objectUnderTest = new ModuleSyncWatchdog(mockInventoryPersistence, mockSyncUtils, mockModuleSyncService, stubbedMap as ConcurrentHashMap) - def 'Schedule a Cm-Handle Sync for ADVISED Cm-Handles where #scenario'() { + def 'Schedule a Cm-Handle Sync for ADVISED Cm-Handles'() { given: 'cm handles in an advised state and a data sync state' def compositeState1 = new CompositeState(cmHandleState: cmHandleState) def compositeState2 = new CompositeState(cmHandleState: cmHandleState) def yangModelCmHandle1 = new YangModelCmHandle(id: 'some-cm-handle', compositeState: compositeState1) def yangModelCmHandle2 = new YangModelCmHandle(id: 'some-cm-handle-2', compositeState: compositeState2) - objectUnderTest.isGlobalDataSyncCacheEnabled = dataSyncCacheEnabled and: 'sync utilities return a cm handle twice' mockSyncUtils.getAdvisedCmHandles() >> [yangModelCmHandle1, yangModelCmHandle2] when: 'module sync poll is executed' @@ -66,8 +65,10 @@ class ModuleSyncWatchdogSpec extends Specification { 1 * mockModuleSyncService.syncAndCreateSchemaSetAndAnchor(yangModelCmHandle1) then: 'the composite state cm handle state is now READY' assert compositeState1.getCmHandleState() == CmHandleState.READY + and: 'the data sync enabled flag is set correctly' + compositeState1.getDataSyncEnabled() == false and: 'the data store sync state returns the expected state' - compositeState1.getDataStores().operationalDataStore.dataStoreSyncState == expectedDataStoreSyncState + compositeState1.getDataStores().operationalDataStore.dataStoreSyncState == DataStoreSyncState.NONE_REQUESTED and: 'the first cm handle state is updated' 1 * mockInventoryPersistence.saveCmHandleState('some-cm-handle', compositeState1) then: 'the inventory persistence cm handle returns a composite state for the second cm handle' @@ -78,10 +79,6 @@ class ModuleSyncWatchdogSpec extends Specification { assert compositeState2.getCmHandleState() == CmHandleState.READY and: 'the second cm handle state is updated' 1 * mockInventoryPersistence.saveCmHandleState('some-cm-handle-2', compositeState2) - where: - scenario | dataSyncCacheEnabled || expectedDataStoreSyncState - 'data sync cache enabled' | true || DataStoreSyncState.UNSYNCHRONIZED - 'data sync cache is not enabled' | false || DataStoreSyncState.NONE_REQUESTED } def 'Schedule a Cm-Handle Sync for ADVISED Cm-Handle with failure'() { -- cgit 1.2.3-korg