Merge "Add withTrustLevel condition to CmHandle Query API"
[cps.git] / cps-ncmp-service / src / main / java / org / onap / cps / ncmp / api / impl / inventory / sync / ModuleSyncService.java
index b2949c2..8e17ab9 100644 (file)
 
 package org.onap.cps.ncmp.api.impl.inventory.sync;
 
+import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME;
+import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_ANCHOR;
+import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_PARENT;
 import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME;
 
+import java.time.OffsetDateTime;
+import java.util.Arrays;
 import java.util.Collection;
 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.onap.cps.api.CpsAdminService;
+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.inventory.LockReasonCategory;
 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;
 import org.onap.cps.spi.CascadeDeleteAllowed;
+import org.onap.cps.spi.FetchDescendantsOption;
 import org.onap.cps.spi.exceptions.SchemaSetNotFoundException;
+import org.onap.cps.spi.model.DataNode;
 import org.onap.cps.spi.model.ModuleReference;
+import org.onap.cps.utils.JsonObjectMapper;
 import org.springframework.stereotype.Service;
 
 @Slf4j
@@ -43,16 +61,31 @@ public class ModuleSyncService {
 
     private final DmiModelOperations dmiModelOperations;
     private final CpsModuleService cpsModuleService;
-
     private final CpsAdminService cpsAdminService;
+    private final CmHandleQueries cmHandleQueries;
+    private final CpsDataService cpsDataService;
+    private final JsonObjectMapper jsonObjectMapper;
 
     /**
      * This method registers a cm handle and initiates modules sync.
      *
-     * @param yangModelCmHandle the yang model of cm handle.
+     * @param upgradedCmHandle the yang model of cm handle.
      */
-    public void syncAndCreateSchemaSetAndAnchor(final YangModelCmHandle yangModelCmHandle) {
+    public void syncAndCreateOrUpgradeSchemaSetAndAnchor(final YangModelCmHandle upgradedCmHandle) {
+
+        final String moduleSetTag = extractModuleSetTag(upgradedCmHandle.getCompositeState());
+        final Optional<DataNode> existingCmHandleWithSameModuleSetTag
+                = getFirstReadyDataNodeWithModuleSetTag(moduleSetTag);
 
+        if (existingCmHandleWithSameModuleSetTag.isPresent()) {
+            upgradeUsingModuleSetTag(upgradedCmHandle, moduleSetTag);
+        } else {
+            syncAndCreateSchemaSetAndAnchor(upgradedCmHandle);
+        }
+        setCmHandleModuleSetTag(upgradedCmHandle, moduleSetTag);
+    }
+
+    private void syncAndCreateSchemaSetAndAnchor(final YangModelCmHandle yangModelCmHandle) {
         final Collection<ModuleReference> allModuleReferencesFromCmHandle =
                 dmiModelOperations.getModuleReferences(yangModelCmHandle);
 
@@ -73,8 +106,8 @@ public class ModuleSyncService {
                                           final Map<String, String> newModuleNameToContentMap,
                                           final Collection<ModuleReference> allModuleReferencesFromCmHandle) {
         final String schemaSetAndAnchorName = yangModelCmHandle.getId();
-        cpsModuleService.createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, schemaSetAndAnchorName,
-                        newModuleNameToContentMap, allModuleReferencesFromCmHandle);
+        cpsModuleService.createOrUpgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME,
+                schemaSetAndAnchorName, newModuleNameToContentMap, allModuleReferencesFromCmHandle);
         cpsAdminService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, schemaSetAndAnchorName,
             schemaSetAndAnchorName);
     }
@@ -94,4 +127,41 @@ 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 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);
+        cpsDataService.updateNodeLeaves(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, NCMP_DMI_REGISTRY_PARENT,
+                jsonObjectMapper.asJsonString(dmiRegistryProperties), OffsetDateTime.now());
+    }
+
+    private void upgradeUsingModuleSetTag(final YangModelCmHandle upgradedCmHandle, final String moduleSetTag) {
+        log.info("Found cm handle having module set tag: {}", moduleSetTag);
+        final Collection<ModuleReference> moduleReferencesFromExistingCmHandle =
+                cpsModuleService.getYangResourcesModuleReferences(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR);
+        final String upgradedSchemaSetAndAnchorName = upgradedCmHandle.getId();
+        final Map<String, String> noNewModules = Collections.emptyMap();
+        cpsModuleService.createOrUpgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME,
+                upgradedSchemaSetAndAnchorName, noNewModules, moduleReferencesFromExistingCmHandle);
+    }
+
+    private static String extractModuleSetTag(final CompositeState compositeState) {
+        return compositeState.getLockReason() != null && compositeState.getLockReason().getLockReasonCategory()
+                == LockReasonCategory.MODULE_UPGRADE
+                ? Arrays.stream(compositeState.getLockReason().getDetails().split(":")).toList().get(1).trim()
+                : StringUtils.EMPTY;
+    }
+
 }