Improve performance of moduleSetTag lookup
[cps.git] / cps-ncmp-service / src / main / java / org / onap / cps / ncmp / api / impl / inventory / sync / ModuleSyncService.java
index 72d3226..dabfbbc 100644 (file)
@@ -31,16 +31,15 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
 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;
 import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueries;
 import org.onap.cps.ncmp.api.impl.inventory.CmHandleState;
-import org.onap.cps.ncmp.api.impl.inventory.CompositeState;
 import org.onap.cps.ncmp.api.impl.operations.DmiModelOperations;
 import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
@@ -63,7 +62,6 @@ public class ModuleSyncService {
     private final CpsDataService cpsDataService;
     private final CpsAnchorService cpsAnchorService;
     private final JsonObjectMapper jsonObjectMapper;
-    private final Map<String, Collection<ModuleReference>> moduleSetTagCache;
     private static final Map<String, String> NO_NEW_MODULES = Collections.emptyMap();
 
     /**
@@ -73,44 +71,27 @@ public class ModuleSyncService {
      */
     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();
         final String cmHandleId = yangModelCmHandle.getId();
-        final CompositeState compositeState = yangModelCmHandle.getCompositeState();
-        final boolean inUpgrade = ModuleOperationsUtils.isInUpgradeOrUpgradeFailed(compositeState);
-        final String moduleSetTag = getModuleSetTag(yangModelCmHandle, compositeState, inUpgrade);
-
-        final Collection<ModuleReference> moduleReferencesFromCache = moduleSetTagCache.get(moduleSetTag);
-
-        if (moduleReferencesFromCache == null) {
-            final Optional<DataNode> existingCmHandleWithSameModuleSetTag
-                    = getFirstReadyDataNodeWithModuleSetTag(moduleSetTag);
-
-            if (existingCmHandleWithSameModuleSetTag.isPresent()) {
-                final String existingAnchorName = existingCmHandleWithSameModuleSetTag.get().getAnchorName();
-                final Collection<ModuleReference> moduleReferencesFromExistingCmHandle =
-                        upgradeOrCreateSchemaSetUsingModuleSetTag(yangModelCmHandle.getId(), moduleSetTag,
-                                existingAnchorName, inUpgrade);
-                updateModuleSetTagCache(moduleSetTag, moduleReferencesFromExistingCmHandle);
-            } else {
-                if (inUpgrade) {
-                    deleteSchemaSetIfExists(cmHandleId);
-                }
-                final Collection<ModuleReference> allModuleReferencesFromCmHandle
-                        = syncAndCreateSchemaSet(yangModelCmHandle);
-                updateModuleSetTagCache(moduleSetTag, allModuleReferencesFromCmHandle);
-            }
+
+        if (inUpgrade) {
+            cpsModuleService.upgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId,
+                    newYangResources, allModuleReferences);
+            setCmHandleModuleSetTag(yangModelCmHandle, moduleSetTag);
         } else {
-            if (inUpgrade) {
-                cpsModuleService.upgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId,
-                        NO_NEW_MODULES, moduleReferencesFromCache);
-            } else {
-                cpsModuleService.createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME,
-                        cmHandleId, NO_NEW_MODULES, moduleReferencesFromCache);
-            }
-        }
-        if (!inUpgrade) {
+            cpsModuleService.createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId,
+                    newYangResources, allModuleReferences);
             cpsAnchorService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId, cmHandleId);
         }
-        setCmHandleModuleSetTag(yangModelCmHandle, moduleSetTag);
     }
 
     /**
@@ -128,14 +109,37 @@ public class ModuleSyncService {
         }
     }
 
-    private Optional<DataNode> getFirstReadyDataNodeWithModuleSetTag(final String moduleSetTag) {
-        final List<DataNode> dataNodes = StringUtils.isNotBlank(moduleSetTag) ? cmHandleQueries
-                .queryNcmpRegistryByCpsPath("//cm-handles[@module-set-tag='" + moduleSetTag + "']",
-                        FetchDescendantsOption.OMIT_DESCENDANTS) : Collections.emptyList();
-        return dataNodes.stream().filter(dataNode -> {
-            final String cmHandleId = YangDataConverter.extractCmHandleIdFromXpath(dataNode.getXpath());
-            return cmHandleQueries.cmHandleHasState(cmHandleId, CmHandleState.READY);
-        }).findFirst();
+    private ImmutableTriple<String, Map<String, String>, Collection<ModuleReference>>
+        getAllModuleReferencesAndNewYangResourcesByModuleSetTag(final YangModelCmHandle yangModelCmHandle,
+                                                                final boolean inUpgrade) {
+        final String moduleSetTag = getModuleSetTag(yangModelCmHandle, inUpgrade);
+        final Collection<ModuleReference> allModuleReferences;
+        final Map<String, String> newYangResources;
+
+        final YangModelCmHandle cmHandleWithSameModuleSetTag = getAnyReadyCmHandleByModuleSetTag(moduleSetTag);
+        if (cmHandleWithSameModuleSetTag == null) {
+            allModuleReferences = dmiModelOperations.getModuleReferences(yangModelCmHandle);
+            newYangResources = getNewModuleNameToContentMap(yangModelCmHandle, allModuleReferences);
+        } else {
+            log.info("Found other cm handle having same module set tag: {}", moduleSetTag);
+            allModuleReferences = cpsModuleService.getYangResourcesModuleReferences(
+                    NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleWithSameModuleSetTag.getId());
+            newYangResources = NO_NEW_MODULES;
+        }
+        return ImmutableTriple.of(moduleSetTag, newYangResources, allModuleReferences);
+    }
+
+    private YangModelCmHandle getAnyReadyCmHandleByModuleSetTag(final String moduleSetTag) {
+        if (StringUtils.isBlank(moduleSetTag)) {
+            return null;
+        }
+        final String escapedModuleSetTag = moduleSetTag.replace("'", "''");
+        final List<DataNode> dataNodes = cmHandleQueries.queryNcmpRegistryByCpsPath(
+                NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@module-set-tag='" + escapedModuleSetTag + "']",
+                FetchDescendantsOption.DIRECT_CHILDREN_ONLY);
+        return dataNodes.stream().map(YangDataConverter::convertCmHandleToYangModel)
+                .filter(cmHandle -> cmHandle.getCompositeState().getCmHandleState() == CmHandleState.READY)
+                .findFirst().orElse(null);
     }
 
     private void setCmHandleModuleSetTag(final YangModelCmHandle upgradedCmHandle, final String moduleSetTag) {
@@ -148,56 +152,19 @@ public class ModuleSyncService {
                 jsonObjectMapper.asJsonString(dmiRegistryProperties), OffsetDateTime.now());
     }
 
-    private Collection<ModuleReference> syncAndCreateSchemaSet(final YangModelCmHandle yangModelCmHandle) {
-        final Collection<ModuleReference> allModuleReferencesFromCmHandle =
-                dmiModelOperations.getModuleReferences(yangModelCmHandle);
-        final Collection<ModuleReference> identifiedNewModuleReferencesFromCmHandle = cpsModuleService
-                .identifyNewModuleReferences(allModuleReferencesFromCmHandle);
-        final Map<String, String> newModuleNameToContentMap;
-        if (identifiedNewModuleReferencesFromCmHandle.isEmpty()) {
-            newModuleNameToContentMap = NO_NEW_MODULES;
-        } else {
-            newModuleNameToContentMap = dmiModelOperations.getNewYangResourcesFromDmi(yangModelCmHandle,
-                    identifiedNewModuleReferencesFromCmHandle);
-        }
-        cpsModuleService.createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME,
-                yangModelCmHandle.getId(), newModuleNameToContentMap, allModuleReferencesFromCmHandle);
-        return allModuleReferencesFromCmHandle;
-    }
-
-    private Collection<ModuleReference> upgradeOrCreateSchemaSetUsingModuleSetTag(final String schemaSetName,
-                                                                                  final String moduleSetTag,
-                                                                                  final String existingAnchorName,
-                                                                                  final boolean inUpgrade) {
-        log.info("Found cm handle having module set tag: {}", moduleSetTag);
-        final Collection<ModuleReference> moduleReferencesFromExistingCmHandle =
-                cpsModuleService.getYangResourcesModuleReferences(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME,
-                        existingAnchorName);
-        if (inUpgrade) {
-            cpsModuleService.upgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, schemaSetName,
-                    NO_NEW_MODULES, moduleReferencesFromExistingCmHandle);
-        } else {
-            cpsModuleService.createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME,
-                    schemaSetName, NO_NEW_MODULES, moduleReferencesFromExistingCmHandle);
-        }
-        return moduleReferencesFromExistingCmHandle;
+    private Map<String, String> getNewModuleNameToContentMap(final YangModelCmHandle yangModelCmHandle,
+                                                             final Collection<ModuleReference> moduleReferences) {
+        final Collection<ModuleReference> identifiedNewModuleReferences = cpsModuleService
+                .identifyNewModuleReferences(moduleReferences);
+        return dmiModelOperations.getNewYangResourcesFromDmi(yangModelCmHandle, identifiedNewModuleReferences);
     }
 
-    private String getModuleSetTag(final YangModelCmHandle yangModelCmHandle,
-                                   final CompositeState compositeState,
-                                   final boolean inUpgrade) {
+    private String getModuleSetTag(final YangModelCmHandle yangModelCmHandle, final boolean inUpgrade) {
         if (inUpgrade) {
-            return ModuleOperationsUtils.getLockedCompositeStateDetails(compositeState.getLockReason())
-                    .get(ModuleOperationsUtils.MODULE_SET_TAG_KEY);
+            return ModuleOperationsUtils.getUpgradedModuleSetTagFromLockReason(
+                    yangModelCmHandle.getCompositeState().getLockReason());
         }
         return yangModelCmHandle.getModuleSetTag();
     }
 
-    private void updateModuleSetTagCache(final String moduleSetTag,
-                                         final Collection<ModuleReference> allModuleReferencesFromCmHandle) {
-        if (StringUtils.isNotBlank(moduleSetTag)) {
-            moduleSetTagCache.putIfAbsent(moduleSetTag, allModuleReferencesFromCmHandle);
-        }
-    }
-
 }