X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=cps-ncmp-service%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Fcps%2Fncmp%2Fapi%2Fimpl%2FNetworkCmProxyDataServiceImpl.java;h=a37b27199c89ef97a9ef450e9512924db160e910;hb=624f04c03146e002bab2ca88e55b7f586c6e1aff;hp=16b9a66f4eaf2cc76df5e1f388ea54dcb405f420;hpb=7fc07b993a97b223c500b47bbb598b811b0e982e;p=cps.git diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java index 16b9a66f4..a37b27199 100755 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java @@ -1,9 +1,10 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2021 highstreet technologies GmbH - * Modifications Copyright (C) 2021-2022 Nordix Foundation + * Modifications Copyright (C) 2021-2023 Nordix Foundation * Modifications Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2021-2022 Bell Canada + * Modifications Copyright (C) 2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,40 +24,62 @@ package org.onap.cps.ncmp.api.impl; -import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum; -import static org.onap.cps.utils.CmHandleQueryRestParametersValidator.validateCmHandleQueryParameters; +import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLES_NOT_FOUND; +import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLES_NOT_READY; +import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_ALREADY_EXIST; +import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_INVALID_ID; +import static org.onap.cps.ncmp.api.impl.inventory.LockReasonCategory.MODULE_UPGRADE; +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 static org.onap.cps.ncmp.api.impl.utils.RestQueryParametersValidator.validateCmHandleQueryParameters; +import com.google.common.collect.Lists; +import com.hazelcast.map.IMap; +import java.text.MessageFormat; +import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.onap.cps.ncmp.api.NetworkCmProxyCmHandlerQueryService; +import org.onap.cps.api.CpsDataService; +import org.onap.cps.ncmp.api.NetworkCmProxyCmHandleQueryService; import org.onap.cps.ncmp.api.NetworkCmProxyDataService; +import org.onap.cps.ncmp.api.impl.events.lcm.LcmEventsCmHandleStateHandler; +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.CompositeStateBuilder; +import org.onap.cps.ncmp.api.impl.inventory.CompositeStateUtils; +import org.onap.cps.ncmp.api.impl.inventory.DataStoreSyncState; +import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence; import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations; -import org.onap.cps.ncmp.api.impl.operations.DmiOperations; +import org.onap.cps.ncmp.api.impl.operations.OperationType; +import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel; +import org.onap.cps.ncmp.api.impl.utils.CmHandleQueryConditions; +import org.onap.cps.ncmp.api.impl.utils.InventoryQueryConditions; import org.onap.cps.ncmp.api.impl.utils.YangDataConverter; import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle; -import org.onap.cps.ncmp.api.inventory.CmHandleState; -import org.onap.cps.ncmp.api.inventory.CompositeState; -import org.onap.cps.ncmp.api.inventory.InventoryPersistence; import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters; +import org.onap.cps.ncmp.api.models.CmHandleQueryServiceParameters; import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse; -import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse.RegistrationError; +import org.onap.cps.ncmp.api.models.DataOperationRequest; import org.onap.cps.ncmp.api.models.DmiPluginRegistration; import org.onap.cps.ncmp.api.models.DmiPluginRegistrationResponse; import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle; +import org.onap.cps.ncmp.api.models.UpgradedCmHandles; +import org.onap.cps.spi.FetchDescendantsOption; 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.onap.cps.spi.model.CmHandleQueryServiceParameters; import org.onap.cps.spi.model.ModuleDefinition; import org.onap.cps.spi.model.ModuleReference; -import org.onap.cps.utils.CpsValidator; import org.onap.cps.utils.JsonObjectMapper; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; @@ -66,83 +89,98 @@ import org.springframework.stereotype.Service; @RequiredArgsConstructor public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService { + private static final int DELETE_BATCH_SIZE = 100; private final JsonObjectMapper jsonObjectMapper; - private final DmiDataOperations dmiDataOperations; - private final NetworkCmProxyDataServicePropertyHandler networkCmProxyDataServicePropertyHandler; - private final InventoryPersistence inventoryPersistence; - - private final NetworkCmProxyCmHandlerQueryService networkCmProxyCmHandlerQueryService; + private final CmHandleQueries cmHandleQueries; + private final NetworkCmProxyCmHandleQueryService networkCmProxyCmHandleQueryService; + private final LcmEventsCmHandleStateHandler lcmEventsCmHandleStateHandler; + private final CpsDataService cpsDataService; + private final IMap moduleSyncStartedOnCmHandles; + private final Map trustLevelPerDmiPlugin; @Override public DmiPluginRegistrationResponse updateDmiRegistrationAndSyncModule( final DmiPluginRegistration dmiPluginRegistration) { dmiPluginRegistration.validateDmiPluginRegistration(); final DmiPluginRegistrationResponse dmiPluginRegistrationResponse = new DmiPluginRegistrationResponse(); - dmiPluginRegistrationResponse.setRemovedCmHandles( - parseAndRemoveCmHandlesInDmiRegistration(dmiPluginRegistration.getRemovedCmHandles())); + + if (!dmiPluginRegistration.getRemovedCmHandles().isEmpty()) { + dmiPluginRegistrationResponse.setRemovedCmHandles( + parseAndProcessDeletedCmHandlesInRegistration(dmiPluginRegistration.getRemovedCmHandles())); + } + if (!dmiPluginRegistration.getCreatedCmHandles().isEmpty()) { dmiPluginRegistrationResponse.setCreatedCmHandles( - parseAndCreateCmHandlesInDmiRegistrationAndSyncModules(dmiPluginRegistration)); + parseAndProcessCreatedCmHandlesInRegistration(dmiPluginRegistration)); } if (!dmiPluginRegistration.getUpdatedCmHandles().isEmpty()) { dmiPluginRegistrationResponse.setUpdatedCmHandles( networkCmProxyDataServicePropertyHandler .updateCmHandleProperties(dmiPluginRegistration.getUpdatedCmHandles())); } + if (dmiPluginRegistration.getUpgradedCmHandles() != null + && !dmiPluginRegistration.getUpgradedCmHandles().getCmHandles().isEmpty()) { + dmiPluginRegistrationResponse.setUpgradedCmHandles( + parseAndProcessUpgradedCmHandlesInRegistration(dmiPluginRegistration)); + } + + setTrustLevelPerDmiPlugin(dmiPluginRegistration); + return dmiPluginRegistrationResponse; } @Override - public Object getResourceDataOperationalForCmHandle(final String cmHandleId, - final String resourceIdentifier, - final String optionsParamInQuery, - final String topicParamInQuery, - final String requestId) { - final ResponseEntity responseEntity = dmiDataOperations.getResourceDataFromDmi(cmHandleId, - resourceIdentifier, - optionsParamInQuery, - DmiOperations.DataStoreEnum.PASSTHROUGH_OPERATIONAL, - requestId, topicParamInQuery); + public Object getResourceDataForCmHandle(final String datastoreName, + final String cmHandleId, + final String resourceIdentifier, + final String optionsParamInQuery, + final String topicParamInQuery, + final String requestId) { + final ResponseEntity responseEntity = dmiDataOperations.getResourceDataFromDmi(datastoreName, cmHandleId, + resourceIdentifier, + optionsParamInQuery, + topicParamInQuery, + requestId); return responseEntity.getBody(); } @Override - public Object getResourceDataPassThroughRunningForCmHandle(final String cmHandleId, - final String resourceIdentifier, - final String optionsParamInQuery, - final String topicParamInQuery, - final String requestId) { - final ResponseEntity responseEntity = dmiDataOperations.getResourceDataFromDmi(cmHandleId, - resourceIdentifier, - optionsParamInQuery, - DmiOperations.DataStoreEnum.PASSTHROUGH_RUNNING, - requestId, topicParamInQuery); - return responseEntity.getBody(); + public Object getResourceDataForCmHandle(final String datastoreName, + final String cmHandleId, + final String resourceIdentifier, + final FetchDescendantsOption fetchDescendantsOption) { + return cpsDataService.getDataNodes(datastoreName, cmHandleId, resourceIdentifier, + fetchDescendantsOption).iterator().next(); + } + + @Override + public void executeDataOperationForCmHandles(final String topicParamInQuery, + final DataOperationRequest + dataOperationRequest, + final String requestId) { + dmiDataOperations.requestResourceDataFromDmi(topicParamInQuery, dataOperationRequest, requestId); } @Override public Object writeResourceDataPassThroughRunningForCmHandle(final String cmHandleId, final String resourceIdentifier, - final OperationEnum operation, + final OperationType operationType, final String requestData, final String dataType) { - CpsValidator.validateNameCharacters(cmHandleId); - return dmiDataOperations.writeResourceDataPassThroughRunningFromDmi(cmHandleId, resourceIdentifier, operation, - requestData, dataType); + return dmiDataOperations.writeResourceDataPassThroughRunningFromDmi(cmHandleId, resourceIdentifier, + operationType, requestData, dataType); } @Override public Collection getYangResourcesModuleReferences(final String cmHandleId) { - CpsValidator.validateNameCharacters(cmHandleId); return inventoryPersistence.getYangResourcesModuleReferences(cmHandleId); } @Override public Collection getModuleDefinitionsByCmHandleId(final String cmHandleId) { - CpsValidator.validateNameCharacters(cmHandleId); return inventoryPersistence.getModuleDefinitionsByCmHandleId(cmHandleId); } @@ -153,13 +191,12 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService * @return cm handles with details */ @Override - public Set executeCmHandleSearch(final CmHandleQueryApiParameters cmHandleQueryApiParameters) { + public Collection executeCmHandleSearch( + final CmHandleQueryApiParameters cmHandleQueryApiParameters) { final CmHandleQueryServiceParameters cmHandleQueryServiceParameters = jsonObjectMapper.convertToValueType( cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class); - - validateCmHandleQueryParameters(cmHandleQueryServiceParameters); - - return networkCmProxyCmHandlerQueryService.queryCmHandles(cmHandleQueryServiceParameters); + validateCmHandleQueryParameters(cmHandleQueryServiceParameters, CmHandleQueryConditions.ALL_CONDITION_NAMES); + return networkCmProxyCmHandleQueryService.queryCmHandles(cmHandleQueryServiceParameters); } /** @@ -169,13 +206,63 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService * @return cm handle ids */ @Override - public Set executeCmHandleIdSearch(final CmHandleQueryApiParameters cmHandleQueryApiParameters) { + public Collection executeCmHandleIdSearch(final CmHandleQueryApiParameters cmHandleQueryApiParameters) { final CmHandleQueryServiceParameters cmHandleQueryServiceParameters = jsonObjectMapper.convertToValueType( cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class); + validateCmHandleQueryParameters(cmHandleQueryServiceParameters, CmHandleQueryConditions.ALL_CONDITION_NAMES); + return networkCmProxyCmHandleQueryService.queryCmHandleIds(cmHandleQueryServiceParameters); + } + + /** + * Set the data sync enabled flag, along with the data sync state + * based on the data sync enabled boolean for the cm handle id provided. + * + * @param cmHandleId cm handle id + * @param dataSyncEnabled data sync enabled flag + */ + @Override + public void setDataSyncEnabled(final String cmHandleId, final boolean dataSyncEnabled) { + final CompositeState compositeState = inventoryPersistence.getCmHandleState(cmHandleId); + if (compositeState.getDataSyncEnabled().equals(dataSyncEnabled)) { + log.info("Data-Sync Enabled flag is already: {} ", dataSyncEnabled); + } else if (compositeState.getCmHandleState() != CmHandleState.READY) { + throw new CpsException("State mismatch exception.", "Cm-Handle not in READY state. Cm handle state is: " + + compositeState.getCmHandleState()); + } else { + final DataStoreSyncState dataStoreSyncState = compositeState.getDataStores() + .getOperationalDataStore().getDataStoreSyncState(); + if (!dataSyncEnabled && dataStoreSyncState == DataStoreSyncState.SYNCHRONIZED) { + cpsDataService.deleteDataNode(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId, + "/netconf-state", OffsetDateTime.now()); + } + CompositeStateUtils.setDataSyncEnabledFlagWithDataSyncState(dataSyncEnabled, compositeState); + inventoryPersistence.saveCmHandleState(cmHandleId, + compositeState); + } + } - validateCmHandleQueryParameters(cmHandleQueryServiceParameters); + /** + * Get all cm handle IDs by DMI plugin identifier. + * + * @param dmiPluginIdentifier DMI plugin identifier + * @return set of cm handle IDs + */ + @Override + public Collection getAllCmHandleIdsByDmiPluginIdentifier(final String dmiPluginIdentifier) { + return cmHandleQueries.getCmHandleIdsByDmiPluginIdentifier(dmiPluginIdentifier); + } - return networkCmProxyCmHandlerQueryService.queryCmHandleIds(cmHandleQueryServiceParameters); + /** + * Get all cm handle IDs by various properties. + * + * @param cmHandleQueryServiceParameters cm handle query parameters + * @return set of cm handle IDs + */ + @Override + public Collection executeCmHandleIdSearchForInventory( + final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) { + validateCmHandleQueryParameters(cmHandleQueryServiceParameters, InventoryQueryConditions.ALL_CONDITION_NAMES); + return networkCmProxyCmHandleQueryService.queryCmHandleIdsForInventory(cmHandleQueryServiceParameters); } /** @@ -186,7 +273,6 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService */ @Override public NcmpServiceCmHandle getNcmpServiceCmHandle(final String cmHandleId) { - CpsValidator.validateNameCharacters(cmHandleId); return YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle( inventoryPersistence.getYangModelCmHandle(cmHandleId)); } @@ -199,9 +285,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService */ @Override public Map getCmHandlePublicProperties(final String cmHandleId) { - CpsValidator.validateNameCharacters(cmHandleId); - final YangModelCmHandle yangModelCmHandle = - inventoryPersistence.getYangModelCmHandle(cmHandleId); + final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle(cmHandleId); final List yangModelPublicProperties = yangModelCmHandle.getPublicProperties(); final Map cmHandlePublicProperties = new HashMap<>(); YangDataConverter.asPropertiesMap(yangModelPublicProperties, cmHandlePublicProperties); @@ -216,7 +300,6 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService */ @Override public CompositeState getCmHandleCompositeState(final String cmHandleId) { - CpsValidator.validateNameCharacters(cmHandleId); return inventoryPersistence.getYangModelCmHandle(cmHandleId).getCompositeState(); } @@ -226,77 +309,181 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService * @param dmiPluginRegistration dmi plugin registration information. * @return cm-handle registration response for create cm-handle requests. */ - public List parseAndCreateCmHandlesInDmiRegistrationAndSyncModules( + public List parseAndProcessCreatedCmHandlesInRegistration( final DmiPluginRegistration dmiPluginRegistration) { - List cmHandleRegistrationResponses = new ArrayList<>(); - try { - cmHandleRegistrationResponses = dmiPluginRegistration.getCreatedCmHandles().stream() - .map(cmHandle -> { - setCompositeStateToAdvised(cmHandle); - return YangModelCmHandle.toYangModelCmHandle( + final Map cmHandleStatePerCmHandle = new HashMap<>(); + dmiPluginRegistration.getCreatedCmHandles() + .forEach(cmHandle -> { + final YangModelCmHandle yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle( + dmiPluginRegistration.getDmiPlugin(), + dmiPluginRegistration.getDmiDataPlugin(), + dmiPluginRegistration.getDmiModelPlugin(), + cmHandle, + cmHandle.getModuleSetTag()); + cmHandleStatePerCmHandle.put(yangModelCmHandle, CmHandleState.ADVISED); + }); + return registerNewCmHandles(cmHandleStatePerCmHandle); + } + + protected List parseAndProcessDeletedCmHandlesInRegistration( + final List tobeRemovedCmHandles) { + final List cmHandleRegistrationResponses = + new ArrayList<>(tobeRemovedCmHandles.size()); + final Collection yangModelCmHandles = + inventoryPersistence.getYangModelCmHandles(tobeRemovedCmHandles); + + updateCmHandleStateBatch(yangModelCmHandles, CmHandleState.DELETING); + + final Set notDeletedCmHandles = new HashSet<>(); + for (final List tobeRemovedCmHandleBatch : Lists.partition(tobeRemovedCmHandles, DELETE_BATCH_SIZE)) { + try { + batchDeleteCmHandlesFromDbAndModuleSyncMap(tobeRemovedCmHandleBatch); + tobeRemovedCmHandleBatch.forEach(cmHandleId -> + cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createSuccessResponse(cmHandleId))); + + } catch (final RuntimeException batchException) { + log.error("Unable to de-register cm-handle batch, retrying on each cm handle"); + for (final String cmHandleId : tobeRemovedCmHandleBatch) { + final CmHandleRegistrationResponse cmHandleRegistrationResponse = + deleteCmHandleAndGetCmHandleRegistrationResponse(cmHandleId); + cmHandleRegistrationResponses.add(cmHandleRegistrationResponse); + if (cmHandleRegistrationResponse.getStatus() != CmHandleRegistrationResponse.Status.SUCCESS) { + notDeletedCmHandles.add(cmHandleId); + } + } + } + } + + yangModelCmHandles.removeIf(yangModelCmHandle -> notDeletedCmHandles.contains(yangModelCmHandle.getId())); + updateCmHandleStateBatch(yangModelCmHandles, CmHandleState.DELETED); + + return cmHandleRegistrationResponses; + } + + protected List parseAndProcessUpgradedCmHandlesInRegistration( + final DmiPluginRegistration dmiPluginRegistration) { + + final UpgradedCmHandles upgradedCmHandles = dmiPluginRegistration.getUpgradedCmHandles(); + final String moduleSetTag = dmiPluginRegistration.getUpgradedCmHandles().getModuleSetTag(); + final Map cmHandleStatePerCmHandle = + new HashMap<>(upgradedCmHandles.getCmHandles().size()); + final Collection notReadyCmHandles = new ArrayList<>(upgradedCmHandles.getCmHandles().size()); + final NcmpServiceCmHandle ncmpServiceCmHandle = new NcmpServiceCmHandle(); + final String formattedModuleSetTag = MessageFormat.format("new moduleSetTag: {0}", moduleSetTag); + + upgradedCmHandles.getCmHandles().forEach(cmHandleId -> { + if (cmHandleQueries.cmHandleHasState(cmHandleId, CmHandleState.READY)) { + ncmpServiceCmHandle.setCmHandleId(cmHandleId); + ncmpServiceCmHandle.setCompositeState(new CompositeStateBuilder() + .withCmHandleState(CmHandleState.READY) + .withLockReason(MODULE_UPGRADE, formattedModuleSetTag).build()); + final YangModelCmHandle yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle( dmiPluginRegistration.getDmiPlugin(), dmiPluginRegistration.getDmiDataPlugin(), dmiPluginRegistration.getDmiModelPlugin(), - cmHandle); - } - ) - .map(this::registerNewCmHandle) - .collect(Collectors.toList()); + ncmpServiceCmHandle, + moduleSetTag); + cmHandleStatePerCmHandle.put(yangModelCmHandle, CmHandleState.LOCKED); + } else { + notReadyCmHandles.add(cmHandleId); + } + }); + + final List cmHandleRegistrationResponses + = upgradeCmHandles(cmHandleStatePerCmHandle); + cmHandleRegistrationResponses.addAll(CmHandleRegistrationResponse.createFailureResponses(notReadyCmHandles, + CM_HANDLES_NOT_READY)); + return cmHandleRegistrationResponses; + } + + private CmHandleRegistrationResponse deleteCmHandleAndGetCmHandleRegistrationResponse(final String cmHandleId) { + try { + deleteCmHandleFromDbAndModuleSyncMap(cmHandleId); + return CmHandleRegistrationResponse.createSuccessResponse(cmHandleId); + } catch (final DataNodeNotFoundException dataNodeNotFoundException) { + log.error("Unable to find dataNode for cmHandleId : {} , caused by : {}", + cmHandleId, dataNodeNotFoundException.getMessage()); + return CmHandleRegistrationResponse.createFailureResponse(cmHandleId, CM_HANDLES_NOT_FOUND); } catch (final DataValidationException dataValidationException) { - cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createFailureResponse(dmiPluginRegistration - .getCreatedCmHandles().stream() - .map(NcmpServiceCmHandle::getCmHandleId).findFirst().orElse(null), - RegistrationError.CM_HANDLE_INVALID_ID)); + log.error("Unable to de-register cm-handle id: {}, caused by: {}", + cmHandleId, dataValidationException.getMessage()); + return CmHandleRegistrationResponse.createFailureResponse(cmHandleId, CM_HANDLE_INVALID_ID); + } catch (final Exception exception) { + log.error("Unable to de-register cm-handle id : {} , caused by : {}", cmHandleId, exception.getMessage()); + return CmHandleRegistrationResponse.createFailureResponse(cmHandleId, exception); } - return cmHandleRegistrationResponses; } - private void setCompositeStateToAdvised(final NcmpServiceCmHandle ncmpServiceCmHandle) { - final CompositeState compositeState = new CompositeState(); - compositeState.setCmHandleState(CmHandleState.ADVISED); - compositeState.setLastUpdateTimeNow(); - ncmpServiceCmHandle.setCompositeState(compositeState); + private void updateCmHandleStateBatch(final Collection yangModelCmHandles, + final CmHandleState cmHandleState) { + final Map cmHandleStatePerCmHandle = new HashMap<>(yangModelCmHandles.size()); + yangModelCmHandles.forEach(yangModelCmHandle -> cmHandleStatePerCmHandle.put(yangModelCmHandle, cmHandleState)); + lcmEventsCmHandleStateHandler.updateCmHandleStateBatch(cmHandleStatePerCmHandle); } - protected List parseAndRemoveCmHandlesInDmiRegistration( - final List tobeRemovedCmHandles) { - final List cmHandleRegistrationResponses = - new ArrayList<>(tobeRemovedCmHandles.size()); - for (final String cmHandle : tobeRemovedCmHandles) { - try { - CpsValidator.validateNameCharacters(cmHandle); - inventoryPersistence.deleteSchemaSetWithCascade(cmHandle); - inventoryPersistence.deleteListOrListElement("/dmi-registry/cm-handles[@id='" + cmHandle + "']"); - cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createSuccessResponse(cmHandle)); - } catch (final DataNodeNotFoundException dataNodeNotFoundException) { - log.error("Unable to find dataNode for cmHandleId : {} , caused by : {}", - cmHandle, dataNodeNotFoundException.getMessage()); - cmHandleRegistrationResponses.add(CmHandleRegistrationResponse - .createFailureResponse(cmHandle, RegistrationError.CM_HANDLE_DOES_NOT_EXIST)); - } catch (final DataValidationException dataValidationException) { - log.error("Unable to de-register cm-handle id: {}, caused by: {}", - cmHandle, dataValidationException.getMessage()); - cmHandleRegistrationResponses.add(CmHandleRegistrationResponse - .createFailureResponse(cmHandle, RegistrationError.CM_HANDLE_INVALID_ID)); - } catch (final Exception exception) { - log.error("Unable to de-register cm-handle id : {} , caused by : {}", - cmHandle, exception.getMessage()); - cmHandleRegistrationResponses.add( - CmHandleRegistrationResponse.createFailureResponse(cmHandle, exception)); - } + private void deleteCmHandleFromDbAndModuleSyncMap(final String cmHandleId) { + inventoryPersistence.deleteSchemaSetWithCascade(cmHandleId); + inventoryPersistence.deleteDataNode(NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='" + cmHandleId + + "']"); + removeDeletedCmHandleFromModuleSyncMap(cmHandleId); + } + + private void batchDeleteCmHandlesFromDbAndModuleSyncMap(final Collection tobeRemovedCmHandles) { + inventoryPersistence.deleteSchemaSetsWithCascade(tobeRemovedCmHandles); + inventoryPersistence.deleteDataNodes(mapCmHandleIdsToXpaths(tobeRemovedCmHandles)); + tobeRemovedCmHandles.forEach(this::removeDeletedCmHandleFromModuleSyncMap); + } + + private Collection mapCmHandleIdsToXpaths(final Collection cmHandles) { + return cmHandles.stream() + .map(cmHandleId -> NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='" + cmHandleId + "']") + .collect(Collectors.toSet()); + } + + // CPS-1239 Robustness cleaning of in progress cache + private void removeDeletedCmHandleFromModuleSyncMap(final String deletedCmHandleId) { + if (moduleSyncStartedOnCmHandles.remove(deletedCmHandleId) != null) { + log.debug("{} removed from in progress map", deletedCmHandleId); } - return cmHandleRegistrationResponses; } - private CmHandleRegistrationResponse registerNewCmHandle(final YangModelCmHandle yangModelCmHandle) { + private List registerNewCmHandles(final Map + cmHandleStatePerCmHandle) { + final List cmHandleIds = getCmHandleIds(cmHandleStatePerCmHandle); try { - inventoryPersistence.saveCmHandle(yangModelCmHandle); - return CmHandleRegistrationResponse.createSuccessResponse(yangModelCmHandle.getId()); + lcmEventsCmHandleStateHandler.updateCmHandleStateBatch(cmHandleStatePerCmHandle); + return CmHandleRegistrationResponse.createSuccessResponses(cmHandleIds); } catch (final AlreadyDefinedException alreadyDefinedException) { - return CmHandleRegistrationResponse.createFailureResponse( - yangModelCmHandle.getId(), RegistrationError.CM_HANDLE_ALREADY_EXIST); + return CmHandleRegistrationResponse.createFailureResponses( + alreadyDefinedException.getAlreadyDefinedObjectNames(), + CM_HANDLE_ALREADY_EXIST); } catch (final Exception exception) { - return CmHandleRegistrationResponse.createFailureResponse(yangModelCmHandle.getId(), exception); + return CmHandleRegistrationResponse.createFailureResponses(cmHandleIds, exception); } } + + private List upgradeCmHandles(final Map + cmHandleStatePerCmHandle) { + final List cmHandleIds = getCmHandleIds(cmHandleStatePerCmHandle); + log.info("Moving cm handles : {} into locked (for upgrade) state.", cmHandleIds); + try { + lcmEventsCmHandleStateHandler.updateCmHandleStateBatch(cmHandleStatePerCmHandle); + return CmHandleRegistrationResponse.createSuccessResponses(cmHandleIds); + } catch (final Exception exception) { + return CmHandleRegistrationResponse.createFailureResponses(cmHandleIds, exception); + } + } + + private static List getCmHandleIds(final Map cmHandleStatePerCmHandle) { + 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); + } + } + }