diff options
11 files changed, 221 insertions, 205 deletions
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NcmpResponseStatus.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NcmpResponseStatus.java index b9c834c559..462679e74f 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NcmpResponseStatus.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/NcmpResponseStatus.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2023 Nordix Foundation + * Copyright (C) 2023-2024 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,8 @@ public enum NcmpResponseStatus { 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"); + CM_HANDLE_INVALID_ID("110", "cm-handle has an invalid character(s) in id"), + ALTERNATE_ID_ALREADY_ASSOCIATED("111", "alternate id already associated"); private final String code; private final String message; 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 1f2748b4af..08afde49a1 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,6 +24,7 @@ package org.onap.cps.ncmp.api.impl; +import static org.onap.cps.ncmp.api.NcmpResponseStatus.ALTERNATE_ID_ALREADY_ASSOCIATED; 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; @@ -306,45 +307,17 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService return inventoryPersistence.getYangModelCmHandle(cmHandleId).getCompositeState(); } - /** - * THis method registers a cm handle and initiates modules sync. - * - * @param dmiPluginRegistration dmi plugin registration information. - * @return cm-handle registration response for create cm-handle requests. - */ - public List<CmHandleRegistrationResponse> parseAndProcessCreatedCmHandlesInRegistration( - final DmiPluginRegistration dmiPluginRegistration, final Collection<String> acceptedCmHandleIds) { - final List<NcmpServiceCmHandle> cmHandlesToBeCreated = dmiPluginRegistration.getCreatedCmHandles(); - final Map<String, TrustLevel> initialTrustLevelPerCmHandleId = new HashMap<>(cmHandlesToBeCreated.size()); - final List<YangModelCmHandle> yangModelCmHandles = new ArrayList<>(cmHandlesToBeCreated.size()); - cmHandlesToBeCreated - .forEach(cmHandle -> { - if (acceptedCmHandleIds.contains(cmHandle.getCmHandleId())) { - final YangModelCmHandle yangModelCmHandle = YangModelCmHandle.toYangModelCmHandle( - dmiPluginRegistration.getDmiPlugin(), - dmiPluginRegistration.getDmiDataPlugin(), - dmiPluginRegistration.getDmiModelPlugin(), - cmHandle, - cmHandle.getModuleSetTag(), - cmHandle.getAlternateId()); - yangModelCmHandles.add(yangModelCmHandle); - initialTrustLevelPerCmHandleId.put(cmHandle.getCmHandleId(), - cmHandle.getRegistrationTrustLevel()); - } - }); - return registerNewCmHandles(yangModelCmHandles, initialTrustLevelPerCmHandleId); - } - - protected List<CmHandleRegistrationResponse> parseAndProcessDeletedCmHandlesInRegistration( - final List<String> tobeRemovedCmHandles) { + protected void processRemovedCmHandles(final DmiPluginRegistration dmiPluginRegistration, + final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) { + final List<String> tobeRemovedCmHandleIds = dmiPluginRegistration.getRemovedCmHandles(); final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses = - new ArrayList<>(tobeRemovedCmHandles.size()); + new ArrayList<>(tobeRemovedCmHandleIds.size()); final Collection<YangModelCmHandle> yangModelCmHandles = - inventoryPersistence.getYangModelCmHandles(tobeRemovedCmHandles); + inventoryPersistence.getYangModelCmHandles(tobeRemovedCmHandleIds); updateCmHandleStateBatch(yangModelCmHandles, CmHandleState.DELETING); final Set<String> notDeletedCmHandles = new HashSet<>(); - for (final List<String> tobeRemovedCmHandleBatch : Lists.partition(tobeRemovedCmHandles, DELETE_BATCH_SIZE)) { + for (final List<String> tobeRemovedCmHandleBatch : Lists.partition(tobeRemovedCmHandleIds, DELETE_BATCH_SIZE)) { try { batchDeleteCmHandlesFromDbAndModuleSyncMap(tobeRemovedCmHandleBatch); tobeRemovedCmHandleBatch.forEach(cmHandleId -> @@ -362,60 +335,58 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService } } } - yangModelCmHandles.removeIf(yangModelCmHandle -> notDeletedCmHandles.contains(yangModelCmHandle.getId())); updateCmHandleStateBatch(yangModelCmHandles, CmHandleState.DELETED); - - return cmHandleRegistrationResponses; + dmiPluginRegistrationResponse.setRemovedCmHandles(cmHandleRegistrationResponses); } - private void processRemovedCmHandles(final DmiPluginRegistration dmiPluginRegistration, + protected void processCreatedCmHandles(final DmiPluginRegistration dmiPluginRegistration, final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) { - if (!dmiPluginRegistration.getRemovedCmHandles().isEmpty()) { - dmiPluginRegistrationResponse.setRemovedCmHandles( - parseAndProcessDeletedCmHandlesInRegistration(dmiPluginRegistration.getRemovedCmHandles())); - } - } + final List<NcmpServiceCmHandle> ncmpServiceCmHandles = dmiPluginRegistration.getCreatedCmHandles(); + final List<CmHandleRegistrationResponse> failedCmHandleRegistrationResponses = new ArrayList<>(); - private void processCreatedCmHandles(final DmiPluginRegistration dmiPluginRegistration, - final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) { - final Collection<String> acceptedCmHandleIds = alternateIdChecker - .getIdsOfCmHandlesWithAcceptableAlternateId(dmiPluginRegistration.getCreatedCmHandles()); - if (!acceptedCmHandleIds.isEmpty()) { - dmiPluginRegistrationResponse.setCreatedCmHandles( - parseAndProcessCreatedCmHandlesInRegistration(dmiPluginRegistration, acceptedCmHandleIds)); - } - } + try { + final Collection<String> rejectedCmHandleIds + = checkAlternateIds(ncmpServiceCmHandles, failedCmHandleRegistrationResponses); - private void processUpdatedCmHandles(final DmiPluginRegistration dmiPluginRegistration, - final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) { - if (!dmiPluginRegistration.getUpdatedCmHandles().isEmpty()) { - dmiPluginRegistrationResponse.setUpdatedCmHandles( - networkCmProxyDataServicePropertyHandler - .updateCmHandleProperties(dmiPluginRegistration.getUpdatedCmHandles())); + final Collection<String> succeededCmHandleIds = persistCmHandlesWithState(dmiPluginRegistration, + dmiPluginRegistrationResponse, ncmpServiceCmHandles, rejectedCmHandleIds); + + processTrustLevels(ncmpServiceCmHandles, succeededCmHandleIds); + + } catch (final AlreadyDefinedException alreadyDefinedException) { + failedCmHandleRegistrationResponses.addAll(CmHandleRegistrationResponse.createFailureResponsesFromXpaths( + alreadyDefinedException.getAlreadyDefinedObjectNames(), CM_HANDLE_ALREADY_EXIST)); + } catch (final Exception exception) { + final Collection<String> cmHandleIds = + ncmpServiceCmHandles.stream().map(NcmpServiceCmHandle::getCmHandleId).collect(Collectors.toList()); + failedCmHandleRegistrationResponses.addAll(CmHandleRegistrationResponse + .createFailureResponses(cmHandleIds, exception)); } + final List<CmHandleRegistrationResponse> mergedCmHandleRegistrationResponses + = new ArrayList<>(failedCmHandleRegistrationResponses); + mergedCmHandleRegistrationResponses.addAll(dmiPluginRegistrationResponse.getCreatedCmHandles()); + + dmiPluginRegistrationResponse.setCreatedCmHandles(mergedCmHandleRegistrationResponses); } - private void processUpgradedCmHandles(final DmiPluginRegistration dmiPluginRegistration, - final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) { - if (dmiPluginRegistration.getUpgradedCmHandles() != null - && !dmiPluginRegistration.getUpgradedCmHandles().getCmHandles().isEmpty()) { - dmiPluginRegistrationResponse.setUpgradedCmHandles( - parseAndProcessUpgradedCmHandlesInRegistration(dmiPluginRegistration)); - } + protected void processUpdatedCmHandles(final DmiPluginRegistration dmiPluginRegistration, + final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) { + dmiPluginRegistrationResponse.setUpdatedCmHandles(networkCmProxyDataServicePropertyHandler + .updateCmHandleProperties(dmiPluginRegistration.getUpdatedCmHandles())); } + protected void processUpgradedCmHandles( + final DmiPluginRegistration dmiPluginRegistration, + final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) { - protected List<CmHandleRegistrationResponse> parseAndProcessUpgradedCmHandlesInRegistration( - final DmiPluginRegistration dmiPluginRegistration) { - - final List<String> upgradedCmHandleIds = dmiPluginRegistration.getUpgradedCmHandles().getCmHandles(); + final List<String> cmHandleIds = dmiPluginRegistration.getUpgradedCmHandles().getCmHandles(); final String upgradedModuleSetTag = dmiPluginRegistration.getUpgradedCmHandles().getModuleSetTag(); final Map<YangModelCmHandle, CmHandleState> acceptedCmHandleStatePerCmHandle - = new HashMap<>(upgradedCmHandleIds.size()); - final List<CmHandleRegistrationResponse> cmHandleUpgradeResponses = new ArrayList<>(upgradedCmHandleIds.size()); + = new HashMap<>(cmHandleIds.size()); + final List<CmHandleRegistrationResponse> cmHandleUpgradeResponses = new ArrayList<>(cmHandleIds.size()); - for (final String cmHandleId : upgradedCmHandleIds) { + for (final String cmHandleId : cmHandleIds) { try { final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle(cmHandleId); if (yangModelCmHandle.getCompositeState().getCmHandleState() == CmHandleState.READY) { @@ -442,7 +413,61 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService } } cmHandleUpgradeResponses.addAll(upgradeCmHandles(acceptedCmHandleStatePerCmHandle)); - return cmHandleUpgradeResponses; + dmiPluginRegistrationResponse.setUpgradedCmHandles(cmHandleUpgradeResponses); + } + + private Collection<String> checkAlternateIds( + final List<NcmpServiceCmHandle> cmHandlesToBeCreated, + final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses) { + final Collection<String> rejectedCmHandleIds = alternateIdChecker + .getIdsOfCmHandlesWithRejectedAlternateId(cmHandlesToBeCreated); + cmHandleRegistrationResponses.addAll(CmHandleRegistrationResponse.createFailureResponses( + rejectedCmHandleIds, ALTERNATE_ID_ALREADY_ASSOCIATED)); + return rejectedCmHandleIds; + } + + private List<String> persistCmHandlesWithState(final DmiPluginRegistration dmiPluginRegistration, + final DmiPluginRegistrationResponse dmiPluginRegistrationResponse, + final List<NcmpServiceCmHandle> cmHandlesToBeCreated, + final Collection<String> rejectedCmHandleIds) { + final List<String> succeededCmHandleIds = new ArrayList<>(cmHandlesToBeCreated.size()); + final List<YangModelCmHandle> yangModelCmHandlesToRegister = new ArrayList<>(cmHandlesToBeCreated.size()); + final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses = + new ArrayList<>(cmHandlesToBeCreated.size()); + for (final NcmpServiceCmHandle ncmpServiceCmHandle: cmHandlesToBeCreated) { + if (!rejectedCmHandleIds.contains(ncmpServiceCmHandle.getCmHandleId())) { + yangModelCmHandlesToRegister.add(getYangModelCmHandle(dmiPluginRegistration, ncmpServiceCmHandle)); + cmHandleRegistrationResponses.add( + CmHandleRegistrationResponse.createSuccessResponse(ncmpServiceCmHandle.getCmHandleId())); + succeededCmHandleIds.add(ncmpServiceCmHandle.getCmHandleId()); + } + } + lcmEventsCmHandleStateHandler.initiateStateAdvised(yangModelCmHandlesToRegister); + dmiPluginRegistrationResponse.setCreatedCmHandles(cmHandleRegistrationResponses); + return succeededCmHandleIds; + } + + private YangModelCmHandle getYangModelCmHandle(final DmiPluginRegistration dmiPluginRegistration, + final NcmpServiceCmHandle ncmpServiceCmHandle) { + return YangModelCmHandle.toYangModelCmHandle( + dmiPluginRegistration.getDmiPlugin(), + dmiPluginRegistration.getDmiDataPlugin(), + dmiPluginRegistration.getDmiModelPlugin(), + ncmpServiceCmHandle, + ncmpServiceCmHandle.getModuleSetTag(), + ncmpServiceCmHandle.getAlternateId()); + } + + private void processTrustLevels(final Collection<NcmpServiceCmHandle> cmHandlesToBeCreated, + final Collection<String> succeededCmHandleIds) { + final Map<String, TrustLevel> initialTrustLevelPerCmHandleId = new HashMap<>(cmHandlesToBeCreated.size()); + for (final NcmpServiceCmHandle ncmpServiceCmHandle: cmHandlesToBeCreated) { + if (succeededCmHandleIds.contains(ncmpServiceCmHandle.getCmHandleId())) { + initialTrustLevelPerCmHandleId.put(ncmpServiceCmHandle.getCmHandleId(), + ncmpServiceCmHandle.getRegistrationTrustLevel()); + } + } + trustLevelManager.handleInitialRegistrationOfTrustLevels(initialTrustLevelPerCmHandleId); } private static boolean moduleUpgradeCanBeSkipped(final YangModelCmHandle yangModelCmHandle, @@ -488,15 +513,14 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService private void deleteCmHandleFromDbAndModuleSyncMap(final String cmHandleId) { inventoryPersistence.deleteSchemaSetWithCascade(cmHandleId); - inventoryPersistence.deleteDataNode(NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='" + cmHandleId - + "']"); + inventoryPersistence.deleteDataNode(NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='" + cmHandleId + "']"); removeDeletedCmHandleFromModuleSyncMap(cmHandleId); } - private void batchDeleteCmHandlesFromDbAndModuleSyncMap(final Collection<String> tobeRemovedCmHandles) { - inventoryPersistence.deleteSchemaSetsWithCascade(tobeRemovedCmHandles); - inventoryPersistence.deleteDataNodes(mapCmHandleIdsToXpaths(tobeRemovedCmHandles)); - tobeRemovedCmHandles.forEach(this::removeDeletedCmHandleFromModuleSyncMap); + private void batchDeleteCmHandlesFromDbAndModuleSyncMap(final Collection<String> cmHandleIds) { + inventoryPersistence.deleteSchemaSetsWithCascade(cmHandleIds); + inventoryPersistence.deleteDataNodes(mapCmHandleIdsToXpaths(cmHandleIds)); + cmHandleIds.forEach(this::removeDeletedCmHandleFromModuleSyncMap); } private Collection<String> mapCmHandleIdsToXpaths(final Collection<String> cmHandles) { @@ -506,25 +530,9 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService } // CPS-1239 Robustness cleaning of in progress cache - private void removeDeletedCmHandleFromModuleSyncMap(final String deletedCmHandleId) { - if (moduleSyncStartedOnCmHandles.remove(deletedCmHandleId) != null) { - log.debug("{} removed from in progress map", deletedCmHandleId); - } - } - - private List<CmHandleRegistrationResponse> registerNewCmHandles(final List<YangModelCmHandle> yangModelCmHandles, - final Map<String, TrustLevel> - initialTrustLevelPerCmHandleId) { - final Set<String> cmHandleIds = initialTrustLevelPerCmHandleId.keySet(); - try { - lcmEventsCmHandleStateHandler.initiateStateAdvised(yangModelCmHandles); - trustLevelManager.handleInitialRegistrationOfTrustLevels(initialTrustLevelPerCmHandleId); - return CmHandleRegistrationResponse.createSuccessResponses(cmHandleIds); - } catch (final AlreadyDefinedException alreadyDefinedException) { - return CmHandleRegistrationResponse.createFailureResponses( - alreadyDefinedException.getAlreadyDefinedObjectNames(), CM_HANDLE_ALREADY_EXIST); - } catch (final Exception exception) { - return CmHandleRegistrationResponse.createFailureResponses(cmHandleIds, exception); + private void removeDeletedCmHandleFromModuleSyncMap(final String cmHandleId) { + if (moduleSyncStartedOnCmHandles.remove(cmHandleId) != null) { + log.debug("{} removed from in progress map", cmHandleId); } } @@ -553,6 +561,4 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService } } - - } 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 1478c86c24..f5d22af281 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 @@ -77,7 +77,8 @@ public class NetworkCmProxyDataServicePropertyHandler { */ public List<CmHandleRegistrationResponse> updateCmHandleProperties( final Collection<NcmpServiceCmHandle> ncmpServiceCmHandles) { - final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses = new ArrayList<>(); + final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses + = new ArrayList<>(ncmpServiceCmHandles.size()); for (final NcmpServiceCmHandle ncmpServiceCmHandle : ncmpServiceCmHandles) { final String cmHandleId = ncmpServiceCmHandle.getCmHandleId(); try { diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/AlternateIdChecker.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/AlternateIdChecker.java index 1be1a90853..4ac6537494 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/AlternateIdChecker.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/AlternateIdChecker.java @@ -103,10 +103,10 @@ public class AlternateIdChecker { * @param newNcmpServiceCmHandles the proposed new cm handles * @return collection of cm handles ids which are acceptable */ - public Collection<String> getIdsOfCmHandlesWithAcceptableAlternateId( + public Collection<String> getIdsOfCmHandlesWithRejectedAlternateId( final Collection<NcmpServiceCmHandle> newNcmpServiceCmHandles) { final Set<String> acceptedAlternateIds = new HashSet<>(newNcmpServiceCmHandles.size()); - final Collection<String> acceptedCmHandleIds = new ArrayList<>(newNcmpServiceCmHandles.size()); + final Collection<String> rejectedCmHandleIds = new ArrayList<>(); for (final NcmpServiceCmHandle ncmpServiceCmHandle : newNcmpServiceCmHandles) { final String cmHandleId = ncmpServiceCmHandle.getCmHandleId(); final String proposedAlternateId = ncmpServiceCmHandle.getAlternateId(); @@ -124,10 +124,11 @@ public class AlternateIdChecker { } if (isAcceptable) { acceptedAlternateIds.add(proposedAlternateId); - acceptedCmHandleIds.add(cmHandleId); + } else { + rejectedCmHandleIds.add(cmHandleId); } } - return acceptedCmHandleIds; + return rejectedCmHandleIds; } private boolean alternateIdAlreadyInDb(final String alternateId) { 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 82283228a1..52b8d6926a 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-2023 Nordix Foundation + * Modifications Copyright (C) 2022-2024 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -76,20 +76,22 @@ public class CmHandleRegistrationResponse { } /** - * Creates a failure response based on registration error. + * Create a failure response of cm handle registration based on xpath and registration error. + * Conditions: + * - the xpath should be valid according to the cps path, otherwise xpath is not included in the response. * - * @param failedXpaths list of failed Xpaths - * @param ncmpResponseStatus enum describing the type of registration error - * @return CmHandleRegistrationResponse + * @param failedXpaths the failed xpaths + * @param ncmpResponseStatus type of the registration error + * @return collection of cm handle registration response */ - public static List<CmHandleRegistrationResponse> createFailureResponses(final Collection<String> failedXpaths, - final NcmpResponseStatus ncmpResponseStatus) { + public static List<CmHandleRegistrationResponse> createFailureResponsesFromXpaths( + final Collection<String> failedXpaths, final NcmpResponseStatus ncmpResponseStatus) { final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses = new ArrayList<>(failedXpaths.size()); for (final String xpath : failedXpaths) { try { final String cmHandleId = YangDataConverter.extractCmHandleIdFromXpath(xpath); - cmHandleRegistrationResponses.add( - CmHandleRegistrationResponse.createFailureResponse(cmHandleId, ncmpResponseStatus)); + cmHandleRegistrationResponses + .add(CmHandleRegistrationResponse.createFailureResponse(cmHandleId, ncmpResponseStatus)); } catch (IllegalArgumentException | IllegalStateException e) { log.warn("Unexpected xpath {}", xpath); } @@ -98,6 +100,24 @@ public class CmHandleRegistrationResponse { } /** + * Create a failure response of cm handle registration based on cm handle id and registration error. + * + * @param failedCmHandleIds the failed cm handle ids + * @param ncmpResponseStatus type of the registration error + * @return collection of cm handle registration response + */ + public static List<CmHandleRegistrationResponse> createFailureResponses( + final Collection<String> failedCmHandleIds, final NcmpResponseStatus ncmpResponseStatus) { + final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses = + new ArrayList<>(failedCmHandleIds.size()); + for (final String failedCmHandleId : failedCmHandleIds) { + cmHandleRegistrationResponses.add( + CmHandleRegistrationResponse.createFailureResponse(failedCmHandleId, ncmpResponseStatus)); + } + return cmHandleRegistrationResponses; + } + + /** * Creates a failure response based on other exception. * * @param cmHandleIds list of failed cmHandleIds 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 4615af61c1..7d6a8e1407 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-2023 Nordix Foundation + * Copyright (C) 2021-2024 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,7 +50,7 @@ public class DmiPluginRegistration { private List<String> removedCmHandles = Collections.emptyList(); - private UpgradedCmHandles upgradedCmHandles; + private UpgradedCmHandles upgradedCmHandles = new UpgradedCmHandles(); /** * Validates plugin service names. diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy index 313d1b4afd..cb7e1ef8a9 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplRegistrationSpec.groovy @@ -27,7 +27,6 @@ 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.NcmpResponseStatus.UNKNOWN_ERROR -import java.util.stream.Collectors import org.onap.cps.ncmp.api.impl.inventory.CompositeState import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevelManager import org.onap.cps.ncmp.api.impl.utils.AlternateIdChecker @@ -71,12 +70,18 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { def trustLevelPerDmiPlugin = [:] def mockTrustLevelManager = Mock(TrustLevelManager) def mockAlternateIdChecker = Mock(AlternateIdChecker) - def objectUnderTest = getObjectUnderTest() + + def objectUnderTest = Spy(new NetworkCmProxyDataServiceImpl(spiedJsonObjectMapper, mockDmiDataOperations, + mockNetworkCmProxyDataServicePropertyHandler, mockInventoryPersistence, mockCmHandleQueries, + stubbedNetworkCmProxyCmHandlerQueryService, mockLcmEventsCmHandleStateHandler, mockCpsDataService, + mockModuleSyncStartedOnCmHandles, trustLevelPerDmiPlugin, mockTrustLevelManager, mockAlternateIdChecker)) def setup() { // always accept all cm handles - mockAlternateIdChecker.getIdsOfCmHandlesWithAcceptableAlternateId(_) >> - { args -> args[0].stream().map(it -> it.cmHandleId).collect(Collectors.toList()) } + mockAlternateIdChecker.getIdsOfCmHandlesWithRejectedAlternateId(_) >> [] + + // always can find all cm handles in DB + mockInventoryPersistence.getYangModelCmHandles(_) >> { args -> args[0].collect { new YangModelCmHandle(id:it) } } } def 'DMI Registration: Create, Update, Delete & Upgrade operations are processed in the right order'() { @@ -94,15 +99,16 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { when: 'registration is processed' objectUnderTest.updateDmiRegistrationAndSyncModule(dmiRegistration) then: 'cm-handles are removed first' - 1 * objectUnderTest.parseAndProcessDeletedCmHandlesInRegistration(*_) + 1 * objectUnderTest.processRemovedCmHandles(*_) and: 'de-registered cm handle entry is removed from in progress map' 1 * mockModuleSyncStartedOnCmHandles.remove('cmhandle-2') then: 'cm-handles are created' - 1 * objectUnderTest.parseAndProcessCreatedCmHandlesInRegistration(*_) + 1 * objectUnderTest.processCreatedCmHandles(*_) then: 'cm-handles are updated' - 1 * mockNetworkCmProxyDataServicePropertyHandler.updateCmHandleProperties(*_) + 1 * objectUnderTest.processUpdatedCmHandles(*_) + 1 * mockNetworkCmProxyDataServicePropertyHandler.updateCmHandleProperties(*_) >> [] then: 'cm-handles are upgraded' - 1 * objectUnderTest.parseAndProcessUpgradedCmHandlesInRegistration(*_) + 1 * objectUnderTest.processUpgradedCmHandles(*_) } def 'DMI Registration upgrade operation with upgrade node state #scenario'() { @@ -137,29 +143,6 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { 'cm handle is invalid' | new DataValidationException('some error message', 'some error details') || '110' } - def 'DMI Registration: Response from all operations types are in response'() { - given: 'a registration with operations of all three types' - def dmiRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server') - dmiRegistration.setCreatedCmHandles([new NcmpServiceCmHandle(cmHandleId: 'cmhandle-1', publicProperties: ['publicProp1': 'value'], dmiProperties: [:])]) - dmiRegistration.setUpdatedCmHandles([new NcmpServiceCmHandle(cmHandleId: 'cmhandle-2', publicProperties: ['publicProp1': 'value'], dmiProperties: [:])]) - dmiRegistration.setRemovedCmHandles(['cmhandle-2']) - and: 'update cm-handles can be processed successfully' - def updateResponses = [CmHandleRegistrationResponse.createSuccessResponse('cmhandle-2')] - mockNetworkCmProxyDataServicePropertyHandler.updateCmHandleProperties(*_) >> updateResponses - and: 'create cm-handles can be processed successfully' - def createdResponses = [CmHandleRegistrationResponse.createSuccessResponse('cmhandle-1')] - objectUnderTest.parseAndProcessCreatedCmHandlesInRegistration(*_) >> createdResponses - and: 'delete cm-handles can be processed successfully' - def removeResponses = [CmHandleRegistrationResponse.createSuccessResponse('cmhandle-3')] - objectUnderTest.parseAndProcessDeletedCmHandlesInRegistration(*_) >> removeResponses - when: 'registration is processed' - def response = objectUnderTest.updateDmiRegistrationAndSyncModule(dmiRegistration) - then: 'response has values from all operations' - response.removedCmHandles == removeResponses - response.createdCmHandles == createdResponses - response.updatedCmHandles == updateResponses - } - def 'Create CM-handle Validation: Registration with valid Service names: #scenario'() { given: 'a registration ' def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: dmiPlugin, dmiModelPlugin: dmiModelPlugin, @@ -168,7 +151,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { when: 'update registration and sync module is called with correct DMI plugin information' objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration) then: 'create cm handles registration and sync modules is called with the correct plugin information' - 1 * objectUnderTest.parseAndProcessCreatedCmHandlesInRegistration(dmiPluginRegistration, _) + 1 * objectUnderTest.processCreatedCmHandles(dmiPluginRegistration, _) and: 'dmi is added to the dmi trustLevel map' assert trustLevelPerDmiPlugin.size() == 1 assert trustLevelPerDmiPlugin.containsKey(expectedDmiPluginRegisteredName) @@ -190,7 +173,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { def exceptionThrown = thrown(DmiRequestException.class) assert exceptionThrown.getMessage().contains(expectedMessageDetails) and: 'registration is not called' - 0 * objectUnderTest.parseAndProcessCreatedCmHandlesInRegistration(dmiPluginRegistration) + 0 * objectUnderTest.processCreatedCmHandles(*_) where: scenario | dmiPlugin | dmiModelPlugin | dmiDataPlugin || expectedMessageDetails 'empty DMI plugins' | '' | '' | '' || 'No DMI plugin service names' @@ -231,22 +214,18 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { 'without dmi & public properties' | [:] | [:] || [:] | [:] } - def 'Add CM-Handle to trustLevelPerCmHandle Successfully with: #scenario.'() { - given: 'a registration with trustLevel and populated cache' - def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server') - dmiPluginRegistration.createdCmHandles = [new NcmpServiceCmHandle(cmHandleId: 'ch-1', registrationTrustLevel: TrustLevel.NONE), - new NcmpServiceCmHandle(cmHandleId: cmHandleId, registrationTrustLevel: registrationTrustLevel)] + def 'Add CM-Handle #scenario.'() { + given: ' registration details for one cm handles' + def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server', + createdCmHandles:[new NcmpServiceCmHandle(cmHandleId: 'ch-1', registrationTrustLevel: registrationTrustLevel)]) when: 'registration is updated' - def response = objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration) - then: 'a successful response is received' - assert response.createdCmHandles.size() == expectedNumberOfCreatedCmHandles - and: 'trustLevel is set for the created cm-handle' - 1 * mockTrustLevelManager.handleInitialRegistrationOfTrustLevels(_) + objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration) + then: 'trustLevel is set for the created cm-handle' + 1 * mockTrustLevelManager.handleInitialRegistrationOfTrustLevels(expectedMapping) where: - scenario | cmHandleId | registrationTrustLevel || expectedNumberOfCreatedCmHandles - 'new trusted cm handle' | 'ch-new' | TrustLevel.COMPLETE || 2 - 'existing cm handle without trust level' | 'ch-1' | null || 1 - 'new cm handle without trust level' | 'ch-new' | null || 2 + scenario | registrationTrustLevel || expectedMapping + 'with trusted cm handle' | TrustLevel.COMPLETE || [ 'ch-1' : TrustLevel.COMPLETE ] + 'without trust level' | null || [ 'ch-1' : null ] } def 'Create CM-Handle Multiple Requests: All cm-handles creation requests are processed with some failures'() { @@ -311,17 +290,15 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { def 'Remove CmHandle Successfully: #scenario'() { given: 'a registration' - addPersistedYangModelCmHandles(['cmhandle']) - def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server', - removedCmHandles: ['cmhandle']) + def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server', removedCmHandles: ['cmhandle']) and: '#scenario' - mockCpsModuleService.deleteSchemaSetsWithCascade(_, ['cmhandle']) >> - { if (!schemaSetExist) { throw new SchemaSetNotFoundException("", "") } } + mockCpsModuleService.deleteSchemaSetsWithCascade(_, ['cmhandle']) >> { if (!schemaSetExist) { throw new SchemaSetNotFoundException('', '') } } when: 'registration is updated to delete cmhandle' def response = objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration) then: 'the cmHandle state is updated to "DELETING"' - 1 * mockLcmEventsCmHandleStateHandler.updateCmHandleStateBatch(_) - and: 'method to delete relevant schema set is called once' + 1 * mockLcmEventsCmHandleStateHandler.updateCmHandleStateBatch(_) >> + { args -> args[0].values()[0] == CmHandleState.DELETING } + then: 'method to delete relevant schema set is called once' 1 * mockInventoryPersistence.deleteSchemaSetsWithCascade(_) and: 'method to delete relevant list/list element is called once' 1 * mockInventoryPersistence.deleteDataNodes(_) @@ -332,7 +309,10 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { assert it.cmHandle == 'cmhandle' } and: 'the cmHandle state is updated to "DELETED"' - 1 * mockLcmEventsCmHandleStateHandler.updateCmHandleStateBatch(_) + 1 * mockLcmEventsCmHandleStateHandler.updateCmHandleStateBatch(_) >> + { args -> args[0].values()[0] == CmHandleState.DELETED } + and: 'No cm handles state updates for "upgraded cm handles"' + 1 * mockLcmEventsCmHandleStateHandler.updateCmHandleStateBatch([:]) where: scenario | schemaSetExist 'schema-set exists and can be deleted successfully' | true @@ -340,9 +320,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { } def 'Remove CmHandle: Partial Success'() { - given: 'some unique yang model cm handles' - addPersistedYangModelCmHandles(['cmhandle1', 'cmhandle2', 'cmhandle3']) - and: 'a registration with three cm-handles to be deleted' + given: 'a registration with three cm-handles to be deleted' def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server', removedCmHandles: ['cmhandle1', 'cmhandle2', 'cmhandle3']) and: 'cm-handle deletion fails on batch' @@ -359,7 +337,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { 1 * mockModuleSyncStartedOnCmHandles.remove('cmhandle1') and: 'successfully de-registered cm handle 3 is removed from in progress map even though it was already being removed' 1 * mockModuleSyncStartedOnCmHandles.remove('cmhandle3') >> 'already in progress' - and: 'failed de-registered cm handle entries should not be removed from in progress map' + and: 'failed de-registered cm handle entries should NOT be removed from in progress map' 0 * mockModuleSyncStartedOnCmHandles.remove('cmhandle2') and: '1st and 3rd cm-handle deletes successfully' with(response.removedCmHandles[0]) { @@ -382,11 +360,13 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { assert it.size() == 2 assert it.every { entry -> entry.value == CmHandleState.DELETED } }) + and: 'No cm handles state updates for "upgraded cm handles"' + 1 * mockLcmEventsCmHandleStateHandler.updateCmHandleStateBatch([:]) + } def 'Remove CmHandle Error Handling: Schema Set Deletion failed'() { given: 'a registration' - addPersistedYangModelCmHandles(['cmhandle']) def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server', removedCmHandles: ['cmhandle']) and: 'schema set batch deletion failed with unknown error' @@ -413,7 +393,6 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { def 'Remove CmHandle Error Handling: #scenario'() { given: 'a registration' - addPersistedYangModelCmHandles(['cmhandle']) def dmiPluginRegistration = new DmiPluginRegistration(dmiPlugin: 'my-server', removedCmHandles: ['cmhandle']) and: 'cm-handle deletion fails on batch' @@ -446,18 +425,7 @@ class NetworkCmProxyDataServiceImplRegistrationSpec extends Specification { when: 'the DMI plugin registration happens' objectUnderTest.updateDmiRegistrationAndSyncModule(dmiPluginRegistration) then: 'the new alternate id is added to the cache' - 1 * mockAlternateIdChecker.getIdsOfCmHandlesWithAcceptableAlternateId(ncmpServiceCmHandles) >> ['cmhandle1'] + 1 * mockAlternateIdChecker.getIdsOfCmHandlesWithRejectedAlternateId(ncmpServiceCmHandles) >> ['cmhandle1'] } - def getObjectUnderTest() { - return Spy(new NetworkCmProxyDataServiceImpl(spiedJsonObjectMapper, mockDmiDataOperations, - mockNetworkCmProxyDataServicePropertyHandler, mockInventoryPersistence, mockCmHandleQueries, - stubbedNetworkCmProxyCmHandlerQueryService, mockLcmEventsCmHandleStateHandler, mockCpsDataService, - mockModuleSyncStartedOnCmHandles, trustLevelPerDmiPlugin, mockTrustLevelManager, mockAlternateIdChecker)) - } - - def addPersistedYangModelCmHandles(ids) { - def yangModelCmHandles = ids.collect { new YangModelCmHandle(id:it) } - mockInventoryPersistence.getYangModelCmHandles(ids) >> yangModelCmHandles - } } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy index fc548ebe9b..9b4fe146b9 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImplSpec.groovy @@ -23,6 +23,8 @@ package org.onap.cps.ncmp.api.impl +import org.onap.cps.ncmp.api.models.DmiPluginRegistrationResponse + import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME 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 @@ -270,8 +272,11 @@ class NetworkCmProxyDataServiceImplSpec extends Specification { dmiDataPlugin: 'service2') dmiPluginRegistration.createdCmHandles = [ncmpServiceCmHandle] mockDmiPluginRegistration.getCreatedCmHandles() >> [ncmpServiceCmHandle] + and: 'no rejected cm handles because of alternate ids' + mockAlternateIdChecker.getIdsOfCmHandlesWithRejectedAlternateId(_) >> [] when: 'parse and create cm handle in dmi registration then sync module' - objectUnderTest.parseAndProcessCreatedCmHandlesInRegistration(mockDmiPluginRegistration, ['test-cm-handle-id']) + mockDmiPluginRegistration.createdCmHandles = ['test-cm-handle-id'] + objectUnderTest.processCreatedCmHandles(mockDmiPluginRegistration, new DmiPluginRegistrationResponse()) then: 'system persists the cm handle state' 1 * mockLcmEventsCmHandleStateHandler.initiateStateAdvised(_) >> { args -> { diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/AlternateIdCheckerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/AlternateIdCheckerSpec.groovy index f41fd6cdf3..aaa034437c 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/AlternateIdCheckerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/impl/utils/AlternateIdCheckerSpec.groovy @@ -76,17 +76,17 @@ class AlternateIdCheckerSpec extends Specification { mockInventoryPersistenceService.getCmHandleDataNodeByAlternateId(_) >> { args -> altAlreadyInDb.contains(args[0]) ? new DataNode() : throwDataNodeNotFoundException() } when: 'the batch of new cm handles is checked' - def result = objectUnderTest.getIdsOfCmHandlesWithAcceptableAlternateId(batch) + def result = objectUnderTest.getIdsOfCmHandlesWithRejectedAlternateId(batch) then: 'the result only contains the ids of the acceptable cm handles' - assert result.contains('ch-1') == acceptCh1 - assert result.contains('ch-2') == acceptCh2 + assert result.contains('ch-1') == rejectCh1 + assert result.contains('ch-2') == rejectCh2 where: 'the following alternate ids are used' - scenario | alt1 | alt2 | altAlreadyInDb || acceptCh1 | acceptCh2 - 'no alternate ids' | '' | '' | ['dont matter'] || true | true - 'new alternate ids' | 'fdn1' | 'fdn2' | ['other fdn'] || true | true - 'one already used alternate id' | 'fdn1' | 'fdn2' | ['fdn1'] || false | true - 'two already used alternate ids' | 'fdn1' | 'fdn2' | ['fdn1','fdn2'] || false | false - 'duplicate alternate id in batch' | 'fdn1' | 'fdn1' | ['dont matter'] || true | false + scenario | alt1 | alt2 | altAlreadyInDb || rejectCh1 | rejectCh2 + 'no alternate ids' | '' | '' | ['dont matter'] || false | false + 'new alternate ids' | 'fdn1' | 'fdn2' | ['other fdn'] || false | false + 'one already used alternate id' | 'fdn1' | 'fdn2' | ['fdn1'] || true | false + 'two already used alternate ids' | 'fdn1' | 'fdn2' | ['fdn1','fdn2'] || true | true + 'duplicate alternate id in batch' | 'fdn1' | 'fdn1' | ['dont matter'] || false | true } def throwDataNodeNotFoundException() { diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/CmHandleRegistrationResponseSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/CmHandleRegistrationResponseSpec.groovy index d76f912234..7803ae319f 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/CmHandleRegistrationResponseSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/api/models/CmHandleRegistrationResponseSpec.groovy @@ -1,7 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2022 Bell Canada - * Modifications Copyright (C) 2023 Nordix Foundation + * Modifications Copyright (C) 2023-2024 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,6 +21,7 @@ package org.onap.cps.ncmp.api.models +import static org.onap.cps.ncmp.api.NcmpResponseStatus.ALTERNATE_ID_ALREADY_ASSOCIATED import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_ALREADY_EXIST import static org.onap.cps.ncmp.api.NcmpResponseStatus.UNKNOWN_ERROR @@ -71,7 +72,7 @@ class CmHandleRegistrationResponseSpec extends Specification { def 'Failed cm-handle Registration with multiple responses.'() { when: 'cm-handle failure response is created for 2 xpaths' def cmHandleRegistrationResponses = - CmHandleRegistrationResponse.createFailureResponses(["somePathWithId[@id='123']","somePathWithId[@id='456']"], CM_HANDLE_ALREADY_EXIST) + CmHandleRegistrationResponse.createFailureResponsesFromXpaths(["somePathWithId[@id='123']", "somePathWithId[@id='456']"], CM_HANDLE_ALREADY_EXIST) then: 'the response has the correct cm handle ids' assert cmHandleRegistrationResponses.size() == 2 assert cmHandleRegistrationResponses.stream().map(it -> it.cmHandle).collect(Collectors.toList()) @@ -81,9 +82,20 @@ class CmHandleRegistrationResponseSpec extends Specification { def 'Failed cm-handle Registration with multiple responses with an unexpected xpath.'() { when: 'cm-handle failure response is created for one valid and one unexpected xpath' def cmHandleRegistrationResponses = - CmHandleRegistrationResponse.createFailureResponses(["somePathWithId[@id='123']","valid/xpath/without-id[@key='123']"], CM_HANDLE_ALREADY_EXIST) + CmHandleRegistrationResponse.createFailureResponsesFromXpaths(["somePathWithId[@id='123']", "valid/xpath/without-id[@key='123']"], CM_HANDLE_ALREADY_EXIST) then: 'the response has only one entry' assert cmHandleRegistrationResponses.size() == 1 } + def 'Failed cm-handle registration based on cm handle id and registration error'() { + when: 'the failure response is created with "alternate id already associated" error code for 1 cm handle' + def cmHandleRegistrationResponses = + CmHandleRegistrationResponse.createFailureResponses(['ch 1'], ALTERNATE_ID_ALREADY_ASSOCIATED) + then: 'the response with expected values' + assert cmHandleRegistrationResponses[0].cmHandle == 'ch 1' + assert cmHandleRegistrationResponses[0].status == Status.FAILURE + assert cmHandleRegistrationResponses[0].ncmpResponseStatus == ALTERNATE_ID_ALREADY_ASSOCIATED + assert cmHandleRegistrationResponses[0].errorText == 'alternate id already associated' + } + } diff --git a/docs/cps-ncmp-message-status-codes.rst b/docs/cps-ncmp-message-status-codes.rst index 20a5ae3c11..90590a2016 100644 --- a/docs/cps-ncmp-message-status-codes.rst +++ b/docs/cps-ncmp-message-status-codes.rst @@ -1,6 +1,6 @@ .. This work is licensed under a Creative Commons Attribution 4.0 International License. .. http://creativecommons.org/licenses/by/4.0 -.. Copyright (C) 2023 Nordix Foundation +.. Copyright (C) 2023-2024 Nordix Foundation .. DO NOT CHANGE THIS LABEL FOR RELEASE NOTES - EVEN THOUGH IT GIVES A WARNING .. _dataOperationMessageStatusCodes: @@ -38,6 +38,8 @@ CPS-NCMP Message Status Codes +-----------------+------------------------------------------------------+-----------------------------------+ | 110 | cm-handle has an invalid character(s) in id | Inventory | +-----------------+------------------------------------------------------+-----------------------------------+ + | 111 | alternate id already associated | Inventory | + +-----------------+------------------------------------------------------+-----------------------------------+ .. note:: |