diff options
Diffstat (limited to 'cps-ncmp-service/src/main')
12 files changed, 183 insertions, 193 deletions
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cache/AdminCacheConfig.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cache/AdminCacheConfig.java index a29799b13f..fe933d766f 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cache/AdminCacheConfig.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cache/AdminCacheConfig.java @@ -28,7 +28,7 @@ import org.springframework.context.annotation.Configuration; @Configuration public class AdminCacheConfig extends HazelcastCacheConfig { - private static final MapConfig adminCacheMapConfig = createMapConfig("adminCacheMapConfig"); + private static final MapConfig cmHandleStateCacheMapConfig = createMapConfig("cmHandleStateCacheMapConfig"); /** * Distributed instance admin cache map for cm handles by state for use of gauge metrics. @@ -37,13 +37,7 @@ public class AdminCacheConfig extends HazelcastCacheConfig { */ @Bean public IMap<String, Integer> cmHandlesByState() { - final IMap<String, Integer> cmHandlesByState = getOrCreateHazelcastInstance(adminCacheMapConfig).getMap( + return getOrCreateHazelcastInstance(cmHandleStateCacheMapConfig).getMap( "cmHandlesByState"); - cmHandlesByState.putIfAbsent("advisedCmHandlesCount", 0); - cmHandlesByState.putIfAbsent("readyCmHandlesCount", 0); - cmHandlesByState.putIfAbsent("lockedCmHandlesCount", 0); - cmHandlesByState.putIfAbsent("deletingCmHandlesCount", 0); - cmHandlesByState.putIfAbsent("deletedCmHandlesCount", 0); - return cmHandlesByState; } } 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 fc215c9c01..e7fd247a08 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 @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2021-2024 Nordix Foundation + * Copyright (C) 2021-2025 Nordix Foundation * Modifications Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2021-2022 Bell Canada * Modifications Copyright (C) 2023 TechMahindra Ltd. @@ -138,17 +138,20 @@ public class CmHandleRegistrationService { protected void processRemovedCmHandles(final DmiPluginRegistration dmiPluginRegistration, final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) { - final List<String> tobeRemovedCmHandleIds = dmiPluginRegistration.getRemovedCmHandles(); + final List<String> toBeRemovedCmHandleIds = dmiPluginRegistration.getRemovedCmHandles(); + if (toBeRemovedCmHandleIds.isEmpty()) { + return; + } final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses = - new ArrayList<>(tobeRemovedCmHandleIds.size()); + new ArrayList<>(toBeRemovedCmHandleIds.size()); final Collection<YangModelCmHandle> yangModelCmHandles = - inventoryPersistence.getYangModelCmHandles(tobeRemovedCmHandleIds); + inventoryPersistence.getYangModelCmHandles(toBeRemovedCmHandleIds); updateCmHandleStateBatch(yangModelCmHandles, CmHandleState.DELETING); final Set<String> notDeletedCmHandles = new HashSet<>(); - for (final List<String> tobeRemovedCmHandleBatch : Lists.partition(tobeRemovedCmHandleIds, DELETE_BATCH_SIZE)) { + for (final List<String> tobeRemovedCmHandleBatch : Lists.partition(toBeRemovedCmHandleIds, DELETE_BATCH_SIZE)) { try { - batchDeleteCmHandlesFromDbAndCaches(tobeRemovedCmHandleBatch); + deleteCmHandlesFromDbAndCaches(tobeRemovedCmHandleBatch); tobeRemovedCmHandleBatch.forEach(cmHandleId -> cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createSuccessResponse(cmHandleId))); @@ -201,8 +204,9 @@ public class CmHandleRegistrationService { protected void processUpdatedCmHandles(final DmiPluginRegistration dmiPluginRegistration, final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) { - dmiPluginRegistrationResponse.setUpdatedCmHandles(cmHandleRegistrationServicePropertyHandler - .updateCmHandleProperties(dmiPluginRegistration.getUpdatedCmHandles())); + final List<CmHandleRegistrationResponse> updatedCmHandles = cmHandleRegistrationServicePropertyHandler + .updateCmHandleProperties(dmiPluginRegistration.getUpdatedCmHandles()); + dmiPluginRegistrationResponse.setUpdatedCmHandles(updatedCmHandles); } protected void processUpgradedCmHandles( @@ -275,7 +279,7 @@ public class CmHandleRegistrationService { private CmHandleRegistrationResponse deleteCmHandleAndGetCmHandleRegistrationResponse(final String cmHandleId) { try { - deleteCmHandleFromDbAndCaches(cmHandleId); + deleteCmHandlesFromDbAndCaches(Collections.singletonList(cmHandleId)); return CmHandleRegistrationResponse.createSuccessResponse(cmHandleId); } catch (final DataNodeNotFoundException dataNodeNotFoundException) { log.error("Unable to find dataNode for cmHandleId : {} , caused by : {}", @@ -298,16 +302,9 @@ public class CmHandleRegistrationService { lcmEventsCmHandleStateHandler.updateCmHandleStateBatch(cmHandleStatePerCmHandle); } - 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 batchDeleteCmHandlesFromDbAndCaches(final Collection<String> cmHandleIds) { - inventoryPersistence.deleteSchemaSetsWithCascade(cmHandleIds); + private void deleteCmHandlesFromDbAndCaches(final Collection<String> cmHandleIds) { inventoryPersistence.deleteDataNodes(mapCmHandleIdsToXpaths(cmHandleIds)); + inventoryPersistence.deleteAnchors(cmHandleIds); trustLevelManager.removeCmHandles(cmHandleIds); cmHandleIds.forEach(this::removeDeletedCmHandleFromModuleSyncMap); } @@ -326,8 +323,11 @@ public class CmHandleRegistrationService { private List<CmHandleRegistrationResponse> upgradeCmHandles(final Map<YangModelCmHandle, CmHandleState> cmHandleStatePerCmHandle) { + if (cmHandleStatePerCmHandle.isEmpty()) { + return Collections.emptyList(); + } final List<String> cmHandleIds = getCmHandleIds(cmHandleStatePerCmHandle); - log.info("Moving cm handles : {} into locked (for upgrade) state.", cmHandleIds); + log.info("Moving {} cm handles into locked (for upgrade) state: {} ", cmHandleIds.size(), cmHandleIds); try { lcmEventsCmHandleStateHandler.updateCmHandleStateBatch(cmHandleStatePerCmHandle); return CmHandleRegistrationResponse.createSuccessResponses(cmHandleIds); @@ -384,5 +384,4 @@ public class CmHandleRegistrationService { ncmpServiceCmHandle.getDataProducerIdentifier()); } - } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImpl.java index d566ae43cb..e7ec9cd13c 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImpl.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022-2024 Nordix Foundation + * Copyright (C) 2022-2025 Nordix Foundation * Modifications Copyright (C) 2022 Bell Canada * Modifications Copyright (C) 2024 TechMahindra Ltd. * ================================================================================ @@ -62,26 +62,27 @@ public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements Inv private static final int CMHANDLE_BATCH_SIZE = 100; private final CpsModuleService cpsModuleService; - private final CpsAnchorService cpsAnchorService; private final CpsValidator cpsValidator; private final CmHandleQueryService cmHandleQueryService; /** * initialize an inventory persistence object. * - * @param jsonObjectMapper json mapper object - * @param cpsDataService cps data service instance - * @param cpsModuleService cps module service instance - * @param cpsValidator cps validation service instance - * @param cpsAnchorService cps anchor service instance + * @param cpsValidator cps validation service instance + * @param jsonObjectMapper json mapper object + * @param cpsAnchorService cps anchor service instance + * @param cpsModuleService cps module service instance + * @param cpsDataService cps data service instance + * @param cmHandleQueryService cm handle query service instance */ - public InventoryPersistenceImpl(final JsonObjectMapper jsonObjectMapper, final CpsDataService cpsDataService, - final CpsModuleService cpsModuleService, final CpsValidator cpsValidator, + public InventoryPersistenceImpl(final CpsValidator cpsValidator, + final JsonObjectMapper jsonObjectMapper, final CpsAnchorService cpsAnchorService, + final CpsModuleService cpsModuleService, + final CpsDataService cpsDataService, final CmHandleQueryService cmHandleQueryService) { - super(jsonObjectMapper, cpsDataService, cpsModuleService, cpsValidator); + super(jsonObjectMapper, cpsAnchorService, cpsDataService); this.cpsModuleService = cpsModuleService; - this.cpsAnchorService = cpsAnchorService; this.cpsValidator = cpsValidator; this.cmHandleQueryService = cmHandleQueryService; } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/NcmpPersistence.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/NcmpPersistence.java index 714a7ca12f..f327edab17 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/NcmpPersistence.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/NcmpPersistence.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022-2023 Nordix Foundation + * Copyright (C) 2022-2025 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,9 +25,6 @@ import java.util.Collection; import org.onap.cps.api.model.DataNode; import org.onap.cps.api.parameters.FetchDescendantsOption; -/** - * DmiRegistryConstants class to be strictly used for DMI Related constants only. - */ public interface NcmpPersistence { String NCMP_DATASPACE_NAME = "NCMP-Admin"; @@ -44,20 +41,6 @@ public interface NcmpPersistence { void deleteListOrListElement(String listElementXpath); /** - * Method to delete a schema set. - * - * @param schemaSetName schema set name - */ - void deleteSchemaSetWithCascade(String schemaSetName); - - /** - * Method to delete multiple schema sets. - * - * @param schemaSetNames schema set names - */ - void deleteSchemaSetsWithCascade(Collection<String> schemaSetNames); - - /** * Get data node via xpath. * * @param xpath xpath @@ -113,4 +96,12 @@ public interface NcmpPersistence { * @param dataNodeXpaths data node xpaths */ void deleteDataNodes(Collection<String> dataNodeXpaths); + + /** + * Deletes multiple anchors identified by their IDs. + * + * @param anchorIds ids of the anchors to be deleted + */ + void deleteAnchors(Collection<String> anchorIds); + } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/NcmpPersistenceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/NcmpPersistenceImpl.java index 6092d8b3b9..2232d7ce12 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/NcmpPersistenceImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/NcmpPersistenceImpl.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2023 Nordix Foundation + * Copyright (C) 2023-2025 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,31 +20,25 @@ package org.onap.cps.ncmp.impl.inventory; -import static org.onap.cps.api.parameters.CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED; import static org.onap.cps.api.parameters.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS; import io.micrometer.core.annotation.Timed; import java.util.Collection; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; +import org.onap.cps.api.CpsAnchorService; import org.onap.cps.api.CpsDataService; -import org.onap.cps.api.CpsModuleService; -import org.onap.cps.api.exceptions.SchemaSetNotFoundException; import org.onap.cps.api.model.DataNode; import org.onap.cps.api.parameters.FetchDescendantsOption; -import org.onap.cps.impl.utils.CpsValidator; import org.onap.cps.utils.JsonObjectMapper; import org.springframework.stereotype.Component; -@Slf4j @RequiredArgsConstructor @Component public class NcmpPersistenceImpl implements NcmpPersistence { protected final JsonObjectMapper jsonObjectMapper; + protected final CpsAnchorService cpsAnchorService; protected final CpsDataService cpsDataService; - private final CpsModuleService cpsModuleService; - private final CpsValidator cpsValidator; @Override public void deleteListOrListElement(final String listElementXpath) { @@ -53,27 +47,6 @@ public class NcmpPersistenceImpl implements NcmpPersistence { } @Override - @Timed(value = "cps.ncmp.inventory.persistence.schemaset.delete", - description = "Time taken to delete a schemaset") - public void deleteSchemaSetWithCascade(final String schemaSetName) { - try { - cpsValidator.validateNameCharacters(schemaSetName); - cpsModuleService.deleteSchemaSet(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, schemaSetName, - CASCADE_DELETE_ALLOWED); - } catch (final SchemaSetNotFoundException schemaSetNotFoundException) { - log.warn("Schema set {} does not exist or already deleted", schemaSetName); - } - } - - @Override - @Timed(value = "cps.ncmp.inventory.persistence.schemaset.delete.batch", - description = "Time taken to delete multiple schemaset") - public void deleteSchemaSetsWithCascade(final Collection<String> schemaSetNames) { - cpsValidator.validateNameCharacters(schemaSetNames); - cpsModuleService.deleteSchemaSetsWithCascade(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, schemaSetNames); - } - - @Override @Timed(value = "cps.ncmp.inventory.persistence.datanode.get", description = "Time taken to get a data node (from ncmp dmi registry)") public Collection<DataNode> getDataNode(final String xpath) { @@ -116,4 +89,9 @@ public class NcmpPersistenceImpl implements NcmpPersistence { cpsDataService.deleteDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, dataNodeXpaths, NO_TIMESTAMP); } + @Override + public void deleteAnchors(final Collection<String> anchorIds) { + cpsAnchorService.deleteAnchors(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, anchorIds); + } + } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleOperationsUtils.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleOperationsUtils.java index 994ca80287..e9f3d9b475 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleOperationsUtils.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleOperationsUtils.java @@ -189,7 +189,7 @@ public class ModuleOperationsUtils { .getLockReasonCategory())); } - public static String getUpgradedModuleSetTagFromLockReason(final CompositeState.LockReason lockReason) { + public static String getTargetModuleSetTagFromLockReason(final CompositeState.LockReason lockReason) { return getLockedCompositeStateDetails(lockReason).getOrDefault(MODULE_SET_TAG_KEY, ""); } 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 3f92dc73f0..9534cf35b1 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 @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022-2024 Nordix Foundation + * Copyright (C) 2022-2025 Nordix Foundation * Modifications Copyright (C) 2024 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,24 +26,18 @@ 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.api.exceptions.SchemaSetNotFoundException; +import org.onap.cps.api.exceptions.AlreadyDefinedException; +import org.onap.cps.api.exceptions.DuplicatedYangResourceException; import org.onap.cps.api.model.ModuleReference; -import org.onap.cps.api.parameters.CascadeDeleteAllowed; -import org.onap.cps.ncmp.api.exceptions.NcmpException; -import org.onap.cps.ncmp.api.inventory.models.CmHandleState; import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle; import org.onap.cps.utils.ContentType; import org.onap.cps.utils.JsonObjectMapper; @@ -54,15 +48,11 @@ 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 final ISet<String> moduleSetTagsBeingProcessed; - private final Map<String, ModuleDelta> privateModuleSetCache = new HashMap<>(); @AllArgsConstructor private static final class ModuleDelta { @@ -71,42 +61,16 @@ public class ModuleSyncService { } /** - * This method creates a cm handle and initiates modules sync. + * Creates a CM handle and initiates the synchronization of modules to create a schema set and anchor. * * @param yangModelCmHandle the yang model of cm handle. */ public void syncAndCreateSchemaSetAndAnchor(final YangModelCmHandle yangModelCmHandle) { + final String cmHandleId = yangModelCmHandle.getId(); 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); - if (isNewModuleSetTag) { - final ModuleDelta noModuleDelta = new ModuleDelta(moduleDelta.allModuleReferences, NO_NEW_MODULES); - privateModuleSetCache.put(moduleSetTag, noModuleDelta); - } - } finally { - if (isNewModuleSetTag) { - moduleSetTagsBeingProcessed.remove(moduleSetTag); - } - } + final String schemaSetName = getSchemaSetName(cmHandleId, moduleSetTag); + syncAndCreateSchemaSet(yangModelCmHandle, schemaSetName); + cpsAnchorService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, schemaSetName, cmHandleId); } /** @@ -115,55 +79,61 @@ public class ModuleSyncService { * @param yangModelCmHandle the yang model of cm handle. */ public void syncAndUpgradeSchemaSet(final YangModelCmHandle yangModelCmHandle) { - final String upgradedModuleSetTag = ModuleOperationsUtils.getUpgradedModuleSetTagFromLockReason( + final String cmHandleId = yangModelCmHandle.getId(); + final String sourceModuleSetTag = yangModelCmHandle.getModuleSetTag(); + final String targetModuleSetTag = ModuleOperationsUtils.getTargetModuleSetTagFromLockReason( 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); + if (sourceModuleSetTag.isEmpty() && targetModuleSetTag.isEmpty()) { + final ModuleDelta moduleDelta = getModuleDelta(yangModelCmHandle); + cpsModuleService.upgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, + cmHandleId, moduleDelta.newModuleNameToContentMap, moduleDelta.allModuleReferences); + } else { + final String targetSchemaSetName = getSchemaSetName(cmHandleId, targetModuleSetTag); + syncAndCreateSchemaSet(yangModelCmHandle, targetSchemaSetName); + cpsAnchorService.updateAnchorSchemaSet(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId, + targetSchemaSetName); + setCmHandleModuleSetTag(yangModelCmHandle, targetModuleSetTag); + log.info("Upgrading schema set for CM handle ID: {}, Source Tag: {}, Target Tag: {}", + cmHandleId, sourceModuleSetTag, targetModuleSetTag); + } } - /** - * Deletes the SchemaSet for schema set id if the SchemaSet Exists. - * - * @param schemaSetId the schema set id to be deleted - */ - public void deleteSchemaSetIfExists(final String schemaSetId) { - try { - cpsModuleService.deleteSchemaSet(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, schemaSetId, - CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED); - log.debug("SchemaSet for {} has been deleted. Ready to be recreated.", schemaSetId); - } catch (final SchemaSetNotFoundException e) { - log.debug("No SchemaSet for {}. Assuming CmHandle has not been previously Module Synced.", schemaSetId); + private void syncAndCreateSchemaSet(final YangModelCmHandle yangModelCmHandle, final String schemaSetName) { + if (isNewSchemaSet(schemaSetName)) { + final ModuleDelta moduleDelta = getModuleDelta(yangModelCmHandle); + try { + log.info("Creating Schema Set {} for CM Handle {}", schemaSetName, yangModelCmHandle.getId()); + cpsModuleService.createSchemaSetFromModules( + NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, + schemaSetName, + moduleDelta.newModuleNameToContentMap, + moduleDelta.allModuleReferences + ); + log.info("Successfully created Schema Set {} for CM Handle {}", + schemaSetName, yangModelCmHandle.getId()); + } catch (final AlreadyDefinedException | DuplicatedYangResourceException exception) { + log.warn("Schema Set {} already exists, no need to (re)create it for {}", + schemaSetName, yangModelCmHandle.getId()); + } } } - public void clearPrivateModuleSetCache() { - privateModuleSetCache.clear(); + private boolean isNewSchemaSet(final String schemaSetName) { + return !cpsModuleService.schemaSetExists(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, schemaSetName); } - private ModuleDelta getModuleDelta(final YangModelCmHandle yangModelCmHandle, final String targetModuleSetTag) { - final Map<String, String> newYangResources; - Collection<ModuleReference> allModuleReferences = getModuleReferencesByModuleSetTag(targetModuleSetTag); - if (allModuleReferences.isEmpty()) { - allModuleReferences = dmiModelOperations.getModuleReferences(yangModelCmHandle); - newYangResources = dmiModelOperations.getNewYangResourcesFromDmi(yangModelCmHandle, - cpsModuleService.identifyNewModuleReferences(allModuleReferences)); - } else { - log.info("Found other cm handle having same module set tag: {}", targetModuleSetTag); - newYangResources = NO_NEW_MODULES; - } + private ModuleDelta getModuleDelta(final YangModelCmHandle yangModelCmHandle) { + final Collection<ModuleReference> allModuleReferences = + dmiModelOperations.getModuleReferences(yangModelCmHandle); + final Collection<ModuleReference> newModuleReferences = + cpsModuleService.identifyNewModuleReferences(allModuleReferences); + final Map<String, String> newYangResources = dmiModelOperations.getNewYangResourcesFromDmi(yangModelCmHandle, + newModuleReferences); + log.debug("Module delta calculated for CM handle ID: {}. All references: {}. New modules: {}", + yangModelCmHandle.getId(), allModuleReferences, newYangResources.keySet()); return new ModuleDelta(allModuleReferences, newYangResources); } - private Collection<ModuleReference> getModuleReferencesByModuleSetTag(final String moduleSetTag) { - if (Strings.isBlank(moduleSetTag)) { - return Collections.emptyList(); - } - return cpsModuleService.getModuleReferencesByAttribute(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, - Map.of("module-set-tag", moduleSetTag), Map.of("cm-handle-state", CmHandleState.READY.name())); - } - 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))); @@ -171,4 +141,8 @@ public class ModuleSyncService { jsonForUpdate, OffsetDateTime.now(), ContentType.JSON); } + private static String getSchemaSetName(final String cmHandleId, final String moduleSetTag) { + return moduleSetTag.isEmpty() ? cmHandleId : moduleSetTag; + } + } 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 5f289c2c01..40404b719a 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 @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022-2024 Nordix Foundation + * Copyright (C) 2022-2025 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -109,13 +109,12 @@ public class ModuleSyncTasks { if (inUpgrade) { moduleSyncService.syncAndUpgradeSchemaSet(yangModelCmHandle); } else { - moduleSyncService.deleteSchemaSetIfExists(yangModelCmHandle.getId()); moduleSyncService.syncAndCreateSchemaSetAndAnchor(yangModelCmHandle); } compositeState.setLockReason(null); return CmHandleState.READY; } catch (final Exception e) { - log.warn("Processing of {} module failed due to reason {}.", yangModelCmHandle.getId(), e.getMessage()); + log.warn("Processing of {} failed,reason : {}.", yangModelCmHandle.getId(), e.getMessage()); final LockReasonCategory lockReasonCategory = inUpgrade ? LockReasonCategory.MODULE_UPGRADE_FAILED : LockReasonCategory.MODULE_SYNC_FAILED; 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 d6ac242b30..c05944f66e 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 @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================== - * Copyright (C) 2022-2024 Nordix Foundation + * Copyright (C) 2022-2025 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,13 +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 lombok.extern.slf4j.Slf4j; import org.onap.cps.ncmp.impl.cache.HazelcastCacheConfig; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -34,7 +31,6 @@ import org.springframework.context.annotation.Configuration; /** * Core infrastructure of the hazelcast distributed caches for Module Sync and Data Sync use cases. */ -@Slf4j @Configuration public class SynchronizationCacheConfig extends HazelcastCacheConfig { @@ -45,8 +41,6 @@ public class SynchronizationCacheConfig extends HazelcastCacheConfig { private static final MapConfig moduleSyncStartedConfig = createMapConfigWithTimeToLiveInSeconds("moduleSyncStartedConfig", MODULE_SYNC_STARTED_TTL_SECS); private static final MapConfig dataSyncSemaphoresConfig = createMapConfig("dataSyncSemaphoresConfig"); - private static final SetConfig moduleSetTagsBeingProcessedConfig - = createSetConfig("moduleSetTagsBeingProcessedConfig"); /** * Module Sync Distributed Queue Instance. @@ -78,14 +72,4 @@ public class SynchronizationCacheConfig extends HazelcastCacheConfig { return getOrCreateHazelcastInstance(dataSyncSemaphoresConfig).getMap("dataSyncSemaphores"); } - /** - * 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"); - } } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/CmHandleStateMonitor.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/CmHandleStateMonitor.java index 31270ca9fc..708508e9d8 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/CmHandleStateMonitor.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/lcm/CmHandleStateMonitor.java @@ -25,18 +25,42 @@ import com.hazelcast.map.IMap; import java.util.Collection; import java.util.Map; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.onap.cps.ncmp.api.inventory.models.CmHandleState; import org.onap.cps.ncmp.api.inventory.models.CompositeState; +import org.onap.cps.ncmp.impl.inventory.CmHandleQueryService; import org.onap.cps.ncmp.impl.inventory.sync.lcm.LcmEventsCmHandleStateHandlerImpl.CmHandleTransitionPair; +import org.onap.cps.ncmp.utils.events.NcmpInventoryModelOnboardingFinishedEvent; +import org.springframework.context.event.EventListener; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; @Component @RequiredArgsConstructor +@Slf4j public class CmHandleStateMonitor { - private static final String METRIC_POSTFIX = "CmHandlesCount"; - final IMap<String, Integer> cmHandlesByState; + + private final CmHandleQueryService cmHandleQueryService; + private final IMap<String, Integer> cmHandlesByState; + + /** + * Method to initialise cm handle state monitor by querying the current state counts + * and storing them in the provided map. This method is triggered by NcmpInventoryModelOnboardingFinishedEvent. + * + * @param ncmpInventoryModelOnboardingFinishedEvent the event that triggers the initialization + */ + @EventListener + public void initialiseCmHandleStateMonitor( + final NcmpInventoryModelOnboardingFinishedEvent ncmpInventoryModelOnboardingFinishedEvent) { + for (final CmHandleState cmHandleState : CmHandleState.values()) { + final String cmHandleStateAsString = cmHandleState.name().toLowerCase(); + final String stateMetricKey = cmHandleStateAsString + METRIC_POSTFIX; + final int cmHandleCountForState = cmHandleQueryService.queryCmHandleIdsByState(cmHandleState).size(); + cmHandlesByState.putIfAbsent(stateMetricKey, cmHandleCountForState); + log.info("Cm handle state monitor has set " + stateMetricKey + " to " + cmHandleCountForState); + } + } /** * Asynchronously update the cm handle state metrics. diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/InventoryModelLoader.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/InventoryModelLoader.java index 58a5f553af..514d9b8fe4 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/InventoryModelLoader.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/InventoryModelLoader.java @@ -30,11 +30,15 @@ import org.onap.cps.api.CpsDataService; import org.onap.cps.api.CpsDataspaceService; import org.onap.cps.api.CpsModuleService; import org.onap.cps.init.AbstractModelLoader; +import org.onap.cps.ncmp.utils.events.NcmpInventoryModelOnboardingFinishedEvent; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; @Slf4j @Service public class InventoryModelLoader extends AbstractModelLoader { + + private final ApplicationEventPublisher applicationEventPublisher; private static final String NEW_MODEL_FILE_NAME = "dmi-registry@2024-02-23.yang"; private static final String NEW_SCHEMA_SET_NAME = "dmi-registry-2024-02-23"; private static final String REGISTRY_DATANODE_NAME = "dmi-registry"; @@ -42,14 +46,17 @@ public class InventoryModelLoader extends AbstractModelLoader { public InventoryModelLoader(final CpsDataspaceService cpsDataspaceService, final CpsModuleService cpsModuleService, final CpsAnchorService cpsAnchorService, - final CpsDataService cpsDataService) { + final CpsDataService cpsDataService, + final ApplicationEventPublisher applicationEventPublisher) { super(cpsDataspaceService, cpsModuleService, cpsAnchorService, cpsDataService); + this.applicationEventPublisher = applicationEventPublisher; } @Override public void onboardOrUpgradeModel() { updateInventoryModel(); log.info("Inventory Model updated successfully"); + applicationEventPublisher.publishEvent(new NcmpInventoryModelOnboardingFinishedEvent(this)); } private void updateInventoryModel() { diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/NcmpInventoryModelOnboardingFinishedEvent.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/NcmpInventoryModelOnboardingFinishedEvent.java new file mode 100644 index 0000000000..92d5e8241d --- /dev/null +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/NcmpInventoryModelOnboardingFinishedEvent.java @@ -0,0 +1,39 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2025 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.cps.ncmp.utils.events; + +import org.springframework.context.ApplicationEvent; + +/** + * Custom event triggered when the NCMP inventory model onboarding process is completed. + * Extends Spring's {@link ApplicationEvent} to be used within Spring's event-driven architecture. + */ +public class NcmpInventoryModelOnboardingFinishedEvent extends ApplicationEvent { + + /** + * Creates a new instance of NcmpModelOnboardingFinishedEvent. + * + * @param source the object that is the source of the event (i.e. the source that completed the onboarding process) + */ + public NcmpInventoryModelOnboardingFinishedEvent(final Object source) { + super(source); + } +} |