diff options
Diffstat (limited to 'cps-ncmp-service/src/main/java')
53 files changed, 917 insertions, 623 deletions
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NcmpEventResponseCode.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NcmpResponseStatus.java index 3b11249838..b9c834c559 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NcmpEventResponseCode.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NcmpResponseStatus.java @@ -23,7 +23,7 @@ package org.onap.cps.ncmp.api; import lombok.Getter; @Getter -public enum NcmpEventResponseCode { +public enum NcmpResponseStatus { SUCCESS("0", "Successfully applied changes"), SUCCESSFULLY_APPLIED_SUBSCRIPTION("1", "successfully applied subscription"), @@ -33,13 +33,16 @@ public enum NcmpEventResponseCode { UNABLE_TO_READ_RESOURCE_DATA("103", "dmi plugin service is not able to read resource data"), PARTIALLY_APPLIED_SUBSCRIPTION("104", "partially applied subscription"), SUBSCRIPTION_NOT_APPLICABLE("105", "subscription not applicable for all cm handles"), - SUBSCRIPTION_PENDING("106", "subscription pending for all cm handles"); + SUBSCRIPTION_PENDING("106", "subscription pending for all cm handles"), + UNKNOWN_ERROR("108", "Unknown error"), + CM_HANDLE_ALREADY_EXIST("109", "cm-handle already exists"), + CM_HANDLE_INVALID_ID("110", "cm-handle has an invalid character(s) in id"); - private final String statusCode; - private final String statusMessage; + private final String code; + private final String message; - NcmpEventResponseCode(final String statusCode, final String statusMessage) { - this.statusCode = statusCode; - this.statusMessage = statusMessage; + NcmpResponseStatus(final String code, final String message) { + this.code = code; + this.message = message; } } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java index a65e3c4be1..e7ffaa624f 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NetworkCmProxyDataService.java @@ -25,8 +25,8 @@ package org.onap.cps.ncmp.api; import java.util.Collection; import java.util.Map; +import org.onap.cps.ncmp.api.impl.inventory.CompositeState; import org.onap.cps.ncmp.api.impl.operations.OperationType; -import org.onap.cps.ncmp.api.inventory.CompositeState; import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters; import org.onap.cps.ncmp.api.models.CmHandleQueryServiceParameters; import org.onap.cps.ncmp.api.models.DataOperationRequest; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandleQueryServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandleQueryServiceImpl.java index 1d390f8d16..7475cdd4a3 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandleQueryServiceImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyCmHandleQueryServiceImpl.java @@ -20,6 +20,7 @@ package org.onap.cps.ncmp.api.impl; +import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_PARENT; import static org.onap.cps.ncmp.api.impl.utils.CmHandleQueryConditions.HAS_ALL_MODULES; import static org.onap.cps.ncmp.api.impl.utils.CmHandleQueryConditions.HAS_ALL_PROPERTIES; import static org.onap.cps.ncmp.api.impl.utils.CmHandleQueryConditions.WITH_CPS_PATH; @@ -41,12 +42,12 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.onap.cps.cpspath.parser.PathParsingException; import org.onap.cps.ncmp.api.NetworkCmProxyCmHandleQueryService; +import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueries; +import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence; +import org.onap.cps.ncmp.api.impl.inventory.enums.PropertyType; 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.CmHandleQueries; -import org.onap.cps.ncmp.api.inventory.InventoryPersistence; -import org.onap.cps.ncmp.api.inventory.enums.PropertyType; import org.onap.cps.ncmp.api.models.CmHandleQueryServiceParameters; import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle; import org.onap.cps.spi.exceptions.DataValidationException; @@ -156,7 +157,8 @@ public class NetworkCmProxyCmHandleQueryServiceImpl implements NetworkCmProxyCmH } try { cpsPathQueryResult = collectCmHandleIdsFromDataNodes( - cmHandleQueries.queryCmHandleDataNodesByCpsPath(cpsPathCondition.get("cpsPath"), OMIT_DESCENDANTS)); + cmHandleQueries.queryCmHandleAncestorsByCpsPath( + cpsPathCondition.get("cpsPath"), OMIT_DESCENDANTS)); } catch (final PathParsingException pathParsingException) { throw new DataValidationException(pathParsingException.getMessage(), pathParsingException.getDetails(), pathParsingException); @@ -198,12 +200,12 @@ public class NetworkCmProxyCmHandleQueryServiceImpl implements NetworkCmProxyCmH } private Collection<NcmpServiceCmHandle> getAllCmHandles() { - final DataNode dataNode = inventoryPersistence.getDataNode("/dmi-registry").iterator().next(); + final DataNode dataNode = inventoryPersistence.getDataNode(NCMP_DMI_REGISTRY_PARENT).iterator().next(); return dataNode.getChildDataNodes().stream().map(this::createNcmpServiceCmHandle).collect(Collectors.toSet()); } private Collection<String> getAllCmHandleIds() { - final DataNode dataNode = inventoryPersistence.getDataNode("/dmi-registry", DIRECT_CHILDREN_ONLY) + final DataNode dataNode = inventoryPersistence.getDataNode(NCMP_DMI_REGISTRY_PARENT, DIRECT_CHILDREN_ONLY) .iterator().next(); return collectCmHandleIdsFromDataNodes(dataNode.getChildDataNodes()); } 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 ea2f72fef7..692a9f2a94 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 @@ -24,11 +24,18 @@ package org.onap.cps.ncmp.api.impl; -import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME; +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; @@ -44,26 +51,28 @@ 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.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.CmHandleQueries; -import org.onap.cps.ncmp.api.inventory.CmHandleState; -import org.onap.cps.ncmp.api.inventory.CompositeState; -import org.onap.cps.ncmp.api.inventory.CompositeStateUtils; -import org.onap.cps.ncmp.api.inventory.DataStoreSyncState; -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; @@ -90,6 +99,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService private final LcmEventsCmHandleStateHandler lcmEventsCmHandleStateHandler; private final CpsDataService cpsDataService; private final IMap<String, Object> moduleSyncStartedOnCmHandles; + private final IMap<String, TrustLevel> trustLevelPerDmiPlugin; @Override public DmiPluginRegistrationResponse updateDmiRegistrationAndSyncModule( @@ -99,18 +109,26 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService if (!dmiPluginRegistration.getRemovedCmHandles().isEmpty()) { dmiPluginRegistrationResponse.setRemovedCmHandles( - parseAndRemoveCmHandlesInDmiRegistration(dmiPluginRegistration.getRemovedCmHandles())); + 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; } @@ -204,8 +222,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService */ @Override public void setDataSyncEnabled(final String cmHandleId, final boolean dataSyncEnabled) { - final CompositeState compositeState = inventoryPersistence - .getCmHandleState(cmHandleId); + 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) { @@ -268,8 +285,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService */ @Override public Map<String, String> getCmHandlePublicProperties(final String cmHandleId) { - final YangModelCmHandle yangModelCmHandle = - inventoryPersistence.getYangModelCmHandle(cmHandleId); + final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle(cmHandleId); final List<YangModelCmHandle.Property> yangModelPublicProperties = yangModelCmHandle.getPublicProperties(); final Map<String, String> cmHandlePublicProperties = new HashMap<>(); YangDataConverter.asPropertiesMap(yangModelPublicProperties, cmHandlePublicProperties); @@ -293,7 +309,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService * @param dmiPluginRegistration dmi plugin registration information. * @return cm-handle registration response for create cm-handle requests. */ - public List<CmHandleRegistrationResponse> parseAndCreateCmHandlesInDmiRegistrationAndSyncModules( + public List<CmHandleRegistrationResponse> parseAndProcessCreatedCmHandlesInRegistration( final DmiPluginRegistration dmiPluginRegistration) { final Map<YangModelCmHandle, CmHandleState> cmHandleStatePerCmHandle = new HashMap<>(); dmiPluginRegistration.getCreatedCmHandles() @@ -302,18 +318,19 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService dmiPluginRegistration.getDmiPlugin(), dmiPluginRegistration.getDmiDataPlugin(), dmiPluginRegistration.getDmiModelPlugin(), - cmHandle); + cmHandle, + cmHandle.getModuleSetTag()); cmHandleStatePerCmHandle.put(yangModelCmHandle, CmHandleState.ADVISED); }); return registerNewCmHandles(cmHandleStatePerCmHandle); } - protected List<CmHandleRegistrationResponse> parseAndRemoveCmHandlesInDmiRegistration( + protected List<CmHandleRegistrationResponse> parseAndProcessDeletedCmHandlesInRegistration( final List<String> tobeRemovedCmHandles) { final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses = new ArrayList<>(tobeRemovedCmHandles.size()); final Collection<YangModelCmHandle> yangModelCmHandles = - inventoryPersistence.getYangModelCmHandles(tobeRemovedCmHandles); + inventoryPersistence.getYangModelCmHandles(tobeRemovedCmHandles); updateCmHandleStateBatch(yangModelCmHandles, CmHandleState.DELETING); @@ -343,6 +360,42 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService return cmHandleRegistrationResponses; } + protected List<CmHandleRegistrationResponse> parseAndProcessUpgradedCmHandlesInRegistration( + final DmiPluginRegistration dmiPluginRegistration) { + + final UpgradedCmHandles upgradedCmHandles = dmiPluginRegistration.getUpgradedCmHandles(); + final String moduleSetTag = dmiPluginRegistration.getUpgradedCmHandles().getModuleSetTag(); + final Map<YangModelCmHandle, CmHandleState> cmHandleStatePerCmHandle = + new HashMap<>(upgradedCmHandles.getCmHandles().size()); + final Collection<String> 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(), + ncmpServiceCmHandle, + moduleSetTag); + cmHandleStatePerCmHandle.put(yangModelCmHandle, CmHandleState.LOCKED); + } else { + notReadyCmHandles.add(cmHandleId); + } + }); + + final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses + = upgradeCmHandles(cmHandleStatePerCmHandle); + cmHandleRegistrationResponses.addAll(CmHandleRegistrationResponse.createFailureResponses(notReadyCmHandles, + CM_HANDLES_NOT_READY)); + return cmHandleRegistrationResponses; + } + private CmHandleRegistrationResponse deleteCmHandleAndGetCmHandleRegistrationResponse(final String cmHandleId) { try { deleteCmHandleFromDbAndModuleSyncMap(cmHandleId); @@ -350,13 +403,11 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService } 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); + return CmHandleRegistrationResponse.createFailureResponse(cmHandleId, CM_HANDLES_NOT_FOUND); } 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); + 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); @@ -372,7 +423,8 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService private void deleteCmHandleFromDbAndModuleSyncMap(final String cmHandleId) { inventoryPersistence.deleteSchemaSetWithCascade(cmHandleId); - inventoryPersistence.deleteDataNode("/dmi-registry/cm-handles[@id='" + cmHandleId + "']"); + inventoryPersistence.deleteDataNode(NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='" + cmHandleId + + "']"); removeDeletedCmHandleFromModuleSyncMap(cmHandleId); } @@ -384,8 +436,8 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService private Collection<String> mapCmHandleIdsToXpaths(final Collection<String> cmHandles) { return cmHandles.stream() - .map(cmHandleId -> "/dmi-registry/cm-handles[@id='" + cmHandleId + "']") - .collect(Collectors.toSet()); + .map(cmHandleId -> NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='" + cmHandleId + "']") + .collect(Collectors.toSet()); } // CPS-1239 Robustness cleaning of in progress cache @@ -397,18 +449,41 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService private List<CmHandleRegistrationResponse> registerNewCmHandles(final Map<YangModelCmHandle, CmHandleState> cmHandleStatePerCmHandle) { - final List<String> cmHandleIds = cmHandleStatePerCmHandle.keySet().stream().map(YangModelCmHandle::getId) - .collect(Collectors.toList()); + final List<String> cmHandleIds = getCmHandleIds(cmHandleStatePerCmHandle); try { lcmEventsCmHandleStateHandler.updateCmHandleStateBatch(cmHandleStatePerCmHandle); return CmHandleRegistrationResponse.createSuccessResponses(cmHandleIds); } catch (final AlreadyDefinedException alreadyDefinedException) { return CmHandleRegistrationResponse.createFailureResponses( alreadyDefinedException.getAlreadyDefinedObjectNames(), - RegistrationError.CM_HANDLE_ALREADY_EXIST); + CM_HANDLE_ALREADY_EXIST); + } catch (final Exception exception) { + return CmHandleRegistrationResponse.createFailureResponses(cmHandleIds, exception); + } + } + + private List<CmHandleRegistrationResponse> upgradeCmHandles(final Map<YangModelCmHandle, CmHandleState> + cmHandleStatePerCmHandle) { + final List<String> 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<String> getCmHandleIds(final Map<YangModelCmHandle, CmHandleState> 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); + } + } + } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandler.java index bbb2c0f56f..401b190360 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandler.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServicePropertyHandler.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022 Nordix Foundation + * Copyright (C) 2022-2023 Nordix Foundation * Modifications Copyright (C) 2022 Bell Canada * Modifications Copyright (C) 2023 TechMahindra Ltd. * ================================================================================ @@ -22,6 +22,8 @@ package org.onap.cps.ncmp.api.impl; +import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLES_NOT_FOUND; +import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_INVALID_ID; import static org.onap.cps.ncmp.api.impl.NetworkCmProxyDataServicePropertyHandler.PropertyType.DMI_PROPERTY; import static org.onap.cps.ncmp.api.impl.NetworkCmProxyDataServicePropertyHandler.PropertyType.PUBLIC_PROPERTY; @@ -36,9 +38,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.onap.cps.ncmp.api.inventory.InventoryPersistence; +import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence; import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse; -import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse.RegistrationError; import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle; import org.onap.cps.spi.exceptions.DataNodeNotFoundException; import org.onap.cps.spi.exceptions.DataValidationException; @@ -75,13 +76,12 @@ public class NetworkCmProxyDataServicePropertyHandler { log.error("Unable to find dataNode for cmHandleId : {} , caused by : {}", cmHandleId, e.getMessage()); cmHandleRegistrationResponses.add(CmHandleRegistrationResponse - .createFailureResponse(cmHandleId, RegistrationError.CM_HANDLE_DOES_NOT_EXIST)); + .createFailureResponse(cmHandleId, CM_HANDLES_NOT_FOUND)); } catch (final DataValidationException e) { log.error("Unable to update cm handle : {}, caused by : {}", cmHandleId, e.getMessage()); cmHandleRegistrationResponses.add( - CmHandleRegistrationResponse.createFailureResponse(cmHandleId, - RegistrationError.CM_HANDLE_INVALID_ID)); + CmHandleRegistrationResponse.createFailureResponse(cmHandleId, CM_HANDLE_INVALID_ID)); } catch (final Exception exception) { log.error("Unable to update cmHandle : {} , caused by : {}", cmHandleId, exception.getMessage()); diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyQueryServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyQueryServiceImpl.java index 5540ecd213..d8353f3029 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyQueryServiceImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyQueryServiceImpl.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. @@ -20,7 +20,7 @@ package org.onap.cps.ncmp.api.impl; -import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME; +import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationCacheConfig.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationCacheConfig.java index 62a380ca5c..8b28717db4 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationCacheConfig.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/SynchronizationCacheConfig.java @@ -23,6 +23,7 @@ package org.onap.cps.ncmp.api.impl.config.embeddedcache; import com.hazelcast.config.MapConfig; import com.hazelcast.config.QueueConfig; import com.hazelcast.map.IMap; +import java.util.Set; import java.util.concurrent.BlockingQueue; import lombok.extern.slf4j.Slf4j; import org.onap.cps.cache.HazelcastCacheConfig; @@ -44,6 +45,8 @@ public class SynchronizationCacheConfig extends HazelcastCacheConfig { private static final MapConfig moduleSyncStartedConfig = createMapConfig("moduleSyncStartedConfig"); private static final MapConfig dataSyncSemaphoresConfig = createMapConfig("dataSyncSemaphoresConfig"); + private static final MapConfig moduleSetTagCacheMapConfig = createMapConfig("moduleSetTagCacheMapConfig"); + /** * Module Sync Distributed Queue Instance. * @@ -74,4 +77,15 @@ public class SynchronizationCacheConfig extends HazelcastCacheConfig { public IMap<String, Boolean> dataSyncSemaphores() { return createHazelcastInstance("dataSyncSemaphores", dataSyncSemaphoresConfig).getMap("dataSyncSemaphores"); } + + /** + * IMap instance for cached ModulesSetTags. + * + * @return configured map of ModuleSetTags + */ + @Bean + public IMap<String, Set<String>> moduleSetTagCache() { + return createHazelcastInstance("moduleSetTags", moduleSetTagCacheMapConfig) + .getMap("moduleSetTagCache"); + } } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/constants/DmiRegistryConstants.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/constants/DmiRegistryConstants.java deleted file mode 100644 index a133cfb80d..0000000000 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/constants/DmiRegistryConstants.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2022 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.api.impl.constants; - -import java.time.OffsetDateTime; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; - -/** - * DmiRegistryConstants class to be strictly used for DMI Related constants only. - */ -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public final class DmiRegistryConstants { - - public static final String NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME = "NFP-Operational"; - - public static final OffsetDateTime NO_TIMESTAMP = null; -} diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/EventsPublisher.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/EventsPublisher.java index 58d0d2d48f..355e5cdf79 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/EventsPublisher.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/EventsPublisher.java @@ -64,8 +64,8 @@ public class EventsPublisher<T> { cloudEventKafkaTemplate.send(topicName, eventKey, event); eventFuture.whenComplete((result, e) -> { if (e == null) { - log.debug("Successfully published event to topic : {} , Event : {}", - result.getRecordMetadata().topic(), result.getProducerRecord().value()); + log.debug("Successfully published event to topic : {} , Event : {}", result.getRecordMetadata().topic(), + result.getProducerRecord().value()); } else { log.error("Unable to publish event to topic : {} due to {}", topicName, e.getMessage()); @@ -85,14 +85,7 @@ public class EventsPublisher<T> { public void publishEvent(final String topicName, final String eventKey, final T event) { final CompletableFuture<SendResult<String, T>> eventFuture = legacyKafkaEventTemplate.send(topicName, eventKey, event); - eventFuture.whenComplete((result, e) -> { - if (e == null) { - log.debug("Successfully published event to topic : {} , Event : {}", - result.getRecordMetadata().topic(), result.getProducerRecord().value()); - } else { - log.error("Unable to publish event to topic : {} due to {}", topicName, e.getMessage()); - } - }); + handleLegacyEventCallback(topicName, eventFuture); } /** @@ -107,16 +100,8 @@ public class EventsPublisher<T> { final ProducerRecord<String, T> producerRecord = new ProducerRecord<>(topicName, null, eventKey, event, eventHeaders); - final CompletableFuture<SendResult<String, T>> eventFuture = - legacyKafkaEventTemplate.send(producerRecord); - eventFuture.whenComplete((result, ex) -> { - if (ex != null) { - log.error("Unable to publish event to topic : {} due to {}", topicName, ex.getMessage()); - } else { - log.debug("Successfully published event to topic : {} , Event : {}", - result.getRecordMetadata().topic(), result.getProducerRecord().value()); - } - }); + final CompletableFuture<SendResult<String, T>> eventFuture = legacyKafkaEventTemplate.send(producerRecord); + handleLegacyEventCallback(topicName, eventFuture); } /** @@ -133,6 +118,17 @@ public class EventsPublisher<T> { publishEvent(topicName, eventKey, convertToKafkaHeaders(eventHeaders), event); } + private void handleLegacyEventCallback(final String topicName, + final CompletableFuture<SendResult<String, T>> eventFuture) { + eventFuture.whenComplete((result, e) -> { + if (e != null) { + log.error("Unable to publish event to topic : {} due to {}", topicName, e.getMessage()); + } else { + log.debug("Successfully published event to topic : {} , Event : {}", result.getRecordMetadata().topic(), + result.getProducerRecord().value()); + } + }); + } private Headers convertToKafkaHeaders(final Map<String, Object> eventMessageHeaders) { final Headers eventHeaders = new RecordHeaders(); diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpInEventForwarder.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpInEventForwarder.java index ea2d17d3a7..5f26db335b 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpInEventForwarder.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpInEventForwarder.java @@ -36,13 +36,13 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.onap.cps.ncmp.api.impl.config.embeddedcache.ForwardedSubscriptionEventCacheConfig; import org.onap.cps.ncmp.api.impl.events.EventsPublisher; +import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence; import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionPersistence; import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus; import org.onap.cps.ncmp.api.impl.utils.CmSubscriptionEventCloudMapper; import org.onap.cps.ncmp.api.impl.utils.DmiServiceNameOrganizer; import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle; import org.onap.cps.ncmp.api.impl.yangmodels.YangModelSubscriptionEvent; -import org.onap.cps.ncmp.api.inventory.InventoryPersistence; import org.onap.cps.ncmp.api.models.CmSubscriptionEvent; import org.onap.cps.ncmp.events.cmsubscription1_0_0.client_to_ncmp.CmSubscriptionNcmpInEvent; import org.onap.cps.ncmp.events.cmsubscription1_0_0.ncmp_to_dmi.CmHandle; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpOutEventPublisher.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpOutEventPublisher.java index 473538c93e..a0fd81c12a 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpOutEventPublisher.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/cmsubscription/CmSubscriptionNcmpOutEventPublisher.java @@ -20,13 +20,20 @@ package org.onap.cps.ncmp.api.impl.events.cmsubscription; +import static org.onap.cps.ncmp.api.NcmpResponseStatus.PARTIALLY_APPLIED_SUBSCRIPTION; +import static org.onap.cps.ncmp.api.NcmpResponseStatus.SUBSCRIPTION_NOT_APPLICABLE; +import static org.onap.cps.ncmp.api.NcmpResponseStatus.SUBSCRIPTION_PENDING; +import static org.onap.cps.ncmp.api.NcmpResponseStatus.SUCCESSFULLY_APPLIED_SUBSCRIPTION; +import static org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus.ACCEPTED; +import static org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus.PENDING; +import static org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus.REJECTED; + import io.cloudevents.CloudEvent; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.onap.cps.ncmp.api.NcmpEventResponseCode; +import org.onap.cps.ncmp.api.NcmpResponseStatus; import org.onap.cps.ncmp.api.impl.events.EventsPublisher; import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionPersistence; import org.onap.cps.ncmp.api.impl.subscriptions.SubscriptionStatus; @@ -100,48 +107,39 @@ public class CmSubscriptionNcmpOutEventPublisher { cmSubscriptionStatus.setStatus(SubscriptionStatus.fromString(status)); cmSubscriptionStatus.setDetails(details); return cmSubscriptionStatus; - }).collect(Collectors.toList()); + }).toList(); } - private NcmpEventResponseCode decideOnNcmpEventResponseCodeForSubscription( + private NcmpResponseStatus decideOnNcmpEventResponseCodeForSubscription( final Map<String, Map<String, String>> cmHandleIdToStatusAndDetailsAsMap) { - final boolean isAllTargetsPending = isAllTargetCmHandleStatusMatch(cmHandleIdToStatusAndDetailsAsMap, - SubscriptionStatus.PENDING); - - final boolean isAllTargetsRejected = isAllTargetCmHandleStatusMatch(cmHandleIdToStatusAndDetailsAsMap, - SubscriptionStatus.REJECTED); - - final boolean isAllTargetsAccepted = isAllTargetCmHandleStatusMatch(cmHandleIdToStatusAndDetailsAsMap, - SubscriptionStatus.ACCEPTED); - - if (isAllTargetsAccepted) { - return NcmpEventResponseCode.SUCCESSFULLY_APPLIED_SUBSCRIPTION; - } else if (isAllTargetsRejected) { - return NcmpEventResponseCode.SUBSCRIPTION_NOT_APPLICABLE; - } else if (isAllTargetsPending) { - return NcmpEventResponseCode.SUBSCRIPTION_PENDING; - } else { - return NcmpEventResponseCode.PARTIALLY_APPLIED_SUBSCRIPTION; + if (allTargetsHaveStatus(cmHandleIdToStatusAndDetailsAsMap, ACCEPTED)) { + return SUCCESSFULLY_APPLIED_SUBSCRIPTION; + } + if (allTargetsHaveStatus(cmHandleIdToStatusAndDetailsAsMap, REJECTED)) { + return SUBSCRIPTION_NOT_APPLICABLE; + } + if (allTargetsHaveStatus(cmHandleIdToStatusAndDetailsAsMap, PENDING)) { + return SUBSCRIPTION_PENDING; } + return PARTIALLY_APPLIED_SUBSCRIPTION; } - private boolean isAllTargetCmHandleStatusMatch( - final Map<String, Map<String, String>> cmHandleIdToStatusAndDetailsAsMap, - final SubscriptionStatus subscriptionStatus) { + private boolean allTargetsHaveStatus(final Map<String, Map<String, String>> cmHandleIdToStatusAndDetailsAsMap, + final SubscriptionStatus subscriptionStatus) { return cmHandleIdToStatusAndDetailsAsMap.values().stream() .allMatch(entryset -> entryset.containsValue(subscriptionStatus.toString())); } private CmSubscriptionNcmpOutEvent fromCmSubscriptionEvent( final CmSubscriptionEvent cmSubscriptionEvent, - final NcmpEventResponseCode ncmpEventResponseCode) { + final NcmpResponseStatus ncmpResponseStatus) { final CmSubscriptionNcmpOutEvent cmSubscriptionNcmpOutEvent = cmSubscriptionEventToCmSubscriptionNcmpOutEventMapper.toCmSubscriptionNcmpOutEvent( cmSubscriptionEvent); - cmSubscriptionNcmpOutEvent.getData().setStatusCode(Integer.parseInt(ncmpEventResponseCode.getStatusCode())); - cmSubscriptionNcmpOutEvent.getData().setStatusMessage(ncmpEventResponseCode.getStatusMessage()); + cmSubscriptionNcmpOutEvent.getData().setStatusCode(Integer.parseInt(ncmpResponseStatus.getCode())); + cmSubscriptionNcmpOutEvent.getData().setStatusMessage(ncmpResponseStatus.getMessage()); return cmSubscriptionNcmpOutEvent; } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandler.java index 2ae118872b..fdee28e337 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandler.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandler.java @@ -21,8 +21,8 @@ package org.onap.cps.ncmp.api.impl.events.lcm; import java.util.Map; +import org.onap.cps.ncmp.api.impl.inventory.CmHandleState; import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle; -import org.onap.cps.ncmp.api.inventory.CmHandleState; /** * The implementation of it should handle the persisting of composite state and delegate the request to publish the diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerImpl.java index ce19712c08..02368b8574 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCmHandleStateHandlerImpl.java @@ -20,10 +20,10 @@ package org.onap.cps.ncmp.api.impl.events.lcm; -import static org.onap.cps.ncmp.api.inventory.CmHandleState.ADVISED; -import static org.onap.cps.ncmp.api.inventory.CmHandleState.DELETED; -import static org.onap.cps.ncmp.api.inventory.CmHandleState.LOCKED; -import static org.onap.cps.ncmp.api.inventory.CmHandleState.READY; +import static org.onap.cps.ncmp.api.impl.inventory.CmHandleState.ADVISED; +import static org.onap.cps.ncmp.api.impl.inventory.CmHandleState.DELETED; +import static org.onap.cps.ncmp.api.impl.inventory.CmHandleState.LOCKED; +import static org.onap.cps.ncmp.api.impl.inventory.CmHandleState.READY; import io.micrometer.core.annotation.Timed; import java.util.ArrayList; @@ -36,12 +36,12 @@ import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; import lombok.Setter; import lombok.extern.slf4j.Slf4j; +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.CompositeStateUtils; +import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence; 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.CompositeStateUtils; -import org.onap.cps.ncmp.api.inventory.InventoryPersistence; import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle; import org.springframework.stereotype.Service; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreatorHelper.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreatorHelper.java index d3b45d4a63..19d9ba5c0d 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreatorHelper.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/events/lcm/LcmEventsCreatorHelper.java @@ -23,7 +23,7 @@ package org.onap.cps.ncmp.api.impl.events.lcm; import static org.onap.cps.ncmp.api.impl.events.lcm.LcmEventType.CREATE; import static org.onap.cps.ncmp.api.impl.events.lcm.LcmEventType.DELETE; import static org.onap.cps.ncmp.api.impl.events.lcm.LcmEventType.UPDATE; -import static org.onap.cps.ncmp.api.inventory.CmHandleState.DELETED; +import static org.onap.cps.ncmp.api.impl.inventory.CmHandleState.DELETED; import com.google.common.collect.MapDifference; import com.google.common.collect.Maps; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CmHandleQueries.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CmHandleQueries.java index ff78f00229..a5892afc3e 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CmHandleQueries.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CmHandleQueries.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.inventory; +package org.onap.cps.ncmp.api.impl.inventory; import java.util.Collection; import java.util.List; @@ -53,12 +53,21 @@ public interface CmHandleQueries { List<DataNode> queryCmHandlesByState(CmHandleState cmHandleState); /** + * Method to return data nodes with ancestor representing the cm handles. + * + * @param cpsPath cps path for which the cmHandle is requested + * @return a list of data nodes representing the cm handles. + */ + List<DataNode> queryCmHandleAncestorsByCpsPath(String cpsPath, + FetchDescendantsOption fetchDescendantsOption); + + /** * Method to return data nodes representing the cm handles. * * @param cpsPath cps path for which the cmHandle is requested * @return a list of data nodes representing the cm handles. */ - List<DataNode> queryCmHandleDataNodesByCpsPath(String cpsPath, FetchDescendantsOption fetchDescendantsOption); + List<DataNode> queryNcmpRegistryByCpsPath(String cpsPath, FetchDescendantsOption fetchDescendantsOption); /** * Method to check the state of a cm handle with given id. diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CmHandleQueriesImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CmHandleQueriesImpl.java index f61d6c348a..c4e3fd098d 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CmHandleQueriesImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CmHandleQueriesImpl.java @@ -19,8 +19,11 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.inventory; +package org.onap.cps.ncmp.api.impl.inventory; +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.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS; import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS; @@ -31,7 +34,7 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; -import org.onap.cps.ncmp.api.inventory.enums.PropertyType; +import org.onap.cps.ncmp.api.impl.inventory.enums.PropertyType; import org.onap.cps.spi.CpsDataPersistenceService; import org.onap.cps.spi.FetchDescendantsOption; import org.onap.cps.spi.model.DataNode; @@ -41,8 +44,6 @@ import org.springframework.stereotype.Component; @Component public class CmHandleQueriesImpl implements CmHandleQueries { - private static final String NCMP_DATASPACE_NAME = "NCMP-Admin"; - private static final String NCMP_DMI_REGISTRY_ANCHOR = "ncmp-dmi-registry"; private static final String DESCENDANT_PATH = "//"; private final CpsDataPersistenceService cpsDataPersistenceService; @@ -60,15 +61,21 @@ public class CmHandleQueriesImpl implements CmHandleQueries { @Override public List<DataNode> queryCmHandlesByState(final CmHandleState cmHandleState) { - return queryCmHandleDataNodesByCpsPath("//state[@cm-handle-state=\"" + cmHandleState + "\"]", + return queryCmHandleAncestorsByCpsPath("//state[@cm-handle-state=\"" + cmHandleState + "\"]", INCLUDE_ALL_DESCENDANTS); } @Override - public List<DataNode> queryCmHandleDataNodesByCpsPath(final String cpsPath, - final FetchDescendantsOption fetchDescendantsOption) { + public List<DataNode> queryNcmpRegistryByCpsPath(final String cpsPath, + final FetchDescendantsOption fetchDescendantsOption) { return cpsDataPersistenceService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, - cpsPath + ANCESTOR_CM_HANDLES, fetchDescendantsOption); + cpsPath, fetchDescendantsOption); + } + + @Override + public List<DataNode> queryCmHandleAncestorsByCpsPath(final String cpsPath, + final FetchDescendantsOption fetchDescendantsOption) { + return queryNcmpRegistryByCpsPath(cpsPath + ANCESTOR_CM_HANDLES, fetchDescendantsOption); } @Override @@ -80,7 +87,7 @@ public class CmHandleQueriesImpl implements CmHandleQueries { @Override public List<DataNode> queryCmHandlesByOperationalSyncState(final DataStoreSyncState dataStoreSyncState) { - return queryCmHandleDataNodesByCpsPath("//state/datastores" + "/operational[@sync-state=\"" + return queryCmHandleAncestorsByCpsPath("//state/datastores" + "/operational[@sync-state=\"" + dataStoreSyncState + "\"]", FetchDescendantsOption.OMIT_DESCENDANTS); } @@ -113,7 +120,8 @@ public class CmHandleQueriesImpl implements CmHandleQueries { + publicPropertyQueryPair.getKey() + "\" and @value=\"" + publicPropertyQueryPair.getValue() + "\"]"; - final Collection<DataNode> dataNodes = queryCmHandleDataNodesByCpsPath(cpsPath, OMIT_DESCENDANTS); + final Collection<DataNode> dataNodes = queryCmHandleAncestorsByCpsPath(cpsPath, + OMIT_DESCENDANTS); if (cmHandleIds == null) { cmHandleIds = collectCmHandleIdsFromDataNodes(dataNodes); } else { @@ -128,14 +136,14 @@ public class CmHandleQueriesImpl implements CmHandleQueries { } private List<DataNode> getCmHandlesByDmiPluginIdentifierAndDmiProperty(final String dmiPluginIdentifier, - final String dmiProperty) { + final String dmiProperty) { return cpsDataPersistenceService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, - "/dmi-registry/cm-handles[@" + dmiProperty + "='" + dmiPluginIdentifier + "']", + NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@" + dmiProperty + "='" + dmiPluginIdentifier + "']", OMIT_DESCENDANTS); } private DataNode getCmHandleState(final String cmHandleId) { - final String xpath = "/dmi-registry/cm-handles[@id='" + cmHandleId + "']/state"; + final String xpath = NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='" + cmHandleId + "']/state"; return cpsDataPersistenceService.getDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, xpath, OMIT_DESCENDANTS).iterator().next(); } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CmHandleState.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CmHandleState.java index 7628c81dda..5485ee7e80 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CmHandleState.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CmHandleState.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. @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.inventory; +package org.onap.cps.ncmp.api.impl.inventory; public enum CmHandleState { ADVISED, READY, LOCKED, DELETING, DELETED diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeState.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CompositeState.java index bf448c568f..5b88f560eb 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeState.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CompositeState.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. @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.inventory; +package org.onap.cps.ncmp.api.impl.inventory; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeStateBuilder.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CompositeStateBuilder.java index d6a33302d9..2fbe2b2f78 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeStateBuilder.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CompositeStateBuilder.java @@ -1,7 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2022 Bell Canada - * Modifications Copyright (C) 2022 Nordix Foundation. + * Modifications 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. @@ -19,11 +19,11 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.inventory; +package org.onap.cps.ncmp.api.impl.inventory; -import org.onap.cps.ncmp.api.inventory.CompositeState.DataStores; -import org.onap.cps.ncmp.api.inventory.CompositeState.LockReason; -import org.onap.cps.ncmp.api.inventory.CompositeState.Operational; +import org.onap.cps.ncmp.api.impl.inventory.CompositeState.DataStores; +import org.onap.cps.ncmp.api.impl.inventory.CompositeState.LockReason; +import org.onap.cps.ncmp.api.impl.inventory.CompositeState.Operational; import org.onap.cps.spi.model.DataNode; public class CompositeStateBuilder { diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeStateUtils.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CompositeStateUtils.java index cff1000fe9..99cca8c0b3 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeStateUtils.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/CompositeStateUtils.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. @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.inventory; +package org.onap.cps.ncmp.api.impl.inventory; import java.util.function.Consumer; import lombok.AccessLevel; @@ -100,7 +100,9 @@ public class CompositeStateUtils { compositeState.setLastUpdateTimeNow(); final String oldLockReasonDetails = compositeState.getLockReason().getDetails(); final CompositeState.LockReason lockReason = - CompositeState.LockReason.builder().details(oldLockReasonDetails).build(); + CompositeState.LockReason.builder() + .lockReasonCategory(compositeState.getLockReason().getLockReasonCategory()) + .details(oldLockReasonDetails).build(); compositeState.setLockReason(lockReason); }; } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/DataStoreSyncState.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/DataStoreSyncState.java index 4dbedf5f1c..b92d152bfa 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/DataStoreSyncState.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/DataStoreSyncState.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. @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.inventory; +package org.onap.cps.ncmp.api.impl.inventory; public enum DataStoreSyncState { SYNCHRONIZED, UNSYNCHRONIZED, NONE_REQUESTED 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/impl/inventory/InventoryPersistence.java index cbd30a8fef..09de9a7bf3 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/impl/inventory/InventoryPersistence.java @@ -19,17 +19,17 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.inventory; +package org.onap.cps.ncmp.api.impl.inventory; import java.util.Collection; import java.util.Map; +import org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence; import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle; -import org.onap.cps.spi.FetchDescendantsOption; import org.onap.cps.spi.model.DataNode; import org.onap.cps.spi.model.ModuleDefinition; import org.onap.cps.spi.model.ModuleReference; -public interface InventoryPersistence { +public interface InventoryPersistence extends NcmpPersistence { /** * Get the Cm Handle Composite State from the data node. @@ -101,61 +101,6 @@ public interface InventoryPersistence { void saveCmHandleBatch(Collection<YangModelCmHandle> yangModelCmHandles); /** - * Method to delete a list or a list element. - * - * @param listElementXpath list element xPath - */ - 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 - * @return data node - */ - Collection<DataNode> getDataNode(String xpath); - - /** - * Get data node via xpath. - * - * @param xpath xpath - * @param fetchDescendantsOption fetch descendants option - * @return data node - */ - Collection<DataNode> getDataNode(String xpath, FetchDescendantsOption fetchDescendantsOption); - - /** - * Get collection of data nodes via xpaths. - * - * @param xpaths collection of xpaths - * @return collection of data nodes - */ - Collection<DataNode> getDataNodes(Collection<String> xpaths); - - /** - * Get collection of data nodes via xpaths. - * - * @param xpaths collection of xpaths - * @param fetchDescendantsOption fetch descendants option - * @return collection of data nodes - */ - Collection<DataNode> getDataNodes(Collection<String> xpaths, FetchDescendantsOption fetchDescendantsOption); - - /** * Get data node of given cm handle. * * @param cmHandleId cmHandle ID @@ -178,26 +123,4 @@ public interface InventoryPersistence { * @return Collection of CM handle Ids */ Collection<String> getCmHandleIdsWithGivenModules(Collection<String> moduleNamesForQuery); - - /** - * Replaces list content by removing all existing elements and inserting the given new elements as data nodes. - * - * @param parentNodeXpath parent node xpath - * @param dataNodes datanodes representing the updated data - */ - void replaceListContent(String parentNodeXpath, Collection<DataNode> dataNodes); - - /** - * Deletes data node. - * - * @param dataNodeXpath data node xpath - */ - void deleteDataNode(String dataNodeXpath); - - /** - * Deletes multiple data nodes. - * - * @param dataNodeXpaths data node xpaths - */ - void deleteDataNodes(Collection<String> 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/impl/inventory/InventoryPersistenceImpl.java index 7908e629cb..159d8f345a 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/impl/inventory/InventoryPersistenceImpl.java @@ -20,21 +20,14 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.inventory; +package org.onap.cps.ncmp.api.impl.inventory; -import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME; -import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NO_TIMESTAMP; -import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED; -import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS; - -import io.micrometer.core.annotation.Timed; import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; -import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.onap.cps.api.CpsAdminService; import org.onap.cps.api.CpsDataService; @@ -43,7 +36,6 @@ import org.onap.cps.ncmp.api.impl.utils.YangDataConverter; import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle; import org.onap.cps.spi.FetchDescendantsOption; import org.onap.cps.spi.exceptions.DataValidationException; -import org.onap.cps.spi.exceptions.SchemaSetNotFoundException; import org.onap.cps.spi.model.DataNode; import org.onap.cps.spi.model.ModuleDefinition; import org.onap.cps.spi.model.ModuleReference; @@ -52,31 +44,37 @@ import org.onap.cps.utils.JsonObjectMapper; import org.springframework.stereotype.Component; @Slf4j -@RequiredArgsConstructor @Component -public class InventoryPersistenceImpl implements InventoryPersistence { - - private static final String NCMP_DATASPACE_NAME = "NCMP-Admin"; - - private static final String NCMP_DMI_REGISTRY_ANCHOR = "ncmp-dmi-registry"; - - private static final String NCMP_DMI_REGISTRY_PARENT = "/dmi-registry"; - - private final JsonObjectMapper jsonObjectMapper; - - private final CpsDataService cpsDataService; +public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements InventoryPersistence { private final CpsModuleService cpsModuleService; - private final CpsAdminService cpsAdminService; - private final CpsValidator cpsValidator; + /** + * 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 cpsAdminService cps admin service instance + */ + public InventoryPersistenceImpl(final JsonObjectMapper jsonObjectMapper, final CpsDataService cpsDataService, + final CpsModuleService cpsModuleService, final CpsValidator cpsValidator, + final CpsAdminService cpsAdminService) { + super(jsonObjectMapper, cpsDataService, cpsModuleService, cpsValidator); + this.cpsModuleService = cpsModuleService; + this.cpsAdminService = cpsAdminService; + this.cpsValidator = cpsValidator; + } + + @Override public CompositeState getCmHandleState(final String cmHandleId) { final DataNode stateAsDataNode = cpsDataService.getDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, - createCmHandleXPath(cmHandleId) + "/state", - FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS).iterator().next(); + createCmHandleXPath(cmHandleId) + "/state", FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) + .iterator().next(); cpsValidator.validateNameCharacters(cmHandleId); return new CompositeStateBuilder().fromDataNode(stateAsDataNode).build(); } @@ -85,8 +83,7 @@ public class InventoryPersistenceImpl implements InventoryPersistence { public void saveCmHandleState(final String cmHandleId, final CompositeState compositeState) { final String cmHandleJsonData = createStateJsonData(jsonObjectMapper.asJsonString(compositeState)); cpsDataService.updateDataNodeAndDescendants(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, - createCmHandleXPath(cmHandleId), - cmHandleJsonData, OffsetDateTime.now()); + createCmHandleXPath(cmHandleId), cmHandleJsonData, OffsetDateTime.now()); } @Override @@ -150,60 +147,6 @@ public class InventoryPersistenceImpl implements InventoryPersistence { } @Override - public void deleteListOrListElement(final String listElementXpath) { - cpsDataService.deleteListOrListElement(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, - listElementXpath, NO_TIMESTAMP); - } - - @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) { - return getDataNode(xpath, INCLUDE_ALL_DESCENDANTS); - } - - @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, final FetchDescendantsOption fetchDescendantsOption) { - return cpsDataService.getDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, - xpath, fetchDescendantsOption); - } - - @Override - public Collection<DataNode> getDataNodes(final Collection<String> xpaths) { - return getDataNodes(xpaths, INCLUDE_ALL_DESCENDANTS); - } - - @Override - public Collection<DataNode> getDataNodes(final Collection<String> xpaths, - final FetchDescendantsOption fetchDescendantsOption) { - return cpsDataService.getDataNodesForMultipleXpaths(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, - xpaths, fetchDescendantsOption); - } - - @Override public Collection<DataNode> getCmHandleDataNode(final String cmHandleId) { return this.getDataNode(createCmHandleXPath(cmHandleId)); } @@ -220,24 +163,8 @@ public class InventoryPersistenceImpl implements InventoryPersistence { return cpsAdminService.queryAnchorNames(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, moduleNamesForQuery); } - @Override - public void replaceListContent(final String parentNodeXpath, final Collection<DataNode> dataNodes) { - cpsDataService.replaceListContent(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, - parentNodeXpath, dataNodes, NO_TIMESTAMP); - } - - @Override - public void deleteDataNode(final String dataNodeXpath) { - cpsDataService.deleteDataNode(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, dataNodeXpath, NO_TIMESTAMP); - } - - @Override - public void deleteDataNodes(final Collection<String> dataNodeXpaths) { - cpsDataService.deleteDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, dataNodeXpaths, NO_TIMESTAMP); - } - private static String createCmHandleXPath(final String cmHandleId) { - return "/dmi-registry/cm-handles[@id='" + cmHandleId + "']"; + return NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='" + cmHandleId + "']"; } private static String createStateJsonData(final String state) { diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/LockReasonCategory.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/LockReasonCategory.java index 16ae881935..e2b2c6b4ae 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/LockReasonCategory.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/LockReasonCategory.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. @@ -18,8 +18,11 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.inventory; +package org.onap.cps.ncmp.api.impl.inventory; public enum LockReasonCategory { - LOCKED_MODULE_SYNC_FAILED + MODULE_SYNC_FAILED, + MODULE_UPGRADE, + MODULE_UPGRADE_FAILED, + LOCKED_MISBEHAVING } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/ModelledDmiServiceLeaves.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/ModelledDmiServiceLeaves.java index 0546c388bf..b8a1ba02db 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/ModelledDmiServiceLeaves.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/ModelledDmiServiceLeaves.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. @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.inventory; +package org.onap.cps.ncmp.api.impl.inventory; public enum ModelledDmiServiceLeaves { DMI_SERVICE_NAME("dmi-service-name"), diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/NcmpPersistenceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/NcmpPersistenceImpl.java new file mode 100644 index 0000000000..6a2d6d810b --- /dev/null +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/NcmpPersistenceImpl.java @@ -0,0 +1,120 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 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. + * 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.api.impl.inventory; + +import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED; +import static org.onap.cps.spi.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.CpsDataService; +import org.onap.cps.api.CpsModuleService; +import org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence; +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.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 CpsDataService cpsDataService; + private final CpsModuleService cpsModuleService; + private final CpsValidator cpsValidator; + + @Override + public void deleteListOrListElement(final String listElementXpath) { + cpsDataService.deleteListOrListElement(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, listElementXpath, + NO_TIMESTAMP); + } + + @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) { + return getDataNode(xpath, INCLUDE_ALL_DESCENDANTS); + } + + @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, final FetchDescendantsOption fetchDescendantsOption) { + return cpsDataService.getDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, xpath, + fetchDescendantsOption); + } + + @Override + public Collection<DataNode> getDataNodes(final Collection<String> xpaths) { + return getDataNodes(xpaths, INCLUDE_ALL_DESCENDANTS); + } + + @Override + public Collection<DataNode> getDataNodes(final Collection<String> xpaths, + final FetchDescendantsOption fetchDescendantsOption) { + return cpsDataService.getDataNodesForMultipleXpaths(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, xpaths, + fetchDescendantsOption); + } + + @Override + public void replaceListContent(final String parentNodeXpath, final Collection<DataNode> dataNodes) { + cpsDataService.replaceListContent(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, parentNodeXpath, dataNodes, + NO_TIMESTAMP); + } + + @Override + public void deleteDataNode(final String dataNodeXpath) { + cpsDataService.deleteDataNode(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, dataNodeXpath, NO_TIMESTAMP); + } + + @Override + public void deleteDataNodes(final Collection<String> dataNodeXpaths) { + cpsDataService.deleteDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, dataNodeXpaths, NO_TIMESTAMP); + } + +} diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/enums/PropertyType.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/enums/PropertyType.java index c3c46c35e1..08bfe98e5c 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/enums/PropertyType.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/enums/PropertyType.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. @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.inventory.enums; +package org.onap.cps.ncmp.api.impl.inventory.enums; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/DataSyncWatchdog.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/DataSyncWatchdog.java index 9fa75a0d07..49804adc13 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/DataSyncWatchdog.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/DataSyncWatchdog.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. @@ -18,7 +18,9 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.inventory.sync; +package org.onap.cps.ncmp.api.impl.inventory.sync; + +import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME; import com.hazelcast.map.IMap; import java.time.OffsetDateTime; @@ -28,9 +30,9 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.onap.cps.api.CpsDataService; import org.onap.cps.ncmp.api.impl.config.embeddedcache.SynchronizationCacheConfig; -import org.onap.cps.ncmp.api.inventory.CompositeState; -import org.onap.cps.ncmp.api.inventory.DataStoreSyncState; -import org.onap.cps.ncmp.api.inventory.InventoryPersistence; +import org.onap.cps.ncmp.api.impl.inventory.CompositeState; +import org.onap.cps.ncmp.api.impl.inventory.DataStoreSyncState; +import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; @@ -66,7 +68,7 @@ public class DataSyncWatchdog { if (resourceData == null) { log.debug("Error retrieving resource data for Cm-Handle: {}", cmHandleId); } else { - cpsDataService.saveData("NFP-Operational", cmHandleId, + cpsDataService.saveData(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId, resourceData, OffsetDateTime.now()); setSyncStateToSynchronized().accept(compositeState); inventoryPersistence.saveCmHandleState(cmHandleId, compositeState); diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncService.java new file mode 100644 index 0000000000..8e17ab9166 --- /dev/null +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncService.java @@ -0,0 +1,167 @@ +/* + * ============LICENSE_START======================================================= + * 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. + * 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.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 +@Service +@RequiredArgsConstructor +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 upgradedCmHandle the yang model of cm handle. + */ + 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); + + final Collection<ModuleReference> identifiedNewModuleReferencesFromCmHandle = cpsModuleService + .identifyNewModuleReferences(allModuleReferencesFromCmHandle); + + final Map<String, String> newModuleNameToContentMap; + if (identifiedNewModuleReferencesFromCmHandle.isEmpty()) { + newModuleNameToContentMap = Collections.emptyMap(); + } else { + newModuleNameToContentMap = dmiModelOperations.getNewYangResourcesFromDmi(yangModelCmHandle, + identifiedNewModuleReferencesFromCmHandle); + } + createSchemaSetAndAnchor(yangModelCmHandle, newModuleNameToContentMap, allModuleReferencesFromCmHandle); + } + + private void createSchemaSetAndAnchor(final YangModelCmHandle yangModelCmHandle, + final Map<String, String> newModuleNameToContentMap, + final Collection<ModuleReference> allModuleReferencesFromCmHandle) { + final String schemaSetAndAnchorName = yangModelCmHandle.getId(); + cpsModuleService.createOrUpgradeSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, + schemaSetAndAnchorName, newModuleNameToContentMap, allModuleReferencesFromCmHandle); + cpsAdminService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, schemaSetAndAnchorName, + schemaSetAndAnchorName); + } + + /** + * 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 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; + } + +} diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncTasks.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncTasks.java index 914b626e33..c19dbeb900 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncTasks.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncTasks.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.inventory.sync; +package org.onap.cps.ncmp.api.impl.inventory.sync; import com.hazelcast.map.IMap; import java.util.Collection; @@ -30,12 +30,12 @@ import java.util.concurrent.atomic.AtomicInteger; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.onap.cps.ncmp.api.impl.events.lcm.LcmEventsCmHandleStateHandler; +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.InventoryPersistence; +import org.onap.cps.ncmp.api.impl.inventory.LockReasonCategory; 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.inventory.LockReasonCategory; import org.onap.cps.spi.model.DataNode; import org.springframework.stereotype.Component; @@ -60,7 +60,8 @@ public class ModuleSyncTasks { public CompletableFuture<Void> performModuleSync(final Collection<DataNode> cmHandlesAsDataNodes, final AtomicInteger batchCounter) { try { - final Map<YangModelCmHandle, CmHandleState> cmHandelStatePerCmHandle = new HashMap<>(); + final Map<YangModelCmHandle, CmHandleState> cmHandelStatePerCmHandle + = new HashMap<>(cmHandlesAsDataNodes.size()); for (final DataNode cmHandleAsDataNode : cmHandlesAsDataNodes) { final String cmHandleId = String.valueOf(cmHandleAsDataNode.getLeaves().get("id")); final YangModelCmHandle yangModelCmHandle = @@ -68,16 +69,18 @@ public class ModuleSyncTasks { final CompositeState compositeState = inventoryPersistence.getCmHandleState(cmHandleId); try { moduleSyncService.deleteSchemaSetIfExists(cmHandleId); - moduleSyncService.syncAndCreateSchemaSetAndAnchor(yangModelCmHandle); + moduleSyncService.syncAndCreateOrUpgradeSchemaSetAndAnchor(yangModelCmHandle); + yangModelCmHandle.getCompositeState().setLockReason(null); cmHandelStatePerCmHandle.put(yangModelCmHandle, CmHandleState.READY); } catch (final Exception e) { - log.warn("Processing of {} module sync failed due to reason {}.", cmHandleId, e.getMessage()); + log.warn("Processing of {} module sync failed due to reason {}.", + cmHandleId, e.getMessage()); syncUtils.updateLockReasonDetailsAndAttempts(compositeState, - LockReasonCategory.LOCKED_MODULE_SYNC_FAILED, e.getMessage()); + LockReasonCategory.MODULE_SYNC_FAILED, e.getMessage()); setCmHandleStateLocked(yangModelCmHandle, compositeState.getLockReason()); cmHandelStatePerCmHandle.put(yangModelCmHandle, CmHandleState.LOCKED); } - log.info("{} is now in {} state", cmHandleId, compositeState.getCmHandleState().name()); + log.info("{} is now in {} state", cmHandleId, cmHandelStatePerCmHandle.get(yangModelCmHandle).name()); } lcmEventsCmHandleStateHandler.updateCmHandleStateBatch(cmHandelStatePerCmHandle); } finally { @@ -96,7 +99,7 @@ public class ModuleSyncTasks { final Map<YangModelCmHandle, CmHandleState> cmHandleStatePerCmHandle = new HashMap<>(failedCmHandles.size()); for (final YangModelCmHandle failedCmHandle : failedCmHandles) { final CompositeState compositeState = failedCmHandle.getCompositeState(); - final boolean isReadyForRetry = syncUtils.isReadyForRetry(compositeState); + final boolean isReadyForRetry = syncUtils.needsModuleSyncRetryOrUpgrade(compositeState); log.info("Retry for cmHandleId : {} is {}", failedCmHandle.getId(), isReadyForRetry); if (isReadyForRetry) { final String resetCmHandleId = failedCmHandle.getId(); diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncWatchdog.java index 6ff426d66f..75781eb1b3 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/ModuleSyncWatchdog.java @@ -19,12 +19,13 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.inventory.sync; +package org.onap.cps.ncmp.api.impl.inventory.sync; import com.hazelcast.map.IMap; import java.util.Collection; import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -32,8 +33,8 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.onap.cps.ncmp.api.impl.config.embeddedcache.SynchronizationCacheConfig; +import org.onap.cps.ncmp.api.impl.inventory.sync.executor.AsyncTaskExecutor; import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle; -import org.onap.cps.ncmp.api.inventory.sync.executor.AsyncTaskExecutor; import org.onap.cps.spi.model.DataNode; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; @@ -48,6 +49,7 @@ public class ModuleSyncWatchdog { private final IMap<String, Object> moduleSyncStartedOnCmHandles; private final ModuleSyncTasks moduleSyncTasks; private final AsyncTaskExecutor asyncTaskExecutor; + private final IMap<String, Set<String>> moduleSetTagCache; private static final int MODULE_SYNC_BATCH_SIZE = 100; private static final long PREVENT_CPU_BURN_WAIT_TIME_MILLIS = 10; private static final String VALUE_FOR_HAZELCAST_IN_PROGRESS_MAP = "Started"; @@ -88,7 +90,7 @@ public class ModuleSyncWatchdog { @Scheduled(fixedDelayString = "${ncmp.timers.locked-modules-sync.sleep-time-ms:300000}") public void resetPreviouslyFailedCmHandles() { log.info("Processing module sync retry-watchdog waking up."); - final List<YangModelCmHandle> failedCmHandles = syncUtils.getModuleSyncFailedCmHandles(); + final List<YangModelCmHandle> failedCmHandles = syncUtils.getCmHandlesThatFailedModelSyncOrUpgrade(); log.info("Retrying {} cmHandles", failedCmHandles.size()); moduleSyncTasks.resetFailedCmHandles(failedCmHandles); } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/SyncUtils.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/SyncUtils.java index 53d8c797b8..ab85c2127e 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/SyncUtils.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/SyncUtils.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.inventory.sync; +package org.onap.cps.ncmp.api.impl.inventory.sync; import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_OPERATIONAL; @@ -35,17 +35,16 @@ import java.util.Map; import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; -import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +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.DataStoreSyncState; +import org.onap.cps.ncmp.api.impl.inventory.LockReasonCategory; import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations; 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.CmHandleQueries; -import org.onap.cps.ncmp.api.inventory.CmHandleState; -import org.onap.cps.ncmp.api.inventory.CompositeState; -import org.onap.cps.ncmp.api.inventory.DataStoreSyncState; -import org.onap.cps.ncmp.api.inventory.LockReasonCategory; import org.onap.cps.spi.FetchDescendantsOption; import org.onap.cps.spi.model.DataNode; import org.onap.cps.utils.JsonObjectMapper; @@ -56,12 +55,10 @@ import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor public class SyncUtils { - private final CmHandleQueries cmHandleQueries; + private final CmHandleQueries cmHandleQueries; private final DmiDataOperations dmiDataOperations; - private final JsonObjectMapper jsonObjectMapper; - private static final Pattern retryAttemptPattern = Pattern.compile("^Attempt #(\\d+) failed:"); /** @@ -102,13 +99,14 @@ public class SyncUtils { } /** - * Query data nodes for cm handles with an "LOCKED" cm handle state with reason LOCKED_MODULE_SYNC_FAILED". + * Query data nodes for cm handles with an "LOCKED" cm handle state with reason. * * @return a random LOCKED yang model cm handle, return null if not found */ - public List<YangModelCmHandle> getModuleSyncFailedCmHandles() { - final List<DataNode> lockedCmHandlesAsDataNodeList = cmHandleQueries.queryCmHandleDataNodesByCpsPath( - "//lock-reason[@reason=\"LOCKED_MODULE_SYNC_FAILED\"]", + public List<YangModelCmHandle> getCmHandlesThatFailedModelSyncOrUpgrade() { + final List<DataNode> lockedCmHandlesAsDataNodeList + = cmHandleQueries.queryCmHandleAncestorsByCpsPath( + "//lock-reason[@reason=\"MODULE_SYNC_FAILED\" or @reason=\"MODULE_UPGRADE\"]", FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS); return convertCmHandlesDataNodesToYangModelCmHandles(lockedCmHandlesAsDataNodeList); } @@ -136,28 +134,44 @@ public class SyncUtils { /** - * Check if the retry mechanism should attempt to unlock the cm handle based on the last update time. + * Check if a module sync retry is needed. * * @param compositeState the composite state currently in the locked state * @return if the retry mechanism should be attempted */ - public boolean isReadyForRetry(final CompositeState compositeState) { - int timeInMinutesUntilNextAttempt = 1; - final OffsetDateTime time = - OffsetDateTime.parse(compositeState.getLastUpdateTime(), - DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")); - final Matcher matcher = retryAttemptPattern.matcher(compositeState.getLockReason().getDetails()); - if (matcher.find()) { - timeInMinutesUntilNextAttempt = (int) Math.pow(2, Integer.parseInt(matcher.group(1))); - } else { - log.debug("First Attempt: no current attempts found."); - } - final int timeSinceLastAttempt = (int) Duration.between(time, OffsetDateTime.now()).toMinutes(); - if (timeInMinutesUntilNextAttempt >= timeSinceLastAttempt) { - log.info("Time until next attempt is {} minutes: ", - timeInMinutesUntilNextAttempt - timeSinceLastAttempt); + public boolean needsModuleSyncRetryOrUpgrade(final CompositeState compositeState) { + final OffsetDateTime time = OffsetDateTime.parse(compositeState.getLastUpdateTime(), + DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")); + final CompositeState.LockReason lockReason = compositeState.getLockReason(); + + final boolean failedDuringModuleSync = LockReasonCategory.MODULE_SYNC_FAILED + == lockReason.getLockReasonCategory(); + final boolean moduleUpgrade = LockReasonCategory.MODULE_UPGRADE + == lockReason.getLockReasonCategory(); + + if (failedDuringModuleSync) { + final int timeInMinutesUntilNextAttempt; + final Matcher matcher = retryAttemptPattern.matcher(lockReason.getDetails()); + if (matcher.find()) { + timeInMinutesUntilNextAttempt = (int) Math.pow(2, Integer.parseInt(matcher.group(1))); + } else { + timeInMinutesUntilNextAttempt = 1; + log.info("First Attempt: no current attempts found."); + } + final int timeSinceLastAttempt = (int) Duration.between(time, OffsetDateTime.now()).toMinutes(); + if (timeInMinutesUntilNextAttempt >= timeSinceLastAttempt) { + log.info("Time until next attempt is {} minutes: ", + timeInMinutesUntilNextAttempt - timeSinceLastAttempt); + return false; + } + log.info("Retry due now"); + return true; + } else if (moduleUpgrade) { + log.info("Locked for module upgrade."); + return true; } - return timeSinceLastAttempt > timeInMinutesUntilNextAttempt; + log.info("Locked for other reason"); + return false; } /** @@ -189,6 +203,6 @@ public class SyncUtils { final List<DataNode> cmHandlesAsDataNodeList) { return cmHandlesAsDataNodeList.stream() .map(cmHandle -> YangDataConverter.convertCmHandleToYangModel(cmHandle, - cmHandle.getLeaves().get("id").toString())).collect(Collectors.toList()); + cmHandle.getLeaves().get("id").toString())).toList(); } } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/config/WatchdogSchedulingConfigurer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/config/WatchdogSchedulingConfigurer.java index 196a655ca4..1aaee2708f 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/config/WatchdogSchedulingConfigurer.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/config/WatchdogSchedulingConfigurer.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. @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.inventory.sync.config; +package org.onap.cps.ncmp.api.impl.inventory.sync.config; import java.util.concurrent.ThreadPoolExecutor; import org.springframework.context.annotation.Bean; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/executor/AsyncTaskExecutor.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/executor/AsyncTaskExecutor.java index 3d08185e14..2d5e7a1abc 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/executor/AsyncTaskExecutor.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/inventory/sync/executor/AsyncTaskExecutor.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. @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.cps.ncmp.api.inventory.sync.executor; +package org.onap.cps.ncmp.api.impl.inventory.sync.executor; import static java.util.concurrent.TimeUnit.MILLISECONDS; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/ncmppersistence/NcmpPersistence.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/ncmppersistence/NcmpPersistence.java new file mode 100644 index 0000000000..d72b5d58f1 --- /dev/null +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/ncmppersistence/NcmpPersistence.java @@ -0,0 +1,116 @@ +/* + * ============LICENSE_START======================================================= + * 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. + * 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.api.impl.ncmppersistence; + +import java.time.OffsetDateTime; +import java.util.Collection; +import org.onap.cps.spi.FetchDescendantsOption; +import org.onap.cps.spi.model.DataNode; + +/** + * DmiRegistryConstants class to be strictly used for DMI Related constants only. + */ +public interface NcmpPersistence { + + String NCMP_DATASPACE_NAME = "NCMP-Admin"; + String NCMP_DMI_REGISTRY_ANCHOR = "ncmp-dmi-registry"; + String NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME = "NFP-Operational"; + String NCMP_DMI_REGISTRY_PARENT = "/dmi-registry"; + OffsetDateTime NO_TIMESTAMP = null; + + /** + * Method to delete a list or a list element. + * + * @param listElementXpath list element xPath + */ + 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 + * @return data node + */ + Collection<DataNode> getDataNode(String xpath); + + /** + * Get data node via xpath. + * + * @param xpath xpath + * @param fetchDescendantsOption fetch descendants option + * @return data node + */ + Collection<DataNode> getDataNode(String xpath, FetchDescendantsOption fetchDescendantsOption); + + /** + * Get collection of data nodes via xpaths. + * + * @param xpaths collection of xpaths + * @return collection of data nodes + */ + Collection<DataNode> getDataNodes(Collection<String> xpaths); + + /** + * Get collection of data nodes via xpaths. + * + * @param xpaths collection of xpaths + * @param fetchDescendantsOption fetch descendants option + * @return collection of data nodes + */ + Collection<DataNode> getDataNodes(Collection<String> xpaths, + FetchDescendantsOption fetchDescendantsOption); + + /** + * Replaces list content by removing all existing elements and inserting the given new elements as data nodes. + * + * @param parentNodeXpath parent node xpath + * @param dataNodes datanodes representing the updated data + */ + void replaceListContent(String parentNodeXpath, Collection<DataNode> dataNodes); + + /** + * Deletes data node. + * + * @param dataNodeXpath data node xpath + */ + void deleteDataNode(String dataNodeXpath); + + /** + * Deletes multiple data nodes. + * + * @param dataNodeXpaths data node xpaths + */ + void deleteDataNodes(Collection<String> dataNodeXpaths); +} diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java index ba6f89192d..b8edeccf2e 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java @@ -21,6 +21,8 @@ package org.onap.cps.ncmp.api.impl.operations; +import static org.onap.cps.ncmp.api.NcmpResponseStatus.DMI_SERVICE_NOT_RESPONDING; +import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNABLE_TO_READ_RESOURCE_DATA; import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_RUNNING; import static org.onap.cps.ncmp.api.impl.operations.OperationType.READ; @@ -30,16 +32,16 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; -import org.onap.cps.ncmp.api.NcmpEventResponseCode; +import org.onap.cps.ncmp.api.NcmpResponseStatus; import org.onap.cps.ncmp.api.impl.client.DmiRestClient; import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration; import org.onap.cps.ncmp.api.impl.exception.HttpClientRequestException; import org.onap.cps.ncmp.api.impl.executor.TaskExecutor; +import org.onap.cps.ncmp.api.impl.inventory.CmHandleState; +import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence; import org.onap.cps.ncmp.api.impl.utils.DmiServiceUrlBuilder; import org.onap.cps.ncmp.api.impl.utils.data.operation.ResourceDataOperationRequestUtils; import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle; -import org.onap.cps.ncmp.api.inventory.CmHandleState; -import org.onap.cps.ncmp.api.inventory.InventoryPersistence; import org.onap.cps.ncmp.api.models.DataOperationRequest; import org.onap.cps.spi.exceptions.CpsException; import org.onap.cps.utils.JsonObjectMapper; @@ -230,9 +232,7 @@ public class DmiDataOperations extends DmiOperations { final Map<String, List<DmiDataOperation>> groupsOutPerDmiServiceName) { - groupsOutPerDmiServiceName.entrySet().forEach(groupsOutPerDmiServiceNameEntry -> { - final String dmiServiceName = groupsOutPerDmiServiceNameEntry.getKey(); - final List<DmiDataOperation> dmiDataOperationRequestBodies = groupsOutPerDmiServiceNameEntry.getValue(); + groupsOutPerDmiServiceName.forEach((dmiServiceName, dmiDataOperationRequestBodies) -> { final String dmiDataOperationResourceUrl = getDmiServiceDataOperationRequestUrl(dmiServiceName, topicParamInQuery, requestId); sendDataOperationRequestToDmiService(dmiDataOperationResourceUrl, dmiDataOperationRequestBodies); @@ -261,18 +261,18 @@ public class DmiDataOperations extends DmiOperations { final String topicName = dataOperationResourceUrlParameters.get("topic").get(0); final String requestId = dataOperationResourceUrlParameters.get("requestId").get(0); - final MultiValueMap<DmiDataOperation, Map<NcmpEventResponseCode, List<String>>> + final MultiValueMap<DmiDataOperation, Map<NcmpResponseStatus, List<String>>> cmHandleIdsPerResponseCodesPerOperation = new LinkedMultiValueMap<>(); dmiDataOperationRequestBodies.forEach(dmiDataOperationRequestBody -> { final List<String> cmHandleIds = dmiDataOperationRequestBody.getCmHandles().stream() - .map(CmHandle::getId).collect(Collectors.toList()); + .map(CmHandle::getId).toList(); if (throwable.getCause() instanceof HttpClientRequestException) { cmHandleIdsPerResponseCodesPerOperation.add(dmiDataOperationRequestBody, - Map.of(NcmpEventResponseCode.UNABLE_TO_READ_RESOURCE_DATA, cmHandleIds)); + Map.of(UNABLE_TO_READ_RESOURCE_DATA, cmHandleIds)); } else { cmHandleIdsPerResponseCodesPerOperation.add(dmiDataOperationRequestBody, - Map.of(NcmpEventResponseCode.DMI_SERVICE_NOT_RESPONDING, cmHandleIds)); + Map.of(DMI_SERVICE_NOT_RESPONDING, cmHandleIds)); } }); ResourceDataOperationRequestUtils.publishErrorMessageToClientTopic(topicName, requestId, diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java index 1bbd725646..32b5cb7304 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java @@ -32,9 +32,9 @@ import java.util.List; import java.util.Map; import org.onap.cps.ncmp.api.impl.client.DmiRestClient; import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration; +import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence; import org.onap.cps.ncmp.api.impl.utils.DmiServiceUrlBuilder; import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle; -import org.onap.cps.ncmp.api.inventory.InventoryPersistence; import org.onap.cps.ncmp.api.models.YangResource; import org.onap.cps.spi.model.ModuleReference; import org.onap.cps.utils.JsonObjectMapper; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java index 7e9079ec94..c8d73eac63 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java @@ -24,8 +24,8 @@ package org.onap.cps.ncmp.api.impl.operations; import lombok.RequiredArgsConstructor; import org.onap.cps.ncmp.api.impl.client.DmiRestClient; import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration; +import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence; import org.onap.cps.ncmp.api.impl.utils.DmiServiceUrlBuilder; -import org.onap.cps.ncmp.api.inventory.InventoryPersistence; import org.onap.cps.utils.JsonObjectMapper; import org.springframework.stereotype.Service; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionPersistence.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionPersistence.java index 27d4266566..8092e39510 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionPersistence.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionPersistence.java @@ -21,10 +21,11 @@ package org.onap.cps.ncmp.api.impl.subscriptions; import java.util.Collection; +import org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence; import org.onap.cps.ncmp.api.impl.yangmodels.YangModelSubscriptionEvent; import org.onap.cps.spi.model.DataNode; -public interface SubscriptionPersistence { +public interface SubscriptionPersistence extends NcmpPersistence { /** * Save subscription Event. diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionPersistenceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionPersistenceImpl.java index 83a375b1b8..dd0c20d590 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionPersistenceImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/subscriptions/SubscriptionPersistenceImpl.java @@ -20,42 +20,43 @@ package org.onap.cps.ncmp.api.impl.subscriptions; -import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NO_TIMESTAMP; - -import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; -import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.onap.cps.api.CpsDataService; +import org.onap.cps.api.CpsModuleService; +import org.onap.cps.ncmp.api.impl.inventory.NcmpPersistenceImpl; import org.onap.cps.ncmp.api.impl.utils.DataNodeHelper; import org.onap.cps.ncmp.api.impl.yangmodels.YangModelSubscriptionEvent; import org.onap.cps.spi.FetchDescendantsOption; import org.onap.cps.spi.model.DataNode; +import org.onap.cps.spi.utils.CpsValidator; import org.onap.cps.utils.JsonObjectMapper; import org.springframework.stereotype.Component; @Slf4j -@RequiredArgsConstructor @Component -public class SubscriptionPersistenceImpl implements SubscriptionPersistence { +public class SubscriptionPersistenceImpl extends NcmpPersistenceImpl implements SubscriptionPersistence { - private static final String SUBSCRIPTION_DATASPACE_NAME = "NCMP-Admin"; private static final String SUBSCRIPTION_ANCHOR_NAME = "AVC-Subscriptions"; private static final String SUBSCRIPTION_REGISTRY_PARENT = "/subscription-registry"; - private final JsonObjectMapper jsonObjectMapper; - private final CpsDataService cpsDataService; + + public SubscriptionPersistenceImpl(final JsonObjectMapper jsonObjectMapper, final CpsDataService cpsDataService, + final CpsModuleService cpsModuleService, final CpsValidator cpsValidator) { + super(jsonObjectMapper, cpsDataService, cpsModuleService, cpsValidator); + } + @Override public void saveSubscriptionEvent(final YangModelSubscriptionEvent yangModelSubscriptionEvent) { final String clientId = yangModelSubscriptionEvent.getClientId(); final String subscriptionName = yangModelSubscriptionEvent.getSubscriptionName(); - final Collection<DataNode> dataNodes = cpsDataService.getDataNodes(SUBSCRIPTION_DATASPACE_NAME, + final Collection<DataNode> dataNodes = cpsDataService.getDataNodes(NCMP_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME, SUBSCRIPTION_REGISTRY_PARENT, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS); if (isSubscriptionRegistryEmptyOrNonExist(dataNodes, clientId, subscriptionName)) { @@ -74,8 +75,7 @@ public class SubscriptionPersistenceImpl implements SubscriptionPersistence { final Map<String, Map<String, String>> cmHandleIdToStatusAndDetailsAsMapOriginal = DataNodeHelper.cmHandleIdToStatusAndDetailsAsMapFromDataNode(dataNodes); - final Map<String, Map<String, String>> newTargetCmHandles = - mapDifference(cmHandleIdToStatusAndDetailsAsMapNew, + final Map<String, Map<String, String>> newTargetCmHandles = mapDifference(cmHandleIdToStatusAndDetailsAsMapNew, cmHandleIdToStatusAndDetailsAsMapOriginal); traverseCmHandleList(newTargetCmHandles, clientId, subscriptionName, true); @@ -88,7 +88,7 @@ public class SubscriptionPersistenceImpl implements SubscriptionPersistence { final YangModelSubscriptionEvent yangModelSubscriptionEvent) { return yangModelSubscriptionEvent.getPredicates().getTargetCmHandles() .stream().collect( - HashMap<String, Map<String, String>>::new, + HashMap::new, (result, cmHandle) -> { final String cmHandleId = cmHandle.getCmHandleId(); final SubscriptionStatus status = cmHandle.getStatus(); @@ -130,34 +130,31 @@ public class SubscriptionPersistenceImpl implements SubscriptionPersistence { final boolean isAddListElementOperation) { if (isAddListElementOperation) { log.info("targetCmHandleAsJson to be added into DB {}", targetCmHandleAsJson); - cpsDataService.saveListElements(SUBSCRIPTION_DATASPACE_NAME, - SUBSCRIPTION_ANCHOR_NAME, createCmHandleXpathPredicates(clientId, subscriptionName), - targetCmHandleAsJson, NO_TIMESTAMP); + cpsDataService.saveListElements(NCMP_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME, + createCmHandleXpathPredicates(clientId, subscriptionName), targetCmHandleAsJson, NO_TIMESTAMP); } else { log.info("targetCmHandleAsJson to be updated into DB {}", targetCmHandleAsJson); - cpsDataService.updateNodeLeaves(SUBSCRIPTION_DATASPACE_NAME, - SUBSCRIPTION_ANCHOR_NAME, createCmHandleXpathPredicates(clientId, subscriptionName), - targetCmHandleAsJson, NO_TIMESTAMP); + cpsDataService.updateNodeLeaves(NCMP_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME, + createCmHandleXpathPredicates(clientId, subscriptionName), targetCmHandleAsJson, NO_TIMESTAMP); } } private void saveSubscriptionEventYangModel(final String subscriptionEventJsonData) { log.info("SubscriptionEventJsonData to be saved into DB {}", subscriptionEventJsonData); - cpsDataService.saveListElements(SUBSCRIPTION_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME, + cpsDataService.saveListElements(NCMP_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME, SUBSCRIPTION_REGISTRY_PARENT, subscriptionEventJsonData, NO_TIMESTAMP); } @Override public Collection<DataNode> getDataNodesForSubscriptionEvent() { - return cpsDataService.getDataNodes(SUBSCRIPTION_DATASPACE_NAME, - SUBSCRIPTION_ANCHOR_NAME, SUBSCRIPTION_REGISTRY_PARENT, - FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS); + return cpsDataService.getDataNodes(NCMP_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME, + SUBSCRIPTION_REGISTRY_PARENT, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS); } @Override public Collection<DataNode> getCmHandlesForSubscriptionEvent(final String clientId, final String subscriptionName) { - return cpsDataService.getDataNodesForMultipleXpaths(SUBSCRIPTION_DATASPACE_NAME, - SUBSCRIPTION_ANCHOR_NAME, Arrays.asList(createCmHandleXpath(clientId, subscriptionName)), + return cpsDataService.getDataNodesForMultipleXpaths(NCMP_DATASPACE_NAME, SUBSCRIPTION_ANCHOR_NAME, + List.of(createCmHandleXpath(clientId, subscriptionName)), FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS); } @@ -168,8 +165,8 @@ public class SubscriptionPersistenceImpl implements SubscriptionPersistence { final Map<String, String> statusAndDetailsMap = entry.getValue(); final String status = statusAndDetailsMap.get("status"); final String details = statusAndDetailsMap.get("details"); - return new YangModelSubscriptionEvent.TargetCmHandle(cmHandleId, - SubscriptionStatus.fromString(status), details); + return new YangModelSubscriptionEvent.TargetCmHandle(cmHandleId, SubscriptionStatus.fromString(status), + details); }).collect(Collectors.toList()); } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/dmiavailability/DMiPluginWatchDog.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/dmiavailability/DMiPluginWatchDog.java index dac32aa736..d3b95eacbf 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/dmiavailability/DMiPluginWatchDog.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/dmiavailability/DMiPluginWatchDog.java @@ -46,7 +46,7 @@ public class DMiPluginWatchDog { */ @Scheduled(fixedDelayString = "${ncmp.timers.trust-evel.dmi-availability-watchdog-ms:30000}") public void watchDmiPluginAliveness() { - trustLevelPerDmiPlugin.keySet().forEach((dmiPluginName) -> { + trustLevelPerDmiPlugin.keySet().forEach(dmiPluginName -> { final DmiPluginStatus dmiPluginStatus = dmiRestClient.getDmiPluginStatus(dmiPluginName); log.debug("Trust level for dmi-plugin: {} is {}", dmiPluginName, dmiPluginStatus.toString()); if (DmiPluginStatus.UP.equals(dmiPluginStatus)) { diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/YangDataConverter.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/YangDataConverter.java index 7466308981..b6a04d3677 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/YangDataConverter.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/YangDataConverter.java @@ -30,9 +30,9 @@ import java.util.regex.Pattern; import lombok.AccessLevel; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; +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.yangmodels.YangModelCmHandle; -import org.onap.cps.ncmp.api.inventory.CompositeState; -import org.onap.cps.ncmp.api.inventory.CompositeStateBuilder; import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle; import org.onap.cps.spi.model.DataNode; @@ -86,7 +86,8 @@ public class YangDataConverter { (String) cmHandleDataNode.getLeaves().get("dmi-service-name"), (String) cmHandleDataNode.getLeaves().get("dmi-data-service-name"), (String) cmHandleDataNode.getLeaves().get("dmi-model-service-name"), - ncmpServiceCmHandle + ncmpServiceCmHandle, + (String) cmHandleDataNode.getLeaves().get("module-set-tag") ); } @@ -105,7 +106,12 @@ public class YangDataConverter { return yangModelCmHandles; } - private static String extractCmHandleIdFromXpath(final String xpath) { + /** + * This method extract cm handle id from xpath of data node. + * @param xpath for data node of the cm handle + * @return cm handle Id + */ + public static String extractCmHandleIdFromXpath(final String xpath) { final Matcher matcher = cmHandleIdInXpathPattern.matcher(xpath); matcher.find(); return matcher.group(1); diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/data/operation/DataOperationEventCreator.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/data/operation/DataOperationEventCreator.java index 65cda94787..61da706c59 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/data/operation/DataOperationEventCreator.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/data/operation/DataOperationEventCreator.java @@ -28,7 +28,7 @@ import java.util.Map; import lombok.AccessLevel; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.onap.cps.ncmp.api.NcmpEventResponseCode; +import org.onap.cps.ncmp.api.NcmpResponseStatus; import org.onap.cps.ncmp.api.impl.events.NcmpCloudEventBuilder; import org.onap.cps.ncmp.api.impl.operations.DmiDataOperation; import org.onap.cps.ncmp.events.async1_0_0.Data; @@ -51,7 +51,7 @@ public class DataOperationEventCreator { public static CloudEvent createDataOperationEvent(final String clientTopic, final String requestId, final MultiValueMap<DmiDataOperation, - Map<NcmpEventResponseCode, List<String>>> + Map<NcmpResponseStatus, List<String>>> cmHandleIdsPerResponseCodesPerOperation) { final DataOperationEvent dataOperationEvent = new DataOperationEvent(); final Data data = createPayloadFromDataOperationResponses(cmHandleIdsPerResponseCodesPerOperation); @@ -62,7 +62,7 @@ public class DataOperationEventCreator { } private static Data createPayloadFromDataOperationResponses(final MultiValueMap<DmiDataOperation, - Map<NcmpEventResponseCode, List<String>>> cmHandleIdsPerResponseCodesPerOperation) { + Map<NcmpResponseStatus, List<String>>> cmHandleIdsPerResponseCodesPerOperation) { final Data data = new Data(); final List<org.onap.cps.ncmp.events.async1_0_0.Response> responses = new ArrayList<>(); cmHandleIdsPerResponseCodesPerOperation.forEach((dmiDataOperation, cmHandleIdsPerResponseCodes) -> @@ -75,13 +75,13 @@ public class DataOperationEventCreator { private static List<Response> createResponseFromDataOperationResponses( final DmiDataOperation dmiDataOperation, - final Map<NcmpEventResponseCode, List<String>> cmHandleIdsPerResponseCodeEntries) { + final Map<NcmpResponseStatus, List<String>> cmHandleIdsPerResponseCodeEntries) { final List<org.onap.cps.ncmp.events.async1_0_0.Response> responses = new ArrayList<>(); cmHandleIdsPerResponseCodeEntries.forEach((ncmpEventResponseCode, cmHandleIds) -> { final Response response = new Response(); response.setOperationId(dmiDataOperation.getOperationId()); - response.setStatusCode(ncmpEventResponseCode.getStatusCode()); - response.setStatusMessage(ncmpEventResponseCode.getStatusMessage()); + response.setStatusCode(ncmpEventResponseCode.getCode()); + response.setStatusMessage(ncmpEventResponseCode.getMessage()); response.setIds(cmHandleIds); response.setResourceIdentifier(dmiDataOperation.getResourceIdentifier()); response.setOptions(dmiDataOperation.getOptions()); diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/data/operation/ResourceDataOperationRequestUtils.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/data/operation/ResourceDataOperationRequestUtils.java index c455337ac3..e78f0901fe 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/data/operation/ResourceDataOperationRequestUtils.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/data/operation/ResourceDataOperationRequestUtils.java @@ -20,6 +20,9 @@ package org.onap.cps.ncmp.api.impl.utils.data.operation; +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 io.cloudevents.CloudEvent; import java.util.ArrayList; import java.util.Collection; @@ -32,14 +35,14 @@ import java.util.stream.Collectors; import lombok.AccessLevel; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.onap.cps.ncmp.api.NcmpEventResponseCode; +import org.onap.cps.ncmp.api.NcmpResponseStatus; import org.onap.cps.ncmp.api.impl.events.EventsPublisher; +import org.onap.cps.ncmp.api.impl.inventory.CmHandleState; import org.onap.cps.ncmp.api.impl.operations.CmHandle; import org.onap.cps.ncmp.api.impl.operations.DmiDataOperation; import org.onap.cps.ncmp.api.impl.utils.DmiServiceNameOrganizer; import org.onap.cps.ncmp.api.impl.utils.context.CpsApplicationContext; import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle; -import org.onap.cps.ncmp.api.inventory.CmHandleState; import org.onap.cps.ncmp.api.models.DataOperationDefinition; import org.onap.cps.ncmp.api.models.DataOperationRequest; import org.springframework.scheduling.annotation.Async; @@ -68,7 +71,7 @@ public class ResourceDataOperationRequestUtils { final Collection<YangModelCmHandle> yangModelCmHandles) { final Map<String, List<DmiDataOperation>> dmiDataOperationsOutPerDmiServiceName = new HashMap<>(); - final MultiValueMap<DmiDataOperation, Map<NcmpEventResponseCode, + final MultiValueMap<DmiDataOperation, Map<NcmpResponseStatus, List<String>>> cmHandleIdsPerResponseCodesPerOperation = new LinkedMultiValueMap<>(); final Set<String> nonReadyCmHandleIdsLookup = filterAndGetNonReadyCmHandleIds(yangModelCmHandles); @@ -102,10 +105,10 @@ public class ResourceDataOperationRequestUtils { } populateCmHandleIdsPerOperationIdPerResponseCode(cmHandleIdsPerResponseCodesPerOperation, DmiDataOperation.buildDmiDataOperationRequestBodyWithoutCmHandles(dataOperationDefinitionIn), - NcmpEventResponseCode.CM_HANDLES_NOT_FOUND, nonExistingCmHandleIds); + CM_HANDLES_NOT_FOUND, nonExistingCmHandleIds); populateCmHandleIdsPerOperationIdPerResponseCode(cmHandleIdsPerResponseCodesPerOperation, DmiDataOperation.buildDmiDataOperationRequestBodyWithoutCmHandles(dataOperationDefinitionIn), - NcmpEventResponseCode.CM_HANDLES_NOT_READY, nonReadyCmHandleIds); + CM_HANDLES_NOT_READY, nonReadyCmHandleIds); } if (!cmHandleIdsPerResponseCodesPerOperation.isEmpty()) { publishErrorMessageToClientTopic(topicParamInQuery, requestId, cmHandleIdsPerResponseCodesPerOperation); @@ -124,7 +127,7 @@ public class ResourceDataOperationRequestUtils { public static void publishErrorMessageToClientTopic(final String clientTopic, final String requestId, final MultiValueMap<DmiDataOperation, - Map<NcmpEventResponseCode, List<String>>> + Map<NcmpResponseStatus, List<String>>> cmHandleIdsPerResponseCodesPerOperation) { final CloudEvent dataOperationCloudEvent = DataOperationEventCreator.createDataOperationEvent(clientTopic, requestId, cmHandleIdsPerResponseCodesPerOperation); @@ -175,13 +178,13 @@ public class ResourceDataOperationRequestUtils { } private static void populateCmHandleIdsPerOperationIdPerResponseCode(final MultiValueMap<DmiDataOperation, - Map<NcmpEventResponseCode, List<String>>> cmHandleIdsPerResponseCodesPerOperation, + Map<NcmpResponseStatus, List<String>>> cmHandleIdsPerResponseCodesPerOperation, final DmiDataOperation dmiDataOperation, - final NcmpEventResponseCode - ncmpEventResponseCode, + final NcmpResponseStatus + ncmpResponseStatus, final List<String> cmHandleIds) { if (!cmHandleIds.isEmpty()) { - cmHandleIdsPerResponseCodesPerOperation.add(dmiDataOperation, Map.of(ncmpEventResponseCode, cmHandleIds)); + cmHandleIdsPerResponseCodesPerOperation.add(dmiDataOperation, Map.of(ncmpResponseStatus, cmHandleIds)); } } } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java index a6f953aa86..d148f371b5 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java @@ -34,8 +34,8 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.onap.cps.ncmp.api.impl.inventory.CompositeState; import org.onap.cps.ncmp.api.impl.operations.RequiredDmiService; -import org.onap.cps.ncmp.api.inventory.CompositeState; import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle; /** @@ -64,6 +64,9 @@ public class YangModelCmHandle { @JsonProperty("dmi-model-service-name") private String dmiModelServiceName; + @JsonProperty("module-set-tag") + private String moduleSetTag; + @JsonProperty("additional-properties") private List<Property> dmiProperties; @@ -102,12 +105,14 @@ public class YangModelCmHandle { public static YangModelCmHandle toYangModelCmHandle(final String dmiServiceName, final String dmiDataServiceName, final String dmiModelServiceName, - final NcmpServiceCmHandle ncmpServiceCmHandle) { + final NcmpServiceCmHandle ncmpServiceCmHandle, + final String moduleSetTag) { final YangModelCmHandle yangModelCmHandle = new YangModelCmHandle(); yangModelCmHandle.setId(ncmpServiceCmHandle.getCmHandleId()); yangModelCmHandle.setDmiServiceName(dmiServiceName); yangModelCmHandle.setDmiDataServiceName(dmiDataServiceName); yangModelCmHandle.setDmiModelServiceName(dmiModelServiceName); + yangModelCmHandle.setModuleSetTag(moduleSetTag); yangModelCmHandle.setDmiProperties(asYangModelCmHandleProperties(ncmpServiceCmHandle.getDmiProperties())); yangModelCmHandle.setPublicProperties(asYangModelCmHandleProperties( ncmpServiceCmHandle.getPublicProperties())); diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncService.java deleted file mode 100644 index 7efce1ad52..0000000000 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncService.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2022 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.api.inventory.sync; - -import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME; - -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.onap.cps.api.CpsAdminService; -import org.onap.cps.api.CpsModuleService; -import org.onap.cps.ncmp.api.impl.operations.DmiModelOperations; -import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle; -import org.onap.cps.spi.CascadeDeleteAllowed; -import org.onap.cps.spi.exceptions.SchemaSetNotFoundException; -import org.onap.cps.spi.model.ModuleReference; -import org.springframework.stereotype.Service; - -@Slf4j -@Service -@RequiredArgsConstructor -public class ModuleSyncService { - - private final DmiModelOperations dmiModelOperations; - private final CpsModuleService cpsModuleService; - - private final CpsAdminService cpsAdminService; - - /** - * This method registers a cm handle and initiates modules sync. - * - * @param yangModelCmHandle the yang model of cm handle. - */ - public void syncAndCreateSchemaSetAndAnchor(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 = Collections.emptyMap(); - } else { - newModuleNameToContentMap = dmiModelOperations.getNewYangResourcesFromDmi(yangModelCmHandle, - identifiedNewModuleReferencesFromCmHandle); - } - createSchemaSetAndAnchor(yangModelCmHandle, newModuleNameToContentMap, allModuleReferencesFromCmHandle); - } - - private void createSchemaSetAndAnchor(final YangModelCmHandle yangModelCmHandle, - final Map<String, String> newModuleNameToContentMap, - final Collection<ModuleReference> allModuleReferencesFromCmHandle) { - final String schemaSetAndAnchorName = yangModelCmHandle.getId(); - cpsModuleService.createSchemaSetFromModules(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, schemaSetAndAnchorName, - newModuleNameToContentMap, allModuleReferencesFromCmHandle); - cpsAdminService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, schemaSetAndAnchorName, - schemaSetAndAnchorName); - } - - /** - * 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); - } - } - -} diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmHandleRegistrationResponse.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmHandleRegistrationResponse.java index d5b27b61f6..e007491ce0 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmHandleRegistrationResponse.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/CmHandleRegistrationResponse.java @@ -1,7 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2022 Bell Canada - * Modifications Copyright (C) 2022 Nordix Foundation + * Modifications 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. @@ -21,16 +21,16 @@ package org.onap.cps.ncmp.api.models; +import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNKNOWN_ERROR; + import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; import lombok.Builder; import lombok.Data; -import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.onap.cps.ncmp.api.NcmpResponseStatus; +import org.onap.cps.ncmp.api.impl.utils.YangDataConverter; @Data @Builder @@ -39,11 +39,9 @@ public class CmHandleRegistrationResponse { private final String cmHandle; private final Status status; - private RegistrationError registrationError; + private NcmpResponseStatus ncmpResponseStatus; private String errorText; - private static final Pattern cmHandleIdInXpathPattern = Pattern.compile("\\[@id='(.*?)']"); - /** * Creates a failure response based on exception. * @@ -56,7 +54,7 @@ public class CmHandleRegistrationResponse { return CmHandleRegistrationResponse.builder() .cmHandle(cmHandleId) .status(Status.FAILURE) - .registrationError(RegistrationError.UNKNOWN_ERROR) + .ncmpResponseStatus(UNKNOWN_ERROR) .errorText(exception.getMessage()).build(); } @@ -64,15 +62,15 @@ public class CmHandleRegistrationResponse { * Creates a failure response based on registration error. * * @param cmHandleId cmHandleId - * @param registrationError registrationError + * @param ncmpResponseStatus registration error code and status * @return CmHandleRegistrationResponse */ public static CmHandleRegistrationResponse createFailureResponse(final String cmHandleId, - final RegistrationError registrationError) { + final NcmpResponseStatus ncmpResponseStatus) { return CmHandleRegistrationResponse.builder().cmHandle(cmHandleId) .status(Status.FAILURE) - .registrationError(registrationError) - .errorText(registrationError.errorText) + .ncmpResponseStatus(ncmpResponseStatus) + .errorText(ncmpResponseStatus.getMessage()) .build(); } @@ -80,18 +78,18 @@ public class CmHandleRegistrationResponse { * Creates a failure response based on registration error. * * @param failedXpaths list of failed Xpaths - * @param registrationError enum describing the type of registration error + * @param ncmpResponseStatus enum describing the type of registration error * @return CmHandleRegistrationResponse */ public static List<CmHandleRegistrationResponse> createFailureResponses(final Collection<String> failedXpaths, - final RegistrationError registrationError) { + final NcmpResponseStatus ncmpResponseStatus) { final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses = new ArrayList<>(failedXpaths.size()); for (final String xpath : failedXpaths) { - final Matcher matcher = cmHandleIdInXpathPattern.matcher(xpath); - if (matcher.find()) { + try { + final String cmHandleId = YangDataConverter.extractCmHandleIdFromXpath(xpath); cmHandleRegistrationResponses.add( - CmHandleRegistrationResponse.createFailureResponse(matcher.group(1), registrationError)); - } else { + CmHandleRegistrationResponse.createFailureResponse(cmHandleId, ncmpResponseStatus)); + } catch (IllegalArgumentException | IllegalStateException e) { log.warn("Unexpected xpath {}", xpath); } } @@ -109,7 +107,7 @@ public class CmHandleRegistrationResponse { final Exception exception) { return cmHandleIds.stream() .map(cmHandleId -> CmHandleRegistrationResponse.createFailureResponse(cmHandleId, exception)) - .collect(Collectors.toList()); + .toList(); } public static CmHandleRegistrationResponse createSuccessResponse(final String cmHandle) { @@ -118,23 +116,10 @@ public class CmHandleRegistrationResponse { } public static List<CmHandleRegistrationResponse> createSuccessResponses(final List<String> cmHandleIds) { - return cmHandleIds.stream().map(CmHandleRegistrationResponse::createSuccessResponse) - .collect(Collectors.toList()); + return cmHandleIds.stream().map(CmHandleRegistrationResponse::createSuccessResponse).toList(); } public enum Status { SUCCESS, FAILURE; } - - @RequiredArgsConstructor - public enum RegistrationError { - UNKNOWN_ERROR("00", "Unknown error"), - CM_HANDLE_ALREADY_EXIST("01", "cm-handle already exists"), - CM_HANDLE_DOES_NOT_EXIST("02", "cm-handle does not exist"), - CM_HANDLE_INVALID_ID("03", "cm-handle has an invalid character(s) in id"); - - public final String errorCode; - public final String errorText; - - } } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DmiPluginRegistration.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DmiPluginRegistration.java index d1360c3256..4615af61c1 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DmiPluginRegistration.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DmiPluginRegistration.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 Nordix Foundation + * Copyright (C) 2021-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. @@ -50,6 +50,8 @@ public class DmiPluginRegistration { private List<String> removedCmHandles = Collections.emptyList(); + private UpgradedCmHandles upgradedCmHandles; + /** * Validates plugin service names. * @throws NcmpException if validation fails. @@ -80,7 +82,7 @@ public class DmiPluginRegistration { } } - private static boolean isNullEmptyOrBlank(final String serviceName) { + public static boolean isNullEmptyOrBlank(final String serviceName) { return Strings.isNullOrEmpty(serviceName) || serviceName.isBlank(); } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DmiPluginRegistrationResponse.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DmiPluginRegistrationResponse.java index 8a3d26414a..ee034176e3 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DmiPluginRegistrationResponse.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/DmiPluginRegistrationResponse.java @@ -1,6 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2022 Bell Canada + * Modifications Copyright (C) 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. @@ -31,4 +32,5 @@ public class DmiPluginRegistrationResponse { private List<CmHandleRegistrationResponse> createdCmHandles = Collections.emptyList(); private List<CmHandleRegistrationResponse> updatedCmHandles = Collections.emptyList(); private List<CmHandleRegistrationResponse> removedCmHandles = Collections.emptyList(); + private List<CmHandleRegistrationResponse> upgradedCmHandles = Collections.emptyList(); }
\ No newline at end of file diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java index ae40d330ba..0b50346f81 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2021-2022 Nordix Foundation + * Copyright (C) 2021-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. @@ -28,7 +28,7 @@ import java.util.Map; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import org.onap.cps.ncmp.api.inventory.CompositeState; +import org.onap.cps.ncmp.api.impl.inventory.CompositeState; import org.springframework.validation.annotation.Validated; /** @@ -52,6 +52,9 @@ public class NcmpServiceCmHandle { @JsonSetter(nulls = Nulls.AS_EMPTY) private CompositeState compositeState; + @JsonSetter(nulls = Nulls.AS_EMPTY) + private String moduleSetTag; + /** * NcmpServiceCmHandle copy constructor. * @@ -63,5 +66,6 @@ public class NcmpServiceCmHandle { this.publicProperties = new LinkedHashMap<>(ncmpServiceCmHandle.getPublicProperties()); this.compositeState = ncmpServiceCmHandle.getCompositeState() != null ? new CompositeState( ncmpServiceCmHandle.getCompositeState()) : null; + this.moduleSetTag = ncmpServiceCmHandle.getModuleSetTag(); } } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/UpgradedCmHandles.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/UpgradedCmHandles.java new file mode 100644 index 0000000000..61cd99ac8f --- /dev/null +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/UpgradedCmHandles.java @@ -0,0 +1,36 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 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. + * 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.api.models; + +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.Collections; +import java.util.List; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@JsonInclude(JsonInclude.Include.NON_EMPTY) +public class UpgradedCmHandles { + private List<String> cmHandles = Collections.emptyList(); + private String moduleSetTag; +} + 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 5316d666d5..b805cdcd84 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 @@ -20,6 +20,9 @@ package org.onap.cps.ncmp.init; +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 lombok.extern.slf4j.Slf4j; import org.onap.cps.api.CpsAdminService; import org.onap.cps.api.CpsDataService; @@ -32,8 +35,6 @@ public class InventoryModelLoader extends AbstractModelLoader { private static final String NEW_MODEL_FILE_NAME = "dmi-registry@2023-08-23.yang"; private static final String NEW_SCHEMA_SET_NAME = "dmi-registry-2023-08-23"; - private static final String DATASPACE_NAME = "NCMP-Admin"; - private static final String ANCHOR_NAME = "ncmp-dmi-registry"; public InventoryModelLoader(final CpsAdminService cpsAdminService, final CpsModuleService cpsModuleService, @@ -43,20 +44,20 @@ public class InventoryModelLoader extends AbstractModelLoader { @Override public void onboardOrUpgradeModel() { - waitUntilDataspaceIsAvailable(DATASPACE_NAME); + waitUntilDataspaceIsAvailable(NCMP_DATASPACE_NAME); updateInventoryModel(); log.info("Inventory Model updated successfully"); } private void updateInventoryModel() { - createSchemaSet(DATASPACE_NAME, NEW_SCHEMA_SET_NAME, NEW_MODEL_FILE_NAME); - updateAnchorSchemaSet(DATASPACE_NAME, ANCHOR_NAME, NEW_SCHEMA_SET_NAME); + createSchemaSet(NCMP_DATASPACE_NAME, NEW_SCHEMA_SET_NAME, NEW_MODEL_FILE_NAME); + updateAnchorSchemaSet(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, NEW_SCHEMA_SET_NAME); deleteOldButNotThePreviousSchemaSets(); } private void deleteOldButNotThePreviousSchemaSets() { //No schema sets passed in yet, but wil be required for future updates - deleteUnusedSchemaSets(DATASPACE_NAME); + deleteUnusedSchemaSets(NCMP_DATASPACE_NAME); } } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/SubscriptionModelLoader.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/SubscriptionModelLoader.java index 891244c7ca..4d1a91ca99 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/SubscriptionModelLoader.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/init/SubscriptionModelLoader.java @@ -20,6 +20,8 @@ package org.onap.cps.ncmp.init; +import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DATASPACE_NAME; + import lombok.extern.slf4j.Slf4j; import org.onap.cps.api.CpsAdminService; import org.onap.cps.api.CpsDataService; @@ -32,7 +34,6 @@ import org.springframework.stereotype.Service; public class SubscriptionModelLoader extends AbstractModelLoader { private static final String MODEL_FILENAME = "subscription.yang"; - private static final String DATASPACE_NAME = "NCMP-Admin"; private static final String ANCHOR_NAME = "AVC-Subscriptions"; private static final String SCHEMASET_NAME = "subscriptions"; private static final String REGISTRY_DATANODE_NAME = "subscription-registry"; @@ -49,7 +50,7 @@ public class SubscriptionModelLoader extends AbstractModelLoader { @Override public void onboardOrUpgradeModel() { if (subscriptionModelLoaderEnabled) { - waitUntilDataspaceIsAvailable(DATASPACE_NAME); + waitUntilDataspaceIsAvailable(NCMP_DATASPACE_NAME); onboardSubscriptionModel(); log.info("Subscription Model onboarded successfully"); } else { @@ -58,9 +59,9 @@ public class SubscriptionModelLoader extends AbstractModelLoader { } private void onboardSubscriptionModel() { - createSchemaSet(DATASPACE_NAME, SCHEMASET_NAME, MODEL_FILENAME); - createAnchor(DATASPACE_NAME, SCHEMASET_NAME, ANCHOR_NAME); - createTopLevelDataNode(DATASPACE_NAME, ANCHOR_NAME, REGISTRY_DATANODE_NAME); + createSchemaSet(NCMP_DATASPACE_NAME, SCHEMASET_NAME, MODEL_FILENAME); + createAnchor(NCMP_DATASPACE_NAME, SCHEMASET_NAME, ANCHOR_NAME); + createTopLevelDataNode(NCMP_DATASPACE_NAME, ANCHOR_NAME, REGISTRY_DATANODE_NAME); } } |