Introduce class for Module Delta during module sync 40/137340/4
authordanielhanrahan <daniel.hanrahan@est.tech>
Thu, 22 Feb 2024 10:20:17 +0000 (10:20 +0000)
committerdanielhanrahan <daniel.hanrahan@est.tech>
Thu, 22 Feb 2024 10:55:36 +0000 (10:55 +0000)
Removed ImmutableTriple<String, Map<String, String>, Collection<ModuleReference>>
and replaced it with a ModuleDelta class to hold results.

Split syncAndCreateOrUpgradeSchemaSetAndAnchor into methods
syncAndCreateSchemaSetAndAnchor and syncAndUpgradeSchemaSet

Issue-ID: CPS-2027
Signed-off-by: danielhanrahan <daniel.hanrahan@est.tech>
Change-Id: I95462ab55dcae7d98b9e2671fc278c4ded45f3fc

cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncService.java
cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncTasks.java
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncServiceSpec.groovy
cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncTasksSpec.groovy

index dabfbbc..e257112 100644 (file)
@@ -28,13 +28,12 @@ import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NFP_OPE
 import java.time.OffsetDateTime;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import lombok.AllArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.tuple.ImmutableTriple;
 import org.onap.cps.api.CpsAnchorService;
 import org.onap.cps.api.CpsDataService;
 import org.onap.cps.api.CpsModuleService;
@@ -64,34 +63,37 @@ public class ModuleSyncService {
     private final JsonObjectMapper jsonObjectMapper;
     private static final Map<String, String> NO_NEW_MODULES = Collections.emptyMap();
 
+    @AllArgsConstructor
+    private static final class ModuleDelta {
+        Collection<ModuleReference> allModuleReferences;
+        Map<String, String> newModuleNameToContentMap;
+    }
+
     /**
-     * This method registers a cm handle and initiates modules sync.
+     * This method creates a cm handle and initiates modules sync.
      *
      * @param yangModelCmHandle the yang model of cm handle.
      */
-    public void syncAndCreateOrUpgradeSchemaSetAndAnchor(final YangModelCmHandle yangModelCmHandle) {
-
-        final boolean inUpgrade = ModuleOperationsUtils.inUpgradeOrUpgradeFailed(yangModelCmHandle.getCompositeState());
-
-        final ImmutableTriple<String, Map<String, String>, Collection<ModuleReference>>
-                allModuleReferencesAndNewModuleNameByModuleSetTag
-                = getAllModuleReferencesAndNewYangResourcesByModuleSetTag(yangModelCmHandle, inUpgrade);
-
-        final String moduleSetTag = allModuleReferencesAndNewModuleNameByModuleSetTag.getLeft();
-        final Map<String, String> newYangResources = allModuleReferencesAndNewModuleNameByModuleSetTag.getMiddle();
-        final Collection<ModuleReference> allModuleReferences
-                = allModuleReferencesAndNewModuleNameByModuleSetTag.getRight();
+    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,
+                moduleDelta.newModuleNameToContentMap, moduleDelta.allModuleReferences);
+        cpsAnchorService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId, cmHandleId);
+    }
 
-        if (inUpgrade) {
-            cpsModuleService.upgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId,
-                    newYangResources, allModuleReferences);
-            setCmHandleModuleSetTag(yangModelCmHandle, moduleSetTag);
-        } else {
-            cpsModuleService.createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId,
-                    newYangResources, allModuleReferences);
-            cpsAnchorService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId, cmHandleId);
-        }
+    /**
+     * This method upgrades a cm handle and initiates modules sync.
+     *
+     * @param yangModelCmHandle the yang model of cm handle.
+     */
+    public void syncAndUpgradeSchemaSet(final YangModelCmHandle yangModelCmHandle) {
+        final String upgradedModuleSetTag = ModuleOperationsUtils.getUpgradedModuleSetTagFromLockReason(
+                yangModelCmHandle.getCompositeState().getLockReason());
+        final ModuleDelta moduleDelta = getModuleDelta(yangModelCmHandle, upgradedModuleSetTag);
+        cpsModuleService.upgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME,
+                yangModelCmHandle.getId(), moduleDelta.newModuleNameToContentMap, moduleDelta.allModuleReferences);
+        setCmHandleModuleSetTag(yangModelCmHandle, upgradedModuleSetTag);
     }
 
     /**
@@ -109,24 +111,22 @@ public class ModuleSyncService {
         }
     }
 
-    private ImmutableTriple<String, Map<String, String>, Collection<ModuleReference>>
-        getAllModuleReferencesAndNewYangResourcesByModuleSetTag(final YangModelCmHandle yangModelCmHandle,
-                                                                final boolean inUpgrade) {
-        final String moduleSetTag = getModuleSetTag(yangModelCmHandle, inUpgrade);
+    private ModuleDelta getModuleDelta(final YangModelCmHandle yangModelCmHandle, final String targetModuleSetTag) {
         final Collection<ModuleReference> allModuleReferences;
         final Map<String, String> newYangResources;
 
-        final YangModelCmHandle cmHandleWithSameModuleSetTag = getAnyReadyCmHandleByModuleSetTag(moduleSetTag);
+        final YangModelCmHandle cmHandleWithSameModuleSetTag = getAnyReadyCmHandleByModuleSetTag(targetModuleSetTag);
         if (cmHandleWithSameModuleSetTag == null) {
             allModuleReferences = dmiModelOperations.getModuleReferences(yangModelCmHandle);
-            newYangResources = getNewModuleNameToContentMap(yangModelCmHandle, allModuleReferences);
+            newYangResources = dmiModelOperations.getNewYangResourcesFromDmi(yangModelCmHandle,
+                    cpsModuleService.identifyNewModuleReferences(allModuleReferences));
         } else {
-            log.info("Found other cm handle having same module set tag: {}", moduleSetTag);
+            log.info("Found other cm handle having same module set tag: {}", targetModuleSetTag);
             allModuleReferences = cpsModuleService.getYangResourcesModuleReferences(
                     NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleWithSameModuleSetTag.getId());
             newYangResources = NO_NEW_MODULES;
         }
-        return ImmutableTriple.of(moduleSetTag, newYangResources, allModuleReferences);
+        return new ModuleDelta(allModuleReferences, newYangResources);
     }
 
     private YangModelCmHandle getAnyReadyCmHandleByModuleSetTag(final String moduleSetTag) {
@@ -142,29 +142,10 @@ public class ModuleSyncService {
                 .findFirst().orElse(null);
     }
 
-    private void setCmHandleModuleSetTag(final YangModelCmHandle upgradedCmHandle, final String moduleSetTag) {
-        final Map<String, Map<String, String>> dmiRegistryProperties = new HashMap<>(1);
-        final Map<String, String> cmHandleProperties = new HashMap<>(2);
-        cmHandleProperties.put("id", upgradedCmHandle.getId());
-        cmHandleProperties.put("module-set-tag", moduleSetTag);
-        dmiRegistryProperties.put("cm-handles", cmHandleProperties);
+    private void setCmHandleModuleSetTag(final YangModelCmHandle yangModelCmHandle, final String newModuleSetTag) {
+        final String jsonForUpdate = jsonObjectMapper.asJsonString(Map.of(
+                "cm-handles", Map.of("id", yangModelCmHandle.getId(), "module-set-tag", newModuleSetTag)));
         cpsDataService.updateNodeLeaves(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, NCMP_DMI_REGISTRY_PARENT,
-                jsonObjectMapper.asJsonString(dmiRegistryProperties), OffsetDateTime.now());
-    }
-
-    private Map<String, String> getNewModuleNameToContentMap(final YangModelCmHandle yangModelCmHandle,
-                                                             final Collection<ModuleReference> moduleReferences) {
-        final Collection<ModuleReference> identifiedNewModuleReferences = cpsModuleService
-                .identifyNewModuleReferences(moduleReferences);
-        return dmiModelOperations.getNewYangResourcesFromDmi(yangModelCmHandle, identifiedNewModuleReferences);
+                jsonForUpdate, OffsetDateTime.now());
     }
-
-    private String getModuleSetTag(final YangModelCmHandle yangModelCmHandle, final boolean inUpgrade) {
-        if (inUpgrade) {
-            return ModuleOperationsUtils.getUpgradedModuleSetTagFromLockReason(
-                    yangModelCmHandle.getCompositeState().getLockReason());
-        }
-        return yangModelCmHandle.getModuleSetTag();
-    }
-
 }
index 18aac7a..590cb56 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ============LICENSE_START=======================================================
- *  Copyright (C) 2022-2023 Nordix Foundation
+ *  Copyright (C) 2022-2024 Nordix Foundation
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -69,10 +69,12 @@ public class ModuleSyncTasks {
                 final CompositeState compositeState = inventoryPersistence.getCmHandleState(cmHandleId);
                 final boolean inUpgrade = ModuleOperationsUtils.inUpgradeOrUpgradeFailed(compositeState);
                 try {
-                    if (!inUpgrade) {
+                    if (inUpgrade) {
+                        moduleSyncService.syncAndUpgradeSchemaSet(yangModelCmHandle);
+                    } else {
                         moduleSyncService.deleteSchemaSetIfExists(cmHandleId);
+                        moduleSyncService.syncAndCreateSchemaSetAndAnchor(yangModelCmHandle);
                     }
-                    moduleSyncService.syncAndCreateOrUpgradeSchemaSetAndAnchor(yangModelCmHandle);
                     yangModelCmHandle.getCompositeState().setLockReason(null);
                     cmHandelStatePerCmHandle.put(yangModelCmHandle, CmHandleState.READY);
                 } catch (final Exception e) {
index 6ab2d54..0c60e88 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  ============LICENSE_START=======================================================
- *  Copyright (C) 2022-2023 Nordix Foundation
+ *  Copyright (C) 2022-2024 Nordix Foundation
  *  ================================================================================
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -75,7 +75,7 @@ class ModuleSyncServiceSpec extends Specification {
         and: 'system contains other cm handle with "same tag" (that is READY)'
             mockCmHandleQueries.queryNcmpRegistryByCpsPath(*_) >> existingCmHandlesWithSameTag
         when: 'module sync is triggered'
-            objectUnderTest.syncAndCreateOrUpgradeSchemaSetAndAnchor(yangModelCmHandle)
+            objectUnderTest.syncAndCreateSchemaSetAndAnchor(yangModelCmHandle)
         then: 'create schema set from module is invoked with correct parameters'
             1 * mockCpsModuleService.createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, 'ch-1', newModuleNameContentToMap, moduleReferences)
         and: 'anchor is created with the correct parameters'
@@ -108,17 +108,17 @@ class ModuleSyncServiceSpec extends Specification {
         and: 'the other cm handle is a state ready'
             mockCmHandleQueries.cmHandleHasState('otherId', CmHandleState.READY) >> true
         when: 'module sync is triggered'
-            objectUnderTest.syncAndCreateOrUpgradeSchemaSetAndAnchor(yangModelCmHandle)
+            objectUnderTest.syncAndUpgradeSchemaSet(yangModelCmHandle)
         then: 'update schema set from module is invoked for the upgraded cm handle'
-            expectedCallsToUpgradeSchemaSet * mockCpsModuleService.upgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, 'upgraded-ch', [:], moduleReferences)
-        and: 'create schema set from module is invoked for the upgraded cm handle'
-            expectedCallsToCeateSchemaSet * mockCpsModuleService.createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, 'upgraded-ch', [:], moduleReferences)
+            1 * mockCpsModuleService.upgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, 'upgraded-ch', [:], moduleReferences)
+        and: 'create schema set from module is not invoked for the upgraded cm handle'
+            0 * mockCpsModuleService.createSchemaSetFromModules(*_)
         and: 'No anchor is created for the upgraded cm handle'
             0 * mockCpsAnchorService.createAnchor(*_)
         where: 'the following parameters are used'
-            scenario      | existingCmHandlesWithSameTag || expectedCallsToUpgradeSchemaSet | expectedCallsToCeateSchemaSet
-            'new'         | []                           || 1                               | 0
-            'in database' | [cmHandleWithModuleSetTag]   || 1                               | 0
+            scenario      | existingCmHandlesWithSameTag
+            'new'         | []
+            'in database' | [cmHandleWithModuleSetTag]
     }
 
     def 'upgrade model for a existing cm handle'() {
@@ -136,7 +136,7 @@ class ModuleSyncServiceSpec extends Specification {
             mockCmHandleQueries.queryNcmpRegistryByCpsPath(*_) >> [new DataNode(xpath: '/dmi-registry/cm-handles[@id=\'cmHandleId-1\']', leaves: ['id': 'cmHandleId-1'],
                     childDataNodes: [new DataNode(xpath: '/dmi-registry/cm-handles[@id=\'cmHandleId-1\']/state', leaves: ['cm-handle-state': 'READY'])])]
         when: 'module upgrade is triggered'
-            objectUnderTest.syncAndCreateOrUpgradeSchemaSetAndAnchor(yangModelCmHandle)
+            objectUnderTest.syncAndUpgradeSchemaSet(yangModelCmHandle)
         then: 'the upgrade is delegated to the module service (with the correct parameters)'
             1 * mockCpsModuleService.upgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, 'cmHandleId-1', Collections.emptyMap(), moduleReferences)
     }
index ece2d9f..6c0d6df 100644 (file)
@@ -85,8 +85,8 @@ class ModuleSyncTasksSpec extends Specification {
             1 * mockModuleSyncService.deleteSchemaSetIfExists('cm-handle-1')
             1 * mockModuleSyncService.deleteSchemaSetIfExists('cm-handle-2')
         and: 'module sync service is invoked for each cm handle'
-            1 * mockModuleSyncService.syncAndCreateOrUpgradeSchemaSetAndAnchor(_) >> { args -> assertYamgModelCmHandleArgument(args, 'cm-handle-1') }
-            1 * mockModuleSyncService.syncAndCreateOrUpgradeSchemaSetAndAnchor(_) >> { args -> assertYamgModelCmHandleArgument(args, 'cm-handle-2') }
+            1 * mockModuleSyncService.syncAndCreateSchemaSetAndAnchor(_) >> { args -> assert args[0].id == 'cm-handle-1' }
+            1 * mockModuleSyncService.syncAndCreateSchemaSetAndAnchor(_) >> { args -> assert args[0].id == 'cm-handle-2' }
         and: 'the state handler is called for the both cm handles'
             1 * mockLcmEventsCmHandleStateHandler.updateCmHandleStateBatch(_) >> { args ->
                 assertBatch(args, ['cm-handle-1', 'cm-handle-2'], CmHandleState.READY)
@@ -102,7 +102,7 @@ class ModuleSyncTasksSpec extends Specification {
             def cmHandleState = new CompositeState(cmHandleState: CmHandleState.ADVISED)
             1 * mockInventoryPersistence.getCmHandleState('cm-handle') >> cmHandleState
         and: 'module sync service attempts to sync the cm handle and throws an exception'
-            1 * mockModuleSyncService.syncAndCreateOrUpgradeSchemaSetAndAnchor(*_) >> { throw new Exception('some exception') }
+            1 * mockModuleSyncService.syncAndCreateSchemaSetAndAnchor(*_) >> { throw new Exception('some exception') }
         when: 'module sync is executed'
             objectUnderTest.performModuleSync([cmHandle], batchCount)
         then: 'update lock reason, details and attempts is invoked'
@@ -123,7 +123,8 @@ class ModuleSyncTasksSpec extends Specification {
                 .LockReason.builder().lockReasonCategory(lockReasonCategory).details(lockReasonDetails).build())
             1 * mockInventoryPersistence.getCmHandleState('cm-handle') >> expectedCmHandleState
         and: 'module sync service attempts to sync/upgrade the cm handle and throws an exception'
-            1 * mockModuleSyncService.syncAndCreateOrUpgradeSchemaSetAndAnchor(*_) >> { throw new Exception('some exception') }
+            mockModuleSyncService.syncAndCreateSchemaSetAndAnchor(*_) >> { throw new Exception('some exception') }
+            mockModuleSyncService.syncAndUpgradeSchemaSet(*_) >> { throw new Exception('some exception') }
         when: 'module sync is executed'
             objectUnderTest.performModuleSync([cmHandle], batchCount)
         then: 'update lock reason, details and attempts is invoked'
@@ -170,7 +171,7 @@ class ModuleSyncTasksSpec extends Specification {
         when: 'module sync poll is executed'
             objectUnderTest.performModuleSync([cmHandle1], batchCount)
         then: 'module sync service is invoked for cm handle'
-            1 * mockModuleSyncService.syncAndCreateOrUpgradeSchemaSetAndAnchor(_) >> { args -> assertYamgModelCmHandleArgument(args, 'cm-handle-1') }
+            1 * mockModuleSyncService.syncAndCreateSchemaSetAndAnchor(_) >> { args -> assertYamgModelCmHandleArgument(args, 'cm-handle-1') }
         and: 'the entry for other cm handle is still in the progress map'
             assert moduleSyncStartedOnCmHandles.get('other-cm-handle') != null
     }
@@ -202,14 +203,6 @@ class ModuleSyncTasksSpec extends Specification {
         return new DataNode(anchorName: cmHandleId, leaves: ['id': cmHandleId, 'cm-handle-state': cmHandleState])
     }
 
-    def assertYamgModelCmHandleArgument(args, expectedCmHandleId) {
-        {
-            def yangModelCmHandle = args[0]
-            assert yangModelCmHandle.id == expectedCmHandleId
-        }
-        return true
-    }
-
     def assertBatch(args, expectedCmHandleStatePerCmHandleIds, expectedCmHandleState) {
         {
             Map<YangModelCmHandle, CmHandleState> actualCmHandleStatePerCmHandle = args[0]