aboutsummaryrefslogtreecommitdiffstats
path: root/cps-ncmp-service
diff options
context:
space:
mode:
Diffstat (limited to 'cps-ncmp-service')
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cache/HazelcastCacheConfig.java1
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperations.java7
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncService.java49
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncTasks.java5
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/SynchronizationCacheConfig.java18
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cache/HazelcastCacheConfigSpec.groovy5
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncServiceSpec.groovy93
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncTasksSpec.groovy5
-rw-r--r--cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/SynchronizationCacheConfigSpec.groovy18
9 files changed, 175 insertions, 26 deletions
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cache/HazelcastCacheConfig.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cache/HazelcastCacheConfig.java
index 109a541cb3..345eefec2a 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cache/HazelcastCacheConfig.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cache/HazelcastCacheConfig.java
@@ -51,6 +51,7 @@ public class HazelcastCacheConfig {
protected HazelcastInstance getOrCreateHazelcastInstance(final NamedConfig namedConfig) {
return Hazelcast.getOrCreateHazelcastInstance(defineInstanceConfig(instanceConfigName, namedConfig));
+
}
private Config defineInstanceConfig(final String instanceConfigName, final NamedConfig namedConfig) {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperations.java
index 8ba70b3a31..a056efd6ce 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperations.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/DmiModelOperations.java
@@ -26,6 +26,7 @@ import static org.onap.cps.ncmp.impl.models.RequiredDmiService.MODEL;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
+import io.micrometer.core.annotation.Timed;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -33,6 +34,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import org.onap.cps.ncmp.api.inventory.models.YangResource;
import org.onap.cps.ncmp.impl.dmi.DmiProperties;
import org.onap.cps.ncmp.impl.dmi.DmiRestClient;
@@ -48,6 +50,7 @@ import org.springframework.stereotype.Service;
/**
* Operations class for DMI Model.
*/
+@Slf4j
@RequiredArgsConstructor
@Service
public class DmiModelOperations {
@@ -62,6 +65,8 @@ public class DmiModelOperations {
* @param yangModelCmHandle the yang model cm handle
* @return module references
*/
+ @Timed(value = "cps.ncmp.inventory.module.references.from.dmi",
+ description = "Time taken to get all module references for a cm handle from dmi")
public List<ModuleReference> getModuleReferences(final YangModelCmHandle yangModelCmHandle) {
final DmiRequestBody dmiRequestBody = DmiRequestBody.builder()
.moduleSetTag(yangModelCmHandle.getModuleSetTag()).build();
@@ -79,6 +84,8 @@ public class DmiModelOperations {
* @param newModuleReferences the unknown module references
* @return yang resources as map of module name to yang(re)source
*/
+ @Timed(value = "cps.ncmp.inventory.yang.resources.from.dmi",
+ description = "Time taken to get list of yang resources from dmi")
public Map<String, String> getNewYangResourcesFromDmi(final YangModelCmHandle yangModelCmHandle,
final Collection<ModuleReference> newModuleReferences) {
if (newModuleReferences.isEmpty()) {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncService.java
index ca0f1c6a6d..ba50dd3c19 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncService.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncService.java
@@ -26,16 +26,20 @@ import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DMI_REGISTRY
import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DMI_REGISTRY_PARENT;
import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME;
+import com.hazelcast.collection.ISet;
import java.time.OffsetDateTime;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.apache.logging.log4j.util.Strings;
import org.onap.cps.api.CpsAnchorService;
import org.onap.cps.api.CpsDataService;
import org.onap.cps.api.CpsModuleService;
+import org.onap.cps.ncmp.api.exceptions.NcmpException;
import org.onap.cps.ncmp.impl.inventory.models.CmHandleState;
import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
import org.onap.cps.spi.CascadeDeleteAllowed;
@@ -50,12 +54,15 @@ import org.springframework.stereotype.Service;
@RequiredArgsConstructor
public class ModuleSyncService {
+ private static final Map<String, String> NO_NEW_MODULES = Collections.emptyMap();
+
private final DmiModelOperations dmiModelOperations;
private final CpsModuleService cpsModuleService;
private final CpsDataService cpsDataService;
private final CpsAnchorService cpsAnchorService;
private final JsonObjectMapper jsonObjectMapper;
- private static final Map<String, String> NO_NEW_MODULES = Collections.emptyMap();
+ private final ISet<String> moduleSetTagsBeingProcessed;
+ private final Map<String, ModuleDelta> privateModuleSetCache = new HashMap<>();
@AllArgsConstructor
private static final class ModuleDelta {
@@ -69,11 +76,37 @@ public class ModuleSyncService {
* @param yangModelCmHandle the yang model of cm handle.
*/
public void syncAndCreateSchemaSetAndAnchor(final YangModelCmHandle yangModelCmHandle) {
- final ModuleDelta moduleDelta = getModuleDelta(yangModelCmHandle, yangModelCmHandle.getModuleSetTag());
- final String cmHandleId = yangModelCmHandle.getId();
- cpsModuleService.createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId,
+ final String moduleSetTag = yangModelCmHandle.getModuleSetTag();
+ final ModuleDelta moduleDelta;
+ boolean isNewModuleSetTag = Strings.isNotBlank(moduleSetTag);
+ try {
+ if (privateModuleSetCache.containsKey(moduleSetTag)) {
+ moduleDelta = privateModuleSetCache.get(moduleSetTag);
+ } else {
+ if (isNewModuleSetTag) {
+ if (moduleSetTagsBeingProcessed.add(moduleSetTag)) {
+ log.info("Processing new module set tag {}", moduleSetTag);
+ } else {
+ isNewModuleSetTag = false;
+ throw new NcmpException("Concurrent processing of module set tag " + moduleSetTag,
+ moduleSetTag + " already being processed for cm handle " + yangModelCmHandle.getId());
+ }
+ }
+ moduleDelta = getModuleDelta(yangModelCmHandle, moduleSetTag);
+ }
+ final String cmHandleId = yangModelCmHandle.getId();
+ cpsModuleService.createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId,
moduleDelta.newModuleNameToContentMap, moduleDelta.allModuleReferences);
- cpsAnchorService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId, cmHandleId);
+ cpsAnchorService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId, cmHandleId);
+ if (isNewModuleSetTag) {
+ final ModuleDelta noModuleDelta = new ModuleDelta(moduleDelta.allModuleReferences, NO_NEW_MODULES);
+ privateModuleSetCache.put(moduleSetTag, noModuleDelta);
+ }
+ } finally {
+ if (isNewModuleSetTag) {
+ moduleSetTagsBeingProcessed.remove(moduleSetTag);
+ }
+ }
}
/**
@@ -105,6 +138,10 @@ public class ModuleSyncService {
}
}
+ public void clearPrivateModuleSetCache() {
+ privateModuleSetCache.clear();
+ }
+
private ModuleDelta getModuleDelta(final YangModelCmHandle yangModelCmHandle, final String targetModuleSetTag) {
final Map<String, String> newYangResources;
Collection<ModuleReference> allModuleReferences = getModuleReferencesByModuleSetTag(targetModuleSetTag);
@@ -120,7 +157,7 @@ public class ModuleSyncService {
}
private Collection<ModuleReference> getModuleReferencesByModuleSetTag(final String moduleSetTag) {
- if (moduleSetTag == null || moduleSetTag.trim().isEmpty()) {
+ if (Strings.isBlank(moduleSetTag)) {
return Collections.emptyList();
}
return cpsModuleService.getModuleReferencesByAttribute(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncTasks.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncTasks.java
index 31fcbad08b..7cc74a3b55 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncTasks.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncTasks.java
@@ -63,7 +63,8 @@ public class ModuleSyncTasks {
try {
cmHandlesAsDataNodes.forEach(cmHandleAsDataNode -> {
final YangModelCmHandle yangModelCmHandle = YangDataConverter.toYangModelCmHandle(cmHandleAsDataNode);
- cmHandleStatePerCmHandle.put(yangModelCmHandle, processCmHandle(yangModelCmHandle));
+ final CmHandleState cmHandleState = processCmHandle(yangModelCmHandle);
+ cmHandleStatePerCmHandle.put(yangModelCmHandle, cmHandleState);
});
} finally {
batchCounter.getAndDecrement();
@@ -127,4 +128,4 @@ public class ModuleSyncTasks {
log.info("{} removed from in progress map", resetCmHandleId);
}
}
-} \ No newline at end of file
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/SynchronizationCacheConfig.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/SynchronizationCacheConfig.java
index 1f33cc349d..b98075c06c 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/SynchronizationCacheConfig.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/SynchronizationCacheConfig.java
@@ -20,8 +20,10 @@
package org.onap.cps.ncmp.impl.inventory.sync;
+import com.hazelcast.collection.ISet;
import com.hazelcast.config.MapConfig;
import com.hazelcast.config.QueueConfig;
+import com.hazelcast.config.SetConfig;
import com.hazelcast.map.IMap;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.locks.Lock;
@@ -44,6 +46,8 @@ public class SynchronizationCacheConfig extends HazelcastCacheConfig {
private static final QueueConfig commonQueueConfig = createQueueConfig("defaultQueueConfig");
private static final MapConfig moduleSyncStartedConfig = createMapConfig("moduleSyncStartedConfig");
private static final MapConfig dataSyncSemaphoresConfig = createMapConfig("dataSyncSemaphoresConfig");
+ private static final SetConfig moduleSetTagsBeingProcessedConfig
+ = createSetConfig("moduleSetTagsBeingProcessedConfig");
private static final String LOCK_NAME_FOR_WORK_QUEUE = "workQueueLock";
/**
@@ -63,8 +67,7 @@ public class SynchronizationCacheConfig extends HazelcastCacheConfig {
*/
@Bean
public IMap<String, Object> moduleSyncStartedOnCmHandles() {
- return getOrCreateHazelcastInstance(moduleSyncStartedConfig).getMap(
- "moduleSyncStartedOnCmHandles");
+ return getOrCreateHazelcastInstance(moduleSyncStartedConfig).getMap("moduleSyncStartedOnCmHandles");
}
/**
@@ -78,6 +81,17 @@ public class SynchronizationCacheConfig extends HazelcastCacheConfig {
}
/**
+ * Collection of (new) module set tags being processed.
+ * To prevent processing on multiple threads of same tag
+ *
+ * @return set of module set tags being processed
+ */
+ @Bean
+ public ISet<String> moduleSetTagsBeingProcessed() {
+ return getOrCreateHazelcastInstance(moduleSetTagsBeingProcessedConfig).getSet("moduleSetTagsBeingProcessed");
+ }
+
+ /**
* Retrieves a distributed lock used to control access to the work queue for module synchronization.
* This lock ensures that the population and modification of the work queue are thread-safe and
* protected from concurrent access across different nodes in the distributed system.
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cache/HazelcastCacheConfigSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cache/HazelcastCacheConfigSpec.groovy
index 0bd838437d..c08ff75a44 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cache/HazelcastCacheConfigSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cache/HazelcastCacheConfigSpec.groovy
@@ -22,12 +22,17 @@ package org.onap.cps.ncmp.impl.cache
import com.hazelcast.config.Config
import com.hazelcast.config.RestEndpointGroup
+import com.hazelcast.core.Hazelcast
import spock.lang.Specification
class HazelcastCacheConfigSpec extends Specification {
def objectUnderTest = new HazelcastCacheConfig()
+ def cleanupSpec() {
+ Hazelcast.getHazelcastInstanceByName('my instance config').shutdown()
+ }
+
def 'Create Hazelcast instance with a #scenario'() {
given: 'a cluster name and instance config name'
objectUnderTest.clusterName = 'my cluster'
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncServiceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncServiceSpec.groovy
index 6030e5debf..2f13a9a483 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncServiceSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncServiceSpec.groovy
@@ -20,14 +20,17 @@
package org.onap.cps.ncmp.impl.inventory.sync
+import com.hazelcast.collection.ISet
import org.onap.cps.api.CpsAnchorService
import org.onap.cps.api.CpsDataService
import org.onap.cps.api.CpsModuleService
+import org.onap.cps.ncmp.api.exceptions.NcmpException
import org.onap.cps.ncmp.api.inventory.models.CompositeStateBuilder
import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle
import org.onap.cps.ncmp.impl.inventory.CmHandleQueryService
import org.onap.cps.ncmp.impl.inventory.models.CmHandleState
import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle
+import org.onap.cps.ncmp.impl.inventory.sync.ModuleSyncService.ModuleDelta
import org.onap.cps.spi.CascadeDeleteAllowed
import org.onap.cps.spi.exceptions.SchemaSetNotFoundException
import org.onap.cps.spi.model.ModuleReference
@@ -45,18 +48,22 @@ class ModuleSyncServiceSpec extends Specification {
def mockCmHandleQueries = Mock(CmHandleQueryService)
def mockCpsDataService = Mock(CpsDataService)
def mockJsonObjectMapper = Mock(JsonObjectMapper)
+ def mockModuleSetTagsBeingProcessed = Mock(ISet<String>);
- def objectUnderTest = new ModuleSyncService(mockDmiModelOperations, mockCpsModuleService,
- mockCpsDataService, mockCpsAnchorService, mockJsonObjectMapper)
+ def objectUnderTest = new ModuleSyncService(mockDmiModelOperations, mockCpsModuleService, mockCpsDataService, mockCpsAnchorService, mockJsonObjectMapper, mockModuleSetTagsBeingProcessed)
def expectedDataspaceName = NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME
- def 'Sync model for a NEW cm handle using module set tags: #scenario.'() {
- given: 'a cm handle state to be synced'
- def ncmpServiceCmHandle = new NcmpServiceCmHandle()
- ncmpServiceCmHandle.setCompositeState(new CompositeStateBuilder().withCmHandleState(CmHandleState.ADVISED).build())
- ncmpServiceCmHandle.cmHandleId = 'ch-1'
- def yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle('some service name', '', '', ncmpServiceCmHandle, moduleSetTag, '', '')
+ def setup() {
+ // Allow tags for al test except 'duplicate-processing-tag' to be added to processing semaphore
+ mockModuleSetTagsBeingProcessed.add('new-tag') >> true
+ mockModuleSetTagsBeingProcessed.add('same-tag') >> true
+ mockModuleSetTagsBeingProcessed.add('cached-tag') >> true
+ }
+
+ def 'Sync models for a NEW cm handle using module set tags: #scenario.'() {
+ given: 'a cm handle to be synced'
+ def yangModelCmHandle = createAdvisedCmHandle(moduleSetTag)
and: 'DMI operations returns some module references'
def moduleReferences = [ new ModuleReference('module1','1'), new ModuleReference('module2','2') ]
mockDmiModelOperations.getModuleReferences(yangModelCmHandle) >> moduleReferences
@@ -75,10 +82,60 @@ class ModuleSyncServiceSpec extends Specification {
where: 'the following parameters are used'
scenario | identifiedNewModuleReferences | newModuleNameContentToMap | moduleSetTag | existingModuleReferences
'one new module, new tag' | [new ModuleReference('module1', '1')] | [module1: 'some yang source'] | '' | []
- 'no new module, new tag' | [] | [:] | 'new-tag-1' | []
+ 'no new module, new tag' | [] | [:] | 'new-tag' | []
'same tag' | [] | [:] | 'same-tag' | [new ModuleReference('module1', '1'), new ModuleReference('module2', '2')]
}
+ def 'Attempt Sync models for a cm handle with exception and #scenario module set tag'() {
+ given: 'a cm handle to be synced'
+ def yangModelCmHandle = createAdvisedCmHandle(moduleSetTag)
+ and: 'the service returns a list of module references when queried with the specified attributes'
+ mockCpsModuleService.getModuleReferencesByAttribute(*_) >> [new ModuleReference('module1', '1')]
+ and: 'exception occurs when try to store result'
+ def testException = new RuntimeException('test')
+ mockCpsModuleService.createSchemaSetFromModules(*_) >> { throw testException }
+ when: 'module sync is triggered'
+ objectUnderTest.syncAndCreateSchemaSetAndAnchor(yangModelCmHandle)
+ then: 'the same exception is thrown up'
+ def exceptionThrown = thrown(Exception)
+ assert testException == exceptionThrown
+ and: 'module set tag is removed from processing semaphores only when needed'
+ expectedCallsToRemoveTag * mockModuleSetTagsBeingProcessed.remove('new-tag')
+ where: 'following module set tags are used'
+ scenario | moduleSetTag || expectedCallsToRemoveTag
+ 'with' | 'new-tag' || 1
+ 'without' | ' ' || 0
+ }
+
+ def 'Sync models for a cm handle with previously cached module set tag.'() {
+ given: 'a cm handle to be synced'
+ def yangModelCmHandle = createAdvisedCmHandle('cached-tag')
+ and: 'The module set tag exist in the private cache'
+ def moduleReferences = [ new ModuleReference('module1','1') ]
+ def cachedModuleDelta = new ModuleDelta(moduleReferences, [:])
+ objectUnderTest.privateModuleSetCache.put('cached-tag', cachedModuleDelta)
+ when: 'module sync is triggered'
+ objectUnderTest.syncAndCreateSchemaSetAndAnchor(yangModelCmHandle)
+ then: 'create schema set from module is invoked with correct parameters'
+ 1 * mockCpsModuleService.createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, 'ch-1', [:], moduleReferences)
+ and: 'anchor is created with the correct parameters'
+ 1 * mockCpsAnchorService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, 'ch-1', 'ch-1')
+ }
+
+ def 'Attempt to sync using a module set tag already being processed by a different instance or thread.'() {
+ given: 'a cm handle to be synced'
+ def yangModelCmHandle = createAdvisedCmHandle('duplicateTag')
+ and: 'The module set tag already exist in the processing semaphore set'
+ mockModuleSetTagsBeingProcessed.add('duplicate-processing-tag') > false
+ when: 'module sync is triggered'
+ objectUnderTest.syncAndCreateSchemaSetAndAnchor(yangModelCmHandle)
+ then: 'a ncmp exception is thrown with the relevant details'
+ def exceptionThrown = thrown(NcmpException)
+ assert exceptionThrown.message.contains('duplicateTag')
+ assert exceptionThrown.details.contains('duplicateTag')
+ assert exceptionThrown.details.contains('ch-1')
+ }
+
def 'Upgrade model for an existing cm handle with Module Set Tag where the modules are #scenario'() {
given: 'a cm handle being upgraded to module set tag: tag-1'
def ncmpServiceCmHandle = new NcmpServiceCmHandle()
@@ -113,7 +170,7 @@ class ModuleSyncServiceSpec extends Specification {
'in database' | [new ModuleReference('module1', '1')]
}
- def 'upgrade model for a existing cm handle'() {
+ def 'upgrade model for an existing cm handle'() {
given: 'a cm handle that is ready but locked for upgrade'
def ncmpServiceCmHandle = new NcmpServiceCmHandle()
ncmpServiceCmHandle.setCompositeState(new CompositeStateBuilder()
@@ -159,4 +216,20 @@ class ModuleSyncServiceSpec extends Specification {
result == unsupportedOperationException
}
+ def 'Clear module set cache.'() {
+ given: 'something in the module set cache'
+ objectUnderTest.privateModuleSetCache.put('test',new ModuleDelta([],[:]))
+ when: 'the cache is cleared'
+ objectUnderTest.clearPrivateModuleSetCache()
+ then: 'the cache is empty'
+ objectUnderTest.privateModuleSetCache.isEmpty()
+ }
+
+ def createAdvisedCmHandle(moduleSetTag) {
+ def ncmpServiceCmHandle = new NcmpServiceCmHandle()
+ ncmpServiceCmHandle.setCompositeState(new CompositeStateBuilder().withCmHandleState(CmHandleState.ADVISED).build())
+ ncmpServiceCmHandle.cmHandleId = 'ch-1'
+ return YangModelCmHandle.toYangModelCmHandle('some service name', '', '', ncmpServiceCmHandle, moduleSetTag, '', '')
+ }
+
}
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncTasksSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncTasksSpec.groovy
index 8ce1e934f2..e21c868bbf 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncTasksSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncTasksSpec.groovy
@@ -26,6 +26,7 @@ import ch.qos.logback.classic.Logger
import ch.qos.logback.classic.spi.ILoggingEvent
import ch.qos.logback.core.read.ListAppender
import com.hazelcast.config.Config
+import com.hazelcast.core.Hazelcast
import com.hazelcast.instance.impl.HazelcastInstanceFactory
import com.hazelcast.map.IMap
import org.onap.cps.ncmp.api.inventory.models.CompositeState
@@ -75,6 +76,10 @@ class ModuleSyncTasksSpec extends Specification {
def objectUnderTest = new ModuleSyncTasks(mockInventoryPersistence, mockSyncUtils, mockModuleSyncService,
mockLcmEventsCmHandleStateHandler, moduleSyncStartedOnCmHandles)
+ def cleanupSpec() {
+ Hazelcast.getHazelcastInstanceByName('hazelcastInstanceName').shutdown()
+ }
+
def 'Module Sync ADVISED cm handles.'() {
given: 'cm handles in an ADVISED state'
def cmHandle1 = cmHandleAsDataNodeByIdAndState('cm-handle-1', CmHandleState.ADVISED)
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/SynchronizationCacheConfigSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/SynchronizationCacheConfigSpec.groovy
index 4c96d6b822..c2ecf927c8 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/SynchronizationCacheConfigSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/sync/SynchronizationCacheConfigSpec.groovy
@@ -20,6 +20,7 @@
package org.onap.cps.ncmp.impl.inventory.sync
+import com.hazelcast.collection.ISet
import com.hazelcast.config.Config
import com.hazelcast.core.Hazelcast
import com.hazelcast.map.IMap
@@ -38,13 +39,16 @@ import java.util.concurrent.TimeUnit
class SynchronizationCacheConfigSpec extends Specification {
@Autowired
- private BlockingQueue<DataNode> moduleSyncWorkQueue
+ BlockingQueue<DataNode> moduleSyncWorkQueue
@Autowired
- private IMap<String, Object> moduleSyncStartedOnCmHandles
+ IMap<String, Object> moduleSyncStartedOnCmHandles
@Autowired
- private IMap<String, Boolean> dataSyncSemaphores
+ IMap<String, Boolean> dataSyncSemaphores
+
+ @Autowired
+ ISet<String> moduleSetTagsBeingProcessed
def cleanupSpec() {
Hazelcast.getHazelcastInstanceByName('cps-and-ncmp-hazelcast-instance-test-config').shutdown()
@@ -57,8 +61,11 @@ class SynchronizationCacheConfigSpec extends Specification {
assert null != moduleSyncStartedOnCmHandles
and: 'system is able to create an instance of a map to hold data sync semaphores'
assert null != dataSyncSemaphores
- and: 'they have the correct names (in any order)'
- assert Hazelcast.allHazelcastInstances.name.contains('cps-and-ncmp-hazelcast-instance-test-config')
+ and: 'system is able to create an instance of a set to hold module set tags being processed'
+ assert null != moduleSetTagsBeingProcessed
+ and: 'there is only one instance with the correct name'
+ assert Hazelcast.allHazelcastInstances.size() == 1
+ assert Hazelcast.allHazelcastInstances.name[0] == 'cps-and-ncmp-hazelcast-instance-test-config'
}
def 'Verify configs for Distributed objects'(){
@@ -103,7 +110,6 @@ class SynchronizationCacheConfigSpec extends Specification {
then: 'applied properties are reflected'
assert testConfig.networkConfig.join.kubernetesConfig.enabled
assert testConfig.networkConfig.join.kubernetesConfig.properties.get('service-name') == 'test-service-name'
-
}
def 'Time to Live Verify for Module Sync Semaphore'() {