From a0aa860665b94ce35ecd6253e69959b7cf08ddb7 Mon Sep 17 00:00:00 2001 From: danielhanrahan Date: Wed, 1 Feb 2023 14:48:52 +0000 Subject: CmHandle batch deletion - Use plural deleteDataNodes to remove CmHandles in batches, falling back to individual delete on error - Use single deleteDataNode instead of deleteListOrListElement for individual delete Issue-ID: CPS-1464 Signed-off-by: danielhanrahan Change-Id: If09f22478df8703290c8fc24aa6fe2a11c90788a --- .../api/impl/NetworkCmProxyDataServiceImpl.java | 68 +++++++++++++++------- .../ncmp/api/inventory/InventoryPersistence.java | 11 +++- .../api/inventory/InventoryPersistenceImpl.java | 8 ++- 3 files changed, 63 insertions(+), 24 deletions(-) (limited to 'cps-ncmp-service/src/main/java/org/onap') 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 8b80a0341..a5bd60605 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,7 +1,7 @@ /* * ============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 * ================================================================================ @@ -27,6 +27,7 @@ import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NFP_OPER import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum; import static org.onap.cps.ncmp.api.impl.utils.RestQueryParametersValidator.validateCmHandleQueryParameters; +import com.google.common.collect.Lists; import com.hazelcast.map.IMap; import java.time.OffsetDateTime; import java.util.ArrayList; @@ -78,6 +79,7 @@ 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; @@ -330,25 +332,19 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService .collect(Collectors.toList()); updateCmHandleStateBatch(yangModelCmHandles, CmHandleState.DELETING); - for (final String cmHandleId : tobeRemovedCmHandles) { + for (final List tobeRemovedCmHandleBatch : Lists.partition(tobeRemovedCmHandles, DELETE_BATCH_SIZE)) { try { - deleteCmHandleFromDbAndModuleSyncMap(cmHandleId); - cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createSuccessResponse(cmHandleId)); - } catch (final DataNodeNotFoundException dataNodeNotFoundException) { - log.error("Unable to find dataNode for cmHandleId : {} , caused by : {}", - cmHandleId, dataNodeNotFoundException.getMessage()); - cmHandleRegistrationResponses.add(CmHandleRegistrationResponse - .createFailureResponse(cmHandleId, RegistrationError.CM_HANDLE_DOES_NOT_EXIST)); - } catch (final DataValidationException dataValidationException) { - log.error("Unable to de-register cm-handle id: {}, caused by: {}", - cmHandleId, dataValidationException.getMessage()); - cmHandleRegistrationResponses.add(CmHandleRegistrationResponse - .createFailureResponse(cmHandleId, RegistrationError.CM_HANDLE_INVALID_ID)); - } catch (final Exception exception) { - log.error("Unable to de-register cm-handle id : {} , caused by : {}", - cmHandleId, exception.getMessage()); - cmHandleRegistrationResponses.add( - CmHandleRegistrationResponse.createFailureResponse(cmHandleId, exception)); + batchDeleteCmHandlesFromDbAndModuleSyncMap(tobeRemovedCmHandleBatch); + tobeRemovedCmHandleBatch.forEach(cmHandleId -> + cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createSuccessResponse(cmHandleId))); + + } catch (final Exception 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); + } } } @@ -356,6 +352,26 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService 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, + RegistrationError.CM_HANDLE_DOES_NOT_EXIST); + } catch (final DataValidationException dataValidationException) { + log.error("Unable to de-register cm-handle id: {}, caused by: {}", + cmHandleId, dataValidationException.getMessage()); + return CmHandleRegistrationResponse.createFailureResponse(cmHandleId, + RegistrationError.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); + } + } + private void updateCmHandleStateBatch(final List yangModelCmHandles, final CmHandleState cmHandleState) { final Map cmHandleIdsToBeRemoved = new HashMap<>(); @@ -366,10 +382,22 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService private void deleteCmHandleFromDbAndModuleSyncMap(final String cmHandleId) { inventoryPersistence.deleteSchemaSetWithCascade(cmHandleId); - inventoryPersistence.deleteListOrListElement("/dmi-registry/cm-handles[@id='" + cmHandleId + "']"); + inventoryPersistence.deleteDataNode("/dmi-registry/cm-handles[@id='" + cmHandleId + "']"); removeDeletedCmHandleFromModuleSyncMap(cmHandleId); } + private void batchDeleteCmHandlesFromDbAndModuleSyncMap(final Collection tobeRemovedCmHandles) { + tobeRemovedCmHandles.forEach(inventoryPersistence::deleteSchemaSetWithCascade); + inventoryPersistence.deleteDataNodes(mapCmHandleIdsToXpaths(tobeRemovedCmHandles)); + tobeRemovedCmHandles.forEach(this::removeDeletedCmHandleFromModuleSyncMap); + } + + private Collection mapCmHandleIdsToXpaths(final Collection cmHandles) { + return cmHandles.stream() + .map(cmHandleId -> "/dmi-registry/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) { diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistence.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistence.java index 6d006d9e2..55442ecff 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistence.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistence.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation + * Copyright (C) 2022-2023 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -147,9 +147,16 @@ public interface InventoryPersistence { void replaceListContent(String parentNodeXpath, Collection dataNodes); /** - * Deletes data node for given anchor and dataspace. + * Deletes data node. * * @param dataNodeXpath data node xpath */ void deleteDataNode(String dataNodeXpath); + + /** + * Deletes multiple data nodes. + * + * @param dataNodeXpaths data node xpaths + */ + void deleteDataNodes(Collection dataNodeXpaths); } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistenceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistenceImpl.java index dd165853d..29712f4d0 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistenceImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistenceImpl.java @@ -184,7 +184,11 @@ public class InventoryPersistenceImpl implements InventoryPersistence { @Override public void deleteDataNode(final String dataNodeXpath) { - cpsDataService.deleteDataNode(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, dataNodeXpath, - NO_TIMESTAMP); + cpsDataService.deleteDataNode(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, dataNodeXpath, NO_TIMESTAMP); + } + + @Override + public void deleteDataNodes(final Collection dataNodeXpaths) { + cpsDataService.deleteDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, dataNodeXpaths, NO_TIMESTAMP); } } -- cgit 1.2.3-korg