Remove trust level entries from cache when cm handles deleted

- handle removal of device trust levels from the cache when
  cm handles deleted
- handle initial dmi registration inside trust level manager
- add get effective trust level function to trust level manager
  for get and query cm handle APIs (to set trust level on the return
   object)

Issue-ID: CPS-2315

Change-Id: I8daa4a2ad8310de10e35fdc50351deb85fd3ffd0
Signed-off-by: emaclee <lee.anjella.macabuhay@est.tech>
Signed-off-by: halil.cakal <halil.cakal@est.tech>
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/NetworkCmProxyInventoryFacade.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/NetworkCmProxyInventoryFacade.java
index 794bc23..6f51a8d 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/NetworkCmProxyInventoryFacade.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/NetworkCmProxyInventoryFacade.java
@@ -36,7 +36,6 @@
 import org.onap.cps.ncmp.api.inventory.models.DmiPluginRegistration;
 import org.onap.cps.ncmp.api.inventory.models.DmiPluginRegistrationResponse;
 import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle;
-import org.onap.cps.ncmp.api.inventory.models.TrustLevel;
 import org.onap.cps.ncmp.impl.inventory.CmHandleQueryService;
 import org.onap.cps.ncmp.impl.inventory.CmHandleRegistrationService;
 import org.onap.cps.ncmp.impl.inventory.InventoryPersistence;
@@ -44,12 +43,11 @@
 import org.onap.cps.ncmp.impl.inventory.models.CmHandleQueryConditions;
 import org.onap.cps.ncmp.impl.inventory.models.InventoryQueryConditions;
 import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
-import org.onap.cps.ncmp.impl.inventory.trustlevel.TrustLevelCacheConfig;
+import org.onap.cps.ncmp.impl.inventory.trustlevel.TrustLevelManager;
 import org.onap.cps.ncmp.impl.utils.YangDataConverter;
 import org.onap.cps.spi.model.ModuleDefinition;
 import org.onap.cps.spi.model.ModuleReference;
 import org.onap.cps.utils.JsonObjectMapper;
-import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
 @Slf4j
@@ -62,9 +60,7 @@
     private final ParameterizedCmHandleQueryService parameterizedCmHandleQueryService;
     private final InventoryPersistence inventoryPersistence;
     private final JsonObjectMapper jsonObjectMapper;
-
-    @Qualifier(TrustLevelCacheConfig.TRUST_LEVEL_PER_CM_HANDLE)
-    private final Map<String, TrustLevel> trustLevelPerCmHandle;
+    private final TrustLevelManager trustLevelManager;
 
     /**
      * Registration of Created, Removed, Updated or Upgraded CM Handles.
@@ -72,7 +68,6 @@
      * @param dmiPluginRegistration Dmi Plugin Registration details
      * @return dmiPluginRegistrationResponse
      */
-
     public DmiPluginRegistrationResponse updateDmiRegistrationAndSyncModule(
         final DmiPluginRegistration dmiPluginRegistration) {
         return cmHandleRegistrationService.updateDmiRegistrationAndSyncModule(dmiPluginRegistration);
@@ -211,7 +206,8 @@
     }
 
     private void applyCurrentTrustLevel(final NcmpServiceCmHandle ncmpServiceCmHandle) {
-        ncmpServiceCmHandle.setCurrentTrustLevel(trustLevelPerCmHandle.get(ncmpServiceCmHandle.getCmHandleId()));
+        ncmpServiceCmHandle.setCurrentTrustLevel(trustLevelManager
+            .getEffectiveTrustLevel(ncmpServiceCmHandle.getCmHandleId()));
     }
 
 
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationService.java
index d6ddd10..d9f7e38 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationService.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationService.java
@@ -37,6 +37,7 @@
 import java.time.OffsetDateTime;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -58,13 +59,11 @@
 import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
 import org.onap.cps.ncmp.impl.inventory.sync.ModuleOperationsUtils;
 import org.onap.cps.ncmp.impl.inventory.sync.lcm.LcmEventsCmHandleStateHandler;
-import org.onap.cps.ncmp.impl.inventory.trustlevel.TrustLevelCacheConfig;
 import org.onap.cps.ncmp.impl.inventory.trustlevel.TrustLevelManager;
 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.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 
 @Slf4j
@@ -79,11 +78,7 @@
     private final CpsDataService cpsDataService;
     private final LcmEventsCmHandleStateHandler lcmEventsCmHandleStateHandler;
     private final IMap<String, Object> moduleSyncStartedOnCmHandles;
-
-    @Qualifier(TrustLevelCacheConfig.TRUST_LEVEL_PER_DMI_PLUGIN)
-    private final Map<String, TrustLevel> trustLevelPerDmiPlugin;
     private final TrustLevelManager trustLevelManager;
-
     private final AlternateIdChecker alternateIdChecker;
 
     /**
@@ -98,7 +93,7 @@
         dmiPluginRegistration.validateDmiPluginRegistration();
         final DmiPluginRegistrationResponse dmiPluginRegistrationResponse = new DmiPluginRegistrationResponse();
 
-        setTrustLevelPerDmiPlugin(dmiPluginRegistration);
+        trustLevelManager.registerDmiPlugin(dmiPluginRegistration);
 
         processRemovedCmHandles(dmiPluginRegistration, dmiPluginRegistrationResponse);
 
@@ -153,7 +148,7 @@
         final Set<String> notDeletedCmHandles = new HashSet<>();
         for (final List<String> tobeRemovedCmHandleBatch : Lists.partition(tobeRemovedCmHandleIds, DELETE_BATCH_SIZE)) {
             try {
-                batchDeleteCmHandlesFromDbAndModuleSyncMap(tobeRemovedCmHandleBatch);
+                batchDeleteCmHandlesFromDbAndCaches(tobeRemovedCmHandleBatch);
                 tobeRemovedCmHandleBatch.forEach(cmHandleId ->
                     cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createSuccessResponse(cmHandleId)));
 
@@ -259,7 +254,7 @@
                     ncmpServiceCmHandle.getRegistrationTrustLevel());
             }
         }
-        trustLevelManager.handleInitialRegistrationOfTrustLevels(initialTrustLevelPerCmHandleId);
+        trustLevelManager.registerCmHandles(initialTrustLevelPerCmHandleId);
     }
 
     private static boolean moduleUpgradeCanBeSkipped(final YangModelCmHandle yangModelCmHandle,
@@ -280,7 +275,7 @@
 
     private CmHandleRegistrationResponse deleteCmHandleAndGetCmHandleRegistrationResponse(final String cmHandleId) {
         try {
-            deleteCmHandleFromDbAndModuleSyncMap(cmHandleId);
+            deleteCmHandleFromDbAndCaches(cmHandleId);
             return CmHandleRegistrationResponse.createSuccessResponse(cmHandleId);
         } catch (final DataNodeNotFoundException dataNodeNotFoundException) {
             log.error("Unable to find dataNode for cmHandleId : {} , caused by : {}",
@@ -303,15 +298,17 @@
         lcmEventsCmHandleStateHandler.updateCmHandleStateBatch(cmHandleStatePerCmHandle);
     }
 
-    private void deleteCmHandleFromDbAndModuleSyncMap(final String cmHandleId) {
+    private void deleteCmHandleFromDbAndCaches(final String cmHandleId) {
         inventoryPersistence.deleteSchemaSetWithCascade(cmHandleId);
         inventoryPersistence.deleteDataNode(NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='" + cmHandleId + "']");
+        trustLevelManager.removeCmHandles(Collections.singleton(cmHandleId));
         removeDeletedCmHandleFromModuleSyncMap(cmHandleId);
     }
 
-    private void batchDeleteCmHandlesFromDbAndModuleSyncMap(final Collection<String> cmHandleIds) {
+    private void batchDeleteCmHandlesFromDbAndCaches(final Collection<String> cmHandleIds) {
         inventoryPersistence.deleteSchemaSetsWithCascade(cmHandleIds);
         inventoryPersistence.deleteDataNodes(mapCmHandleIdsToXpaths(cmHandleIds));
+        trustLevelManager.removeCmHandles(cmHandleIds);
         cmHandleIds.forEach(this::removeDeletedCmHandleFromModuleSyncMap);
     }
 
@@ -345,14 +342,6 @@
         return cmHandleStatePerCmHandle.keySet().stream().map(YangModelCmHandle::getId).toList();
     }
 
-    private void setTrustLevelPerDmiPlugin(final DmiPluginRegistration dmiPluginRegistration) {
-        if (DmiPluginRegistration.isNullEmptyOrBlank(dmiPluginRegistration.getDmiDataPlugin())) {
-            trustLevelPerDmiPlugin.put(dmiPluginRegistration.getDmiPlugin(), TrustLevel.COMPLETE);
-        } else {
-            trustLevelPerDmiPlugin.put(dmiPluginRegistration.getDmiDataPlugin(), TrustLevel.COMPLETE);
-        }
-    }
-
     private Collection<String> checkAlternateIds(
         final List<NcmpServiceCmHandle> cmHandlesToBeCreated,
         final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses) {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumer.java
index 617fe7f..efcbb78 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumer.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumer.java
@@ -52,7 +52,7 @@
         final DeviceTrustLevel deviceTrustLevel =
             CloudEventMapper.toTargetEvent(consumerRecord.value(), DeviceTrustLevel.class);
         final String trustLevelAsString = deviceTrustLevel.getData().getTrustLevel();
-        trustLevelManager.handleUpdateOfDeviceTrustLevel(cmHandleId, TrustLevel.valueOf(trustLevelAsString));
+        trustLevelManager.updateCmHandleTrustLevel(cmHandleId, TrustLevel.valueOf(trustLevelAsString));
     }
 
 }
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDog.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDog.java
index c81e9b7..94e493d 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDog.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDog.java
@@ -67,7 +67,7 @@
             } else {
                 final Collection<String> cmHandleIds =
                     cmHandleQueryService.getCmHandleIdsByDmiPluginIdentifier(dmiServiceName);
-                trustLevelManager.handleUpdateOfDmiTrustLevel(dmiServiceName, cmHandleIds, newDmiTrustLevel);
+                trustLevelManager.updateDmi(dmiServiceName, cmHandleIds, newDmiTrustLevel);
             }
         });
     }
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelManager.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelManager.java
index 44079c0..50f97a0 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelManager.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelManager.java
@@ -24,6 +24,7 @@
 import java.util.Map;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.api.inventory.models.DmiPluginRegistration;
 import org.onap.cps.ncmp.api.inventory.models.TrustLevel;
 import org.onap.cps.ncmp.impl.inventory.InventoryPersistence;
 import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle;
@@ -49,11 +50,26 @@
     private static final String AVC_NO_OLD_VALUE = null;
 
     /**
+     * Add dmi plugins to the cache.
+     *
+     * @param dmiPluginRegistration a dmi plugin being registered
+     */
+    public void registerDmiPlugin(final DmiPluginRegistration dmiPluginRegistration) {
+        final String dmiServiceName;
+        if (DmiPluginRegistration.isNullEmptyOrBlank(dmiPluginRegistration.getDmiDataPlugin())) {
+            dmiServiceName = dmiPluginRegistration.getDmiPlugin();
+        } else {
+            dmiServiceName = dmiPluginRegistration.getDmiDataPlugin();
+        }
+        trustLevelPerDmiPlugin.put(dmiServiceName, TrustLevel.COMPLETE);
+    }
+
+    /**
      * Add cmHandles to the cache and publish notification for initial trust level of cmHandles if it is NONE.
      *
      * @param cmHandlesToBeCreated a list of cmHandles being created
      */
-    public void handleInitialRegistrationOfTrustLevels(final Map<String, TrustLevel> cmHandlesToBeCreated) {
+    public void registerCmHandles(final Map<String, TrustLevel> cmHandlesToBeCreated) {
         for (final Map.Entry<String, TrustLevel> entry : cmHandlesToBeCreated.entrySet()) {
             final String cmHandleId = entry.getKey();
             if (trustLevelPerCmHandle.containsKey(cmHandleId)) {
@@ -82,15 +98,15 @@
      * @param affectedCmHandleIds   cm handle ids belonging to dmi service name
      * @param newDmiTrustLevel      new trust level of the dmi plugin
      */
-    public void handleUpdateOfDmiTrustLevel(final String dmiServiceName,
-                                            final Collection<String> affectedCmHandleIds,
-                                            final TrustLevel newDmiTrustLevel) {
+    public void updateDmi(final String dmiServiceName,
+                          final Collection<String> affectedCmHandleIds,
+                          final TrustLevel newDmiTrustLevel) {
         final TrustLevel oldDmiTrustLevel  = trustLevelPerDmiPlugin.get(dmiServiceName);
         trustLevelPerDmiPlugin.put(dmiServiceName, newDmiTrustLevel);
         for (final String affectedCmHandleId : affectedCmHandleIds) {
-            final TrustLevel deviceTrustLevel = trustLevelPerCmHandle.get(affectedCmHandleId);
-            final TrustLevel oldEffectiveTrustLevel = deviceTrustLevel.getEffectiveTrustLevel(oldDmiTrustLevel);
-            final TrustLevel newEffectiveTrustLevel = deviceTrustLevel.getEffectiveTrustLevel(newDmiTrustLevel);
+            final TrustLevel cmHandleTrustLevel = trustLevelPerCmHandle.get(affectedCmHandleId);
+            final TrustLevel oldEffectiveTrustLevel = cmHandleTrustLevel.getEffectiveTrustLevel(oldDmiTrustLevel);
+            final TrustLevel newEffectiveTrustLevel = cmHandleTrustLevel.getEffectiveTrustLevel(newDmiTrustLevel);
             sendAvcNotificationIfRequired(affectedCmHandleId, oldEffectiveTrustLevel, newEffectiveTrustLevel);
         }
     }
@@ -100,23 +116,57 @@
      * changed.
      *
      * @param cmHandleId            cm handle id
-     * @param newDeviceTrustLevel   new trust level of the device
+     * @param newCmHandleTrustLevel   new trust level of the device
      */
-    public void handleUpdateOfDeviceTrustLevel(final String cmHandleId,
-                                               final TrustLevel newDeviceTrustLevel) {
-        final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle(cmHandleId);
-        final String dmiServiceName = yangModelCmHandle.resolveDmiServiceName(RequiredDmiService.DATA);
+    public void updateCmHandleTrustLevel(final String cmHandleId,
+                                         final TrustLevel newCmHandleTrustLevel) {
+        final String dmiServiceName = getDmiServiceName(cmHandleId);
 
         final TrustLevel dmiTrustLevel = trustLevelPerDmiPlugin.get(dmiServiceName);
-        final TrustLevel oldDeviceTrustLevel = trustLevelPerCmHandle.get(cmHandleId);
+        final TrustLevel oldCmHandleTrustLevel = trustLevelPerCmHandle.get(cmHandleId);
 
-        final TrustLevel oldEffectiveTrustLevel = oldDeviceTrustLevel.getEffectiveTrustLevel(dmiTrustLevel);
-        final TrustLevel newEffectiveTrustLevel = newDeviceTrustLevel.getEffectiveTrustLevel(dmiTrustLevel);
+        final TrustLevel oldEffectiveTrustLevel = oldCmHandleTrustLevel.getEffectiveTrustLevel(dmiTrustLevel);
+        final TrustLevel newEffectiveTrustLevel = newCmHandleTrustLevel.getEffectiveTrustLevel(dmiTrustLevel);
 
-        trustLevelPerCmHandle.put(cmHandleId, newDeviceTrustLevel);
+        trustLevelPerCmHandle.put(cmHandleId, newCmHandleTrustLevel);
         sendAvcNotificationIfRequired(cmHandleId, oldEffectiveTrustLevel, newEffectiveTrustLevel);
     }
 
+    /**
+     * Select effective trust level among device and dmi plugin.
+     *
+     * @param cmHandleId        cm handle id
+     * @return TrustLevel       effective trust level
+     */
+    public TrustLevel getEffectiveTrustLevel(final String cmHandleId) {
+        final String dmiServiceName = getDmiServiceName(cmHandleId);
+        final TrustLevel dmiTrustLevel = trustLevelPerDmiPlugin.get(dmiServiceName);
+        final TrustLevel cmHandleTrustLevel = trustLevelPerCmHandle.get(cmHandleId);
+        return dmiTrustLevel.getEffectiveTrustLevel(cmHandleTrustLevel);
+    }
+
+    /**
+     * Remove cm handle trust level from the cache and publish notification for trust level of cmHandles
+     * if it is COMPLETE.
+     *
+     * @param cmHandleIds       cm handle ids to be removed from the cache
+     */
+    public void removeCmHandles(final Collection<String> cmHandleIds) {
+        for (final String cmHandleId : cmHandleIds) {
+            if (trustLevelPerCmHandle.containsKey(cmHandleId)) {
+                final TrustLevel oldTrustLevel = trustLevelPerCmHandle.remove(cmHandleId);
+                sendAvcNotificationIfRequired(cmHandleId, oldTrustLevel, TrustLevel.NONE);
+            } else {
+                log.debug("Removed Cm handle: {} is not in trust level cache", cmHandleId);
+            }
+        }
+    }
+
+    private String getDmiServiceName(final String cmHandleId) {
+        final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle(cmHandleId);
+        return yangModelCmHandle.resolveDmiServiceName(RequiredDmiService.DATA);
+    }
+
     private void sendAvcNotificationIfRequired(final String notificationCandidateCmHandleId,
                                                final TrustLevel oldEffectiveTrustLevel,
                                                final TrustLevel newEffectiveTrustLevel) {
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServiceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServiceSpec.groovy
index 0c702ab..dcff2e9 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServiceSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServiceSpec.groovy
@@ -59,13 +59,12 @@
     def mockLcmEventsCmHandleStateHandler = Mock(LcmEventsCmHandleStateHandler)
     def mockCpsDataService = Mock(CpsDataService)
     def mockModuleSyncStartedOnCmHandles = Mock(IMap<String, Object>)
-    def trustLevelPerDmiPlugin = [:]
     def mockTrustLevelManager = Mock(TrustLevelManager)
     def mockAlternateIdChecker = Mock(AlternateIdChecker)
 
     def objectUnderTest = Spy(new CmHandleRegistrationService(
         mockNetworkCmProxyDataServicePropertyHandler, mockInventoryPersistence, mockCpsDataService, mockLcmEventsCmHandleStateHandler,
-        mockModuleSyncStartedOnCmHandles, trustLevelPerDmiPlugin , mockTrustLevelManager, mockAlternateIdChecker))
+        mockModuleSyncStartedOnCmHandles, mockTrustLevelManager, mockAlternateIdChecker))
 
     def setup() {
         // always accept all cm handles
@@ -143,9 +142,6 @@
             objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
         then: 'create cm handles registration and sync modules is called with the correct plugin information'
             1 * objectUnderTest.processCreatedCmHandles(dmiPluginRegistration, _)
-        and: 'dmi is added to the dmi trustLevel map'
-            assert trustLevelPerDmiPlugin.size() == 1
-            assert trustLevelPerDmiPlugin.containsKey(expectedDmiPluginRegisteredName)
         where:
             scenario                          | dmiPlugin  | dmiModelPlugin | dmiDataPlugin || expectedDmiPluginRegisteredName
             'combined DMI plugin'             | 'service1' | ''             | ''            || 'service1'
@@ -212,7 +208,7 @@
         when: 'registration is updated'
             objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration)
         then: 'trustLevel is set for the created cm-handle'
-            1 * mockTrustLevelManager.handleInitialRegistrationOfTrustLevels(expectedMapping)
+            1 * mockTrustLevelManager.registerCmHandles(expectedMapping)
         where:
             scenario                 | registrationTrustLevel || expectedMapping
             'with trusted cm handle' | TrustLevel.COMPLETE    || [ 'ch-1' : TrustLevel.COMPLETE ]
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/NetworkCmProxyInventoryFacadeSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/NetworkCmProxyInventoryFacadeSpec.groovy
index 716efd8..739b2e8 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/NetworkCmProxyInventoryFacadeSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/NetworkCmProxyInventoryFacadeSpec.groovy
@@ -35,6 +35,7 @@
 import org.onap.cps.ncmp.impl.inventory.models.CmHandleState
 import org.onap.cps.ncmp.impl.inventory.models.LockReasonCategory
 import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle
+import org.onap.cps.ncmp.impl.inventory.trustlevel.TrustLevelManager
 import org.onap.cps.spi.model.ConditionProperties
 import org.onap.cps.utils.JsonObjectMapper
 import spock.lang.Specification
@@ -46,9 +47,9 @@
     def mockParameterizedCmHandleQueryService = Mock(ParameterizedCmHandleQueryService)
     def spiedJsonObjectMapper = Spy(new JsonObjectMapper(new ObjectMapper()))
     def mockInventoryPersistence = Mock(InventoryPersistence)
-    def trustLevelPerCmHandle = [:]
+    def mockTrustLevelManager = Mock(TrustLevelManager)
 
-    def objectUnderTest = new NetworkCmProxyInventoryFacade(mockCmHandleRegistrationService, mockCmHandleQueryService, mockParameterizedCmHandleQueryService, mockInventoryPersistence, spiedJsonObjectMapper, trustLevelPerCmHandle)
+    def objectUnderTest = new NetworkCmProxyInventoryFacade(mockCmHandleRegistrationService, mockCmHandleQueryService, mockParameterizedCmHandleQueryService, mockInventoryPersistence, spiedJsonObjectMapper, mockTrustLevelManager)
 
     def 'Update DMI Registration'() {
         given: 'an (updated) dmi plugin registration'
@@ -110,7 +111,7 @@
                  publicProperties: publicProperties, compositeState: compositeState, moduleSetTag: moduleSetTag, alternateId: alternateId)
             1 * mockInventoryPersistence.getYangModelCmHandle('ch-1') >> yangModelCmHandle
         and: 'a trust level for the cm handle in the cache'
-            trustLevelPerCmHandle.put('ch-1', TrustLevel.COMPLETE)
+            mockTrustLevelManager.getEffectiveTrustLevel('ch-1') >> TrustLevel.COMPLETE
         when: 'getting cm handle details for a given cm handle id from ncmp service'
             def result = objectUnderTest.getNcmpServiceCmHandle('ch-1')
         then: 'the result is a ncmpServiceCmHandle'
@@ -205,7 +206,7 @@
                 spiedJsonObjectMapper.convertToValueType(cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class))
                 >> [new NcmpServiceCmHandle(cmHandleId: 'ch-0'), new NcmpServiceCmHandle(cmHandleId: 'ch-1')]
         and: ' a trust level for ch-1'
-            trustLevelPerCmHandle.put('ch-1', TrustLevel.COMPLETE)
+            mockTrustLevelManager.getEffectiveTrustLevel('ch-1') >> TrustLevel.COMPLETE
         when: 'execute cm handle search is called'
             def result = objectUnderTest.executeCmHandleSearch(cmHandleQueryApiParameters)
         then: 'result consists of the two cm handles returned by the CPS Data Service'
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumerSpec.groovy
index 6db304a..c7d0616 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumerSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumerSpec.groovy
@@ -49,7 +49,7 @@
         when: 'the event is consumed'
             objectUnderTest.deviceTrustLevelListener(consumerRecord)
         then: 'cm handles are stored with correct trust level'
-            1 * mockTrustLevelManager.handleUpdateOfDeviceTrustLevel('"ch-1"', TrustLevel.COMPLETE)
+            1 * mockTrustLevelManager.updateCmHandleTrustLevel('"ch-1"', TrustLevel.COMPLETE)
     }
 
     def createTrustLevelEvent(eventPayload) {
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDogSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDogSpec.groovy
index 0a34d26..d4c1f54 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDogSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/DmiPluginTrustLevelWatchDogSpec.groovy
@@ -46,7 +46,7 @@
         when: 'dmi watch dog method runs'
             objectUnderTest.checkDmiAvailability()
         then: 'the update delegated to manager'
-            numberOfCalls * mockTrustLevelManager.handleUpdateOfDmiTrustLevel('dmi-1', _, newDmiTrustLevel)
+            numberOfCalls * mockTrustLevelManager.updateDmi('dmi-1', _, newDmiTrustLevel)
         where: 'the following parameters are used'
             dmiHealhStatus | dmiOldTrustLevel    | newDmiTrustLevel    || numberOfCalls
             'UP'           | TrustLevel.COMPLETE | TrustLevel.COMPLETE || 0
diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelManagerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelManagerSpec.groovy
index b5bfbc1..b017c8b 100644
--- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelManagerSpec.groovy
+++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/trustlevel/TrustLevelManagerSpec.groovy
@@ -20,6 +20,7 @@
 
 package org.onap.cps.ncmp.impl.inventory.trustlevel
 
+import org.onap.cps.ncmp.api.inventory.models.DmiPluginRegistration
 import org.onap.cps.ncmp.api.inventory.models.TrustLevel
 import org.onap.cps.ncmp.impl.inventory.InventoryPersistence
 import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle
@@ -35,11 +36,20 @@
     def mockAttributeValueChangeEventPublisher = Mock(CmAvcEventPublisher)
     def objectUnderTest = new TrustLevelManager(trustLevelPerCmHandle, trustLevelPerDmiPlugin, mockInventoryPersistence, mockAttributeValueChangeEventPublisher)
 
+    def 'Initial dmi registration'() {
+        given: 'a dmi plugin'
+            def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'dmi-1')
+        when: 'method to register to the cache is called'
+            objectUnderTest.registerDmiPlugin(dmiPluginRegistration)
+        then: 'dmi plugin in the cache and trusted'
+            assert trustLevelPerDmiPlugin.get('dmi-1') == TrustLevel.COMPLETE
+    }
+
     def 'Initial cm handle registration'() {
         given: 'two cm handles: one with no trust level and one trusted'
             def cmHandleModelsToBeCreated = ['ch-1': null, 'ch-2': TrustLevel.COMPLETE]
-        when: 'the initial registration handled'
-            objectUnderTest.handleInitialRegistrationOfTrustLevels(cmHandleModelsToBeCreated)
+        when: 'method to register to the cache is called'
+            objectUnderTest.registerCmHandles(cmHandleModelsToBeCreated)
         then: 'no notification sent'
             0 * mockAttributeValueChangeEventPublisher.publishAvcEvent(*_)
         and: 'both cm handles are in the cache and are trusted'
@@ -50,8 +60,8 @@
     def 'Initial cm handle registration with a cm handle that is not trusted'() {
         given: 'a not trusted cm handle'
             def cmHandleModelsToBeCreated = ['ch-2': TrustLevel.NONE]
-        when: 'the initial registration handled'
-            objectUnderTest.handleInitialRegistrationOfTrustLevels(cmHandleModelsToBeCreated)
+        when: 'method to register to the cache is called'
+            objectUnderTest.registerCmHandles(cmHandleModelsToBeCreated)
         then: 'notification is sent'
             1 * mockAttributeValueChangeEventPublisher.publishAvcEvent(*_)
     }
@@ -62,7 +72,7 @@
         and: 'a trusted cm handle'
             trustLevelPerCmHandle.put('ch-1', TrustLevel.COMPLETE)
         when: 'the update is handled'
-            objectUnderTest.handleUpdateOfDmiTrustLevel('my-dmi', ['ch-1'], TrustLevel.NONE)
+            objectUnderTest.updateDmi('my-dmi', ['ch-1'], TrustLevel.NONE)
         then: 'notification is sent'
             1 * mockAttributeValueChangeEventPublisher.publishAvcEvent('ch-1', 'trustLevel', 'COMPLETE', 'NONE')
         and: 'the dmi in the cache is not trusted'
@@ -75,54 +85,89 @@
         and: 'a trusted cm handle'
             trustLevelPerCmHandle.put('ch-1', TrustLevel.COMPLETE)
         when: 'the update is handled'
-            objectUnderTest.handleUpdateOfDmiTrustLevel('my-dmi', ['ch-1'], TrustLevel.COMPLETE)
+            objectUnderTest.updateDmi('my-dmi', ['ch-1'], TrustLevel.COMPLETE)
         then: 'no notification is sent'
             0 * mockAttributeValueChangeEventPublisher.publishAvcEvent(*_)
         and: 'the dmi in the cache is trusted'
             assert trustLevelPerDmiPlugin.get('my-dmi') == TrustLevel.COMPLETE
     }
 
-    def 'Device trust level updated'() {
+    def 'CmHandle trust level updated'() {
         given: 'a non trusted cm handle'
             trustLevelPerCmHandle.put('ch-1', TrustLevel.NONE)
         and: 'a trusted dmi plugin'
             trustLevelPerDmiPlugin.put('my-dmi', TrustLevel.COMPLETE)
         and: 'inventory persistence service returns yang model cm handle'
             mockInventoryPersistence.getYangModelCmHandle('ch-1') >> new YangModelCmHandle(id: 'ch-1', dmiDataServiceName: 'my-dmi')
-        when: 'update of device to COMPLETE trust level handled'
-            objectUnderTest.handleUpdateOfDeviceTrustLevel('ch-1', TrustLevel.COMPLETE)
+        when: 'update of CmHandle to COMPLETE trust level handled'
+            objectUnderTest.updateCmHandleTrustLevel('ch-1', TrustLevel.COMPLETE)
         then: 'the cm handle in the cache is trusted'
             assert trustLevelPerCmHandle.get('ch-1', TrustLevel.COMPLETE)
         and: 'notification is sent'
             1 * mockAttributeValueChangeEventPublisher.publishAvcEvent('ch-1', 'trustLevel', 'NONE', 'COMPLETE')
     }
 
-    def 'Device trust level updated with same value'() {
+    def 'CmHandle trust level updated with same value'() {
         given: 'a non trusted cm handle'
             trustLevelPerCmHandle.put('ch-1', TrustLevel.NONE)
         and: 'a trusted dmi plugin'
             trustLevelPerDmiPlugin.put('my-dmi', TrustLevel.COMPLETE)
         and: 'inventory persistence service returns yang model cm handle'
             mockInventoryPersistence.getYangModelCmHandle('ch-1') >> new YangModelCmHandle(id: 'ch-1', dmiDataServiceName: 'my-dmi')
-        when: 'update of device trust to the same level (NONE)'
-            objectUnderTest.handleUpdateOfDeviceTrustLevel('ch-1', TrustLevel.NONE)
+        when: 'update of CmHandle trust to the same level (NONE)'
+            objectUnderTest.updateCmHandleTrustLevel('ch-1', TrustLevel.NONE)
         then: 'the cm handle in the cache is not trusted'
             assert trustLevelPerCmHandle.get('ch-1', TrustLevel.NONE)
         and: 'no notification is sent'
             0 * mockAttributeValueChangeEventPublisher.publishAvcEvent(*_)
     }
 
-    def 'Dmi trust level restored to complete with non trusted device'() {
+    def 'Dmi trust level restored to complete with non trusted CmHandle'() {
         given: 'a non trusted dmi'
             trustLevelPerDmiPlugin.put('my-dmi', TrustLevel.NONE)
-        and: 'a non trusted device'
+        and: 'a non trusted CmHandle'
             trustLevelPerCmHandle.put('ch-1', TrustLevel.NONE)
         when: 'restore the dmi trust level to COMPLETE'
-            objectUnderTest.handleUpdateOfDmiTrustLevel('my-dmi', ['ch-1'], TrustLevel.COMPLETE)
+            objectUnderTest.updateDmi('my-dmi', ['ch-1'], TrustLevel.COMPLETE)
         then: 'the cm handle in the cache is still NONE'
             assert trustLevelPerCmHandle.get('ch-1') == TrustLevel.NONE
         and: 'no notification is sent'
             0 * mockAttributeValueChangeEventPublisher.publishAvcEvent(*_)
     }
 
+    def 'Select effective trust level among CmHandle and dmi plugin'() {
+        given: 'a non trusted dmi'
+            trustLevelPerDmiPlugin.put('my-dmi', TrustLevel.NONE)
+        and: 'a trusted CmHandle'
+            trustLevelPerCmHandle.put('ch-1', TrustLevel.COMPLETE)
+        and: 'inventory persistence service returns yang model cm handle'
+            mockInventoryPersistence.getYangModelCmHandle('ch-1') >> new YangModelCmHandle(id: 'ch-1', dmiDataServiceName: 'my-dmi')
+        when: 'effective trust level selected'
+            def effectiveTrustLevel = objectUnderTest.getEffectiveTrustLevel('ch-1')
+        then: 'effective trust level is not trusted'
+            assert effectiveTrustLevel == TrustLevel.NONE
+    }
+
+    def 'CmHandle trust level (COMPLETE) removed'() {
+        given: 'a trusted cm handle'
+            trustLevelPerCmHandle.put('ch-1', TrustLevel.COMPLETE)
+        when: 'the remove is handled'
+            objectUnderTest.removeCmHandles(['ch-1'])
+        then: 'cm handle removed from the cache'
+            assert trustLevelPerCmHandle.get('ch-1') == null
+        and: 'notification is sent'
+            1 * mockAttributeValueChangeEventPublisher.publishAvcEvent(_,'trustLevel','COMPLETE','NONE')
+    }
+
+    def 'CmHandle trust level (NONE) removed'() {
+        given: 'a non-trusted cm handle'
+            trustLevelPerCmHandle.put('ch-1', TrustLevel.NONE)
+        when: 'the remove is handled'
+            objectUnderTest.removeCmHandles(['ch-1'])
+        then: 'cm handle removed from the cache'
+            assert trustLevelPerCmHandle.get('ch-1') == null
+        and: 'no notification is sent'
+            0 * mockAttributeValueChangeEventPublisher.publishAvcEvent(*_)
+    }
+
 }
diff --git a/csit/tests/cps-trust-level/cps-trust-level.robot b/csit/tests/cps-trust-level/cps-trust-level.robot
index e4deeff..4db0115 100644
--- a/csit/tests/cps-trust-level/cps-trust-level.robot
+++ b/csit/tests/cps-trust-level/cps-trust-level.robot
@@ -36,7 +36,7 @@
 ${dmiUrl}                                   http://${DMI_HOST}:${DMI_PORT}
 ${jsonCreateCmHandles}                      {"dmiPlugin":"${dmiUrl}","dmiDataPlugin":"","dmiModelPlugin":"","createdCmHandles":[{"trustLevel":"COMPLETE","cmHandle":"CH-1"},{"trustLevel":"COMPLETE","cmHandle":"CH-2"},{"cmHandle":"CH-3"},{"trustLevel":"NONE","cmHandle":"CH-4"}]}
 ${jsonTrustLevelPropertyQueryParameters}    {"cmHandleQueryParameters": [{"conditionName": "cmHandleWithTrustLevel", "conditionParameters": [ {"trustLevel": "COMPLETE"} ] }]}
-${jsonTrustLevelQueryResponse}              {"data":{"attributeValueChange":[{"attributeName":"trustLevel","newAttributeValue":"NONE"}]}}
+${jsonTrustLevelEventPayload}               {"data":{"attributeValueChange":[{"attributeName":"trustLevel","oldAttributeValue":"COMPLETE","newAttributeValue":"NONE"}]}}
 
 *** Test Cases ***
 Register data node
@@ -55,9 +55,9 @@
         Compare Header Values       ${header_key_value_pair[0]}   ${header_key_value_pair[1]}     "ce_specversion"      "1.0"
         Compare Header Values       ${header_key_value_pair[0]}   ${header_key_value_pair[1]}     "ce_source"           "NCMP"
         Compare Header Values       ${header_key_value_pair[0]}   ${header_key_value_pair[1]}     "ce_type"             "org.onap.cps.ncmp.events.avc.ncmp_to_client.AvcEvent"
-        Compare Header Values       ${header_key_value_pair[0]}   ${header_key_value_pair[1]}     "ce_correlationid"    "CH-4"
+        Compare Header Values       ${header_key_value_pair[0]}   ${header_key_value_pair[1]}     "ce_correlationid"    "CmHandleForDelete"
     END
-    Should Be Equal As Strings      ${payload}    ${jsonTrustLevelQueryResponse}
+    Should Be Equal As Strings      ${payload}    ${jsonTrustLevelEventPayload}
     [Teardown]    Basic Teardown    ${group_id}
 
 Retrieve CM Handle ids where query parameters Match (trust level query)