diff options
Diffstat (limited to 'cps-ncmp-service/src')
25 files changed, 325 insertions, 303 deletions
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiInEventProducer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiInEventProducer.java index c62916f05c..232803a941 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiInEventProducer.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiInEventProducer.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2024 Nordix Foundation + * Copyright (C) 2024-2025 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,14 +20,14 @@ package org.onap.cps.ncmp.impl.cmnotificationsubscription.dmi; +import static org.onap.cps.ncmp.events.NcmpEventDataSchema.SUBSCRIPTIONS_V1; + import io.cloudevents.CloudEvent; -import io.cloudevents.core.builder.CloudEventBuilder; -import java.net.URI; -import java.util.UUID; +import java.util.Map; import lombok.RequiredArgsConstructor; import org.onap.cps.events.EventsPublisher; import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_dmi.DmiInEvent; -import org.onap.cps.utils.JsonObjectMapper; +import org.onap.cps.ncmp.utils.events.NcmpEvent; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Component; @@ -38,7 +38,6 @@ import org.springframework.stereotype.Component; public class DmiInEventProducer { private final EventsPublisher<CloudEvent> eventsPublisher; - private final JsonObjectMapper jsonObjectMapper; @Value("${app.ncmp.avc.cm-subscription-dmi-in}") private String dmiInEventTopic; @@ -58,13 +57,15 @@ public class DmiInEventProducer { } - private CloudEvent buildAndGetDmiInEventAsCloudEvent(final String subscriptionId, - final String dmiPluginName, final String eventType, final DmiInEvent dmiInEvent) { - return CloudEventBuilder.v1().withId(UUID.randomUUID().toString()).withType(eventType) - .withSource(URI.create("NCMP")) - .withDataSchema(URI.create("org.onap.ncmp.dmi.cm.subscription:1.0.0")) - .withExtension("correlationid", subscriptionId.concat("#").concat(dmiPluginName)) - .withData(jsonObjectMapper.asJsonBytes(dmiInEvent)).build(); + private CloudEvent buildAndGetDmiInEventAsCloudEvent(final String subscriptionId, final String dmiPluginName, + final String eventType, final DmiInEvent dmiInEvent) { + return NcmpEvent.builder() + .type(eventType) + .dataSchema(SUBSCRIPTIONS_V1.getDataSchema()) + .extensions(Map.of("correlationid", String.join("#", subscriptionId, dmiPluginName))) + .data(dmiInEvent) + .build() + .asCloudEvent(); } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventProducer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventProducer.java index 3371d59f7a..8cfb3ad563 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventProducer.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventProducer.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2024 Nordix Foundation + * Copyright (C) 2024-2025 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,11 +20,10 @@ package org.onap.cps.ncmp.impl.cmnotificationsubscription.ncmp; +import static org.onap.cps.ncmp.events.NcmpEventDataSchema.SUBSCRIPTIONS_V1; + import io.cloudevents.CloudEvent; -import io.cloudevents.core.builder.CloudEventBuilder; -import java.net.URI; import java.util.Map; -import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -35,7 +34,7 @@ import lombok.extern.slf4j.Slf4j; import org.onap.cps.events.EventsPublisher; import org.onap.cps.ncmp.impl.cmnotificationsubscription.cache.DmiCacheHandler; import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_client.NcmpOutEvent; -import org.onap.cps.utils.JsonObjectMapper; +import org.onap.cps.ncmp.utils.events.NcmpEvent; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Component; @@ -53,7 +52,6 @@ public class NcmpOutEventProducer { private Integer dmiOutEventTimeoutInMs; private final EventsPublisher<CloudEvent> eventsPublisher; - private final JsonObjectMapper jsonObjectMapper; private final NcmpOutEventMapper ncmpOutEventMapper; private final DmiCacheHandler dmiCacheHandler; private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); @@ -91,49 +89,48 @@ public class NcmpOutEventProducer { } } + /** + * Get an NCMP out event as cloud event. + * + * @param subscriptionId subscription id + * @param eventType event type + * @param ncmpOutEvent cm notification subscription NCMP out event + * @return cm notification subscription NCMP out event as cloud event + */ + public static CloudEvent buildAndGetNcmpOutEventAsCloudEvent( + final String subscriptionId, final String eventType, final NcmpOutEvent ncmpOutEvent) { + + return NcmpEvent.builder() + .type(eventType) + .dataSchema(SUBSCRIPTIONS_V1.getDataSchema()) + .extensions(Map.of("correlationid", subscriptionId)) + .data(ncmpOutEvent) + .build() + .asCloudEvent(); + } + private ScheduledFuture<?> scheduleAndPublishNcmpOutEvent(final String subscriptionId, final String eventType) { final NcmpOutEventPublishingTask ncmpOutEventPublishingTask = new NcmpOutEventPublishingTask(ncmpOutEventTopic, subscriptionId, eventType, eventsPublisher, - jsonObjectMapper, ncmpOutEventMapper, dmiCacheHandler); + ncmpOutEventMapper, dmiCacheHandler); return scheduledExecutorService.schedule(ncmpOutEventPublishingTask, dmiOutEventTimeoutInMs, TimeUnit.MILLISECONDS); } private void cancelScheduledTask(final String taskKey) { - final ScheduledFuture<?> scheduledFuture = scheduledTasksPerSubscriptionIdAndEventType.get(taskKey); if (scheduledFuture != null) { scheduledFuture.cancel(true); scheduledTasksPerSubscriptionIdAndEventType.remove(taskKey); } - } - private void publishNcmpOutEventNow(final String subscriptionId, final String eventType, final NcmpOutEvent ncmpOutEvent) { final CloudEvent ncmpOutEventAsCloudEvent = - buildAndGetNcmpOutEventAsCloudEvent(jsonObjectMapper, subscriptionId, eventType, ncmpOutEvent); + buildAndGetNcmpOutEventAsCloudEvent(subscriptionId, eventType, ncmpOutEvent); eventsPublisher.publishCloudEvent(ncmpOutEventTopic, subscriptionId, ncmpOutEventAsCloudEvent); dmiCacheHandler.removeAcceptedAndRejectedDmiSubscriptionEntries(subscriptionId); } - /** - * Get an NCMP out event as cloud event. - * - * @param jsonObjectMapper JSON object mapper - * @param subscriptionId subscription id - * @param eventType event type - * @param ncmpOutEvent cm notification subscription NCMP out event - * @return cm notification subscription NCMP out event as cloud event - */ - public static CloudEvent buildAndGetNcmpOutEventAsCloudEvent(final JsonObjectMapper jsonObjectMapper, - final String subscriptionId, final String eventType, final NcmpOutEvent ncmpOutEvent) { - - return CloudEventBuilder.v1().withId(UUID.randomUUID().toString()).withType(eventType) - .withSource(URI.create("NCMP")).withDataSchema(URI.create("org.onap.ncmp.cm.subscription:1.0.0")) - .withExtension("correlationid", subscriptionId) - .withData(jsonObjectMapper.asJsonBytes(ncmpOutEvent)).build(); - } - } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventPublishingTask.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventPublishingTask.java index f8f253d275..e9d6d78429 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventPublishingTask.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventPublishingTask.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2024 Nordix Foundation + * Copyright (C) 2024-2025 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,6 @@ import org.onap.cps.events.EventsPublisher; import org.onap.cps.ncmp.impl.cmnotificationsubscription.cache.DmiCacheHandler; import org.onap.cps.ncmp.impl.cmnotificationsubscription.models.DmiCmSubscriptionDetails; import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_client.NcmpOutEvent; -import org.onap.cps.utils.JsonObjectMapper; @Slf4j @RequiredArgsConstructor @@ -40,7 +39,6 @@ public class NcmpOutEventPublishingTask implements Runnable { private final String subscriptionId; private final String eventType; private final EventsPublisher<CloudEvent> eventsPublisher; - private final JsonObjectMapper jsonObjectMapper; private final NcmpOutEventMapper ncmpOutEventMapper; private final DmiCacheHandler dmiCacheHandler; @@ -55,8 +53,7 @@ public class NcmpOutEventPublishingTask implements Runnable { final NcmpOutEvent ncmpOutEvent = ncmpOutEventMapper.toNcmpOutEvent(subscriptionId, dmiSubscriptionsPerDmi); eventsPublisher.publishCloudEvent(topicName, subscriptionId, - buildAndGetNcmpOutEventAsCloudEvent(jsonObjectMapper, subscriptionId, eventType, - ncmpOutEvent)); + buildAndGetNcmpOutEventAsCloudEvent(subscriptionId, eventType, ncmpOutEvent)); dmiCacheHandler.removeAcceptedAndRejectedDmiSubscriptionEntries(subscriptionId); } } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/DmiDataOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/DmiDataOperations.java index 189239ceb2..7cb1c44526 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/DmiDataOperations.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/DmiDataOperations.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2021-2024 Nordix Foundation + * Copyright (C) 2021-2025 Nordix Foundation * Modifications Copyright (C) 2022 Bell Canada * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -34,7 +34,6 @@ import java.util.Set; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.onap.cps.api.exceptions.CpsException; -import org.onap.cps.api.exceptions.DataValidationException; import org.onap.cps.ncmp.api.NcmpResponseStatus; import org.onap.cps.ncmp.api.data.models.CmResourceAddress; import org.onap.cps.ncmp.api.data.models.DataOperationRequest; @@ -79,7 +78,7 @@ public class DmiDataOperations { * This method fetches the resource data from the operational data store for a given CM handle * identifier on the specified resource using the DMI client. * - * @param cmResourceAddress Target datastore, CM handle, and resource identifier. + * @param cmResourceAddress Target datastore, CM handle reference, and resource identifier. * @param options Options query string. * @param topic Topic name for triggering asynchronous responses. * @param requestId Request ID for asynchronous responses. @@ -94,7 +93,8 @@ public class DmiDataOperations { final String topic, final String requestId, final String authorization) { - final YangModelCmHandle yangModelCmHandle = resolveYangModelCmHandleFromCmHandleReference(cmResourceAddress); + final YangModelCmHandle yangModelCmHandle = getYangModelCmHandle( + cmResourceAddress.resolveCmHandleReferenceToId()); final CmHandleState cmHandleState = yangModelCmHandle.getCompositeState().getCmHandleState(); validateIfCmHandleStateReady(yangModelCmHandle, cmHandleState); final String jsonRequestBody = getDmiRequestBody(READ, requestId, null, null, yangModelCmHandle); @@ -157,22 +157,22 @@ public class DmiDataOperations { * This method creates the resource data from pass-through running data store for given cm handle * identifier on given resource using dmi client. * - * @param cmHandleId network resource identifier - * @param resourceId resource identifier - * @param operationType operation enum - * @param requestData the request data - * @param dataType data type - * @param authorization contents of Authorization header, or null if not present + * @param cmHandleReference network resource identifier + * @param resourceId resource identifier + * @param operationType operation enum + * @param requestData the request data + * @param dataType data type + * @param authorization contents of Authorization header, or null if not present * @return {@code ResponseEntity} response entity */ - public ResponseEntity<Object> writeResourceDataPassThroughRunningFromDmi(final String cmHandleId, + public ResponseEntity<Object> writeResourceDataPassThroughRunningFromDmi(final String cmHandleReference, final String resourceId, final OperationType operationType, final String requestData, final String dataType, final String authorization) { final CmResourceAddress cmResourceAddress = - new CmResourceAddress(PASSTHROUGH_RUNNING.getDatastoreName(), cmHandleId, resourceId); + new CmResourceAddress(PASSTHROUGH_RUNNING.getDatastoreName(), cmHandleReference, resourceId); final YangModelCmHandle yangModelCmHandle = getYangModelCmHandle(cmResourceAddress.resolveCmHandleReferenceToId()); @@ -281,16 +281,6 @@ public class DmiDataOperations { }).subscribe(); } - private YangModelCmHandle resolveYangModelCmHandleFromCmHandleReference(final CmResourceAddress cmResourceAddress) { - String cmHandleId = cmResourceAddress.getCmHandleReference(); - try { - return getYangModelCmHandle(cmHandleId); - } catch (final DataValidationException ignored) { - cmHandleId = cmResourceAddress.resolveCmHandleReferenceToId(); - return getYangModelCmHandle(cmHandleId); - } - } - private String createDmiDataOperationRequestAsJsonString( final List<DmiDataOperation> dmiDataOperationRequestBodies) { final DmiDataOperationRequest dmiDataOperationRequest = DmiDataOperationRequest.builder() diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/utils/DataOperationEventCreator.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/utils/DataOperationEventCreator.java index d74abb9935..14e2eda2d2 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/utils/DataOperationEventCreator.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/utils/DataOperationEventCreator.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2023-2024 Nordix Foundation + * Copyright (C) 2023-2025 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,8 @@ package org.onap.cps.ncmp.impl.data.utils; +import static org.onap.cps.ncmp.events.NcmpEventDataSchema.BATCH_RESPONSE_V1; + import io.cloudevents.CloudEvent; import java.util.ArrayList; import java.util.HashMap; @@ -27,7 +29,6 @@ import java.util.List; import java.util.Map; import lombok.AccessLevel; import lombok.NoArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.onap.cps.ncmp.api.NcmpResponseStatus; import org.onap.cps.ncmp.events.async1_0_0.Data; import org.onap.cps.ncmp.events.async1_0_0.DataOperationEvent; @@ -36,7 +37,6 @@ import org.onap.cps.ncmp.impl.data.models.DmiDataOperation; import org.onap.cps.ncmp.utils.events.NcmpEvent; import org.springframework.util.MultiValueMap; -@Slf4j @NoArgsConstructor(access = AccessLevel.PRIVATE) public class DataOperationEventCreator { @@ -57,8 +57,13 @@ public class DataOperationEventCreator { final Data data = createPayloadFromDataOperationResponses(cmHandleIdsPerResponseCodesPerOperation); dataOperationEvent.setData(data); final Map<String, String> extensions = createDataOperationExtensions(requestId, clientTopic); - return NcmpEvent.builder().type(DataOperationEvent.class.getName()) - .data(dataOperationEvent).extensions(extensions).build().asCloudEvent(); + return NcmpEvent.builder() + .type(DataOperationEvent.class.getName()) + .data(dataOperationEvent) + .dataSchema(BATCH_RESPONSE_V1.getDataSchema()) + .extensions(extensions) + .build() + .asCloudEvent(); } private static Data createPayloadFromDataOperationResponses(final MultiValueMap<DmiDataOperation, diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryService.java index 9447f13b68..9cbc6b0650 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryService.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryService.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022-2024 Nordix Foundation + * Copyright (C) 2022-2025 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -84,6 +84,16 @@ public interface CmHandleQueryService { Collection<DataNode> queryNcmpRegistryByCpsPath(String cpsPath, FetchDescendantsOption fetchDescendantsOption); /** + * Method to return data nodes representing the cm handles. + * + * @param cpsPath cps path for which the cmHandle is requested + * @param queryResultLimit the maximum number of data nodes to return; if less than 1, returns all matching nodes + * @return a list of data nodes representing the cm handles. + */ + Collection<DataNode> queryNcmpRegistryByCpsPath(String cpsPath, FetchDescendantsOption fetchDescendantsOption, + int queryResultLimit); + + /** * Method to check the state of a cm handle with given id. * * @param cmHandleId cm handle id @@ -110,12 +120,4 @@ public interface CmHandleQueryService { Collection<String> getCmHandleReferencesByDmiPluginIdentifier(String dmiPluginIdentifier, boolean outputAlternateId); - /** - * Get map of cmHandle references by DMI plugin identifier. - * - * @param dmiPluginIdentifier DMI plugin identifier - * @return map of cmHandle references key:CmHandleId Value:AlternateId - */ - Map<String, String> getCmHandleReferencesMapByDmiPluginIdentifier(String dmiPluginIdentifier); - } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImpl.java index ae913ddfe7..8b6934b54c 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImpl.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022-2024 Nordix Foundation + * Copyright (C) 2022-2025 Nordix Foundation * Modifications Copyright (C) 2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,9 +28,9 @@ import static org.onap.cps.ncmp.impl.inventory.NcmpPersistence.NCMP_DMI_REGISTRY import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.onap.cps.api.CpsDataService; @@ -52,10 +52,9 @@ import org.springframework.stereotype.Component; @RequiredArgsConstructor @Component public class CmHandleQueryServiceImpl implements CmHandleQueryService { - - private static final String DESCENDANT_PATH = "//"; private static final String ANCESTOR_CM_HANDLES = "/ancestor::cm-handles"; private static final String ALTERNATE_ID = "alternate-id"; + private static final Integer NO_LIMIT = 0; private final CpsDataService cpsDataService; private final CpsQueryService cpsQueryService; @@ -90,7 +89,8 @@ public class CmHandleQueryServiceImpl implements CmHandleQueryService { @Override public Collection<String> queryCmHandleIdsByState(final CmHandleState cmHandleState) { final Collection<DataNode> cmHandlesAsDataNodes = - queryNcmpRegistryByCpsPath("//state[@cm-handle-state='" + cmHandleState + "']", OMIT_DESCENDANTS); + queryNcmpRegistryByCpsPath("//state[@cm-handle-state='" + cmHandleState + "']", + OMIT_DESCENDANTS); return cmHandlesAsDataNodes.stream() .map(DataNode::getXpath) .map(YangDataConverter::extractCmHandleIdFromXpath) @@ -100,13 +100,20 @@ public class CmHandleQueryServiceImpl implements CmHandleQueryService { @Override public Collection<DataNode> queryNcmpRegistryByCpsPath(final String cpsPath, final FetchDescendantsOption fetchDescendantsOption) { + return queryNcmpRegistryByCpsPath(cpsPath, fetchDescendantsOption, NO_LIMIT); + } + + @Override + public Collection<DataNode> queryNcmpRegistryByCpsPath(final String cpsPath, + final FetchDescendantsOption fetchDescendantsOption, + final int queryResultLimit) { return cpsQueryService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, cpsPath, - fetchDescendantsOption); + fetchDescendantsOption, queryResultLimit); } @Override public Collection<DataNode> queryCmHandleAncestorsByCpsPath(final String cpsPath, - final FetchDescendantsOption fetchDescendantsOption) { + final FetchDescendantsOption fetchDescendantsOption) { if (CpsPathUtil.getCpsPathQuery(cpsPath).getXpathPrefix().endsWith("/cm-handles")) { return queryNcmpRegistryByCpsPath(cpsPath, fetchDescendantsOption); } @@ -128,92 +135,51 @@ public class CmHandleQueryServiceImpl implements CmHandleQueryService { @Override public Collection<String> getCmHandleReferencesByDmiPluginIdentifier(final String dmiPluginIdentifier, - final boolean outputAlternateId) { + final boolean outputAlternateId) { final Collection<String> cmHandleReferences = new HashSet<>(); for (final ModelledDmiServiceLeaves modelledDmiServiceLeaf : ModelledDmiServiceLeaves.values()) { - for (final DataNode cmHandleAsDataNode: getCmHandlesByDmiPluginIdentifierAndDmiProperty( - dmiPluginIdentifier, - modelledDmiServiceLeaf.getLeafName())) { - if (outputAlternateId) { - cmHandleReferences.add(cmHandleAsDataNode.getLeaves().get(ALTERNATE_ID).toString()); - } else { - cmHandleReferences.add(cmHandleAsDataNode.getLeaves().get("id").toString()); - } - } + cmHandleReferences.addAll(getIdsByDmiPluginIdentifierAndDmiProperty( + dmiPluginIdentifier, modelledDmiServiceLeaf.getLeafName(), outputAlternateId)); } return cmHandleReferences; } - @Override - public Map<String, String> getCmHandleReferencesMapByDmiPluginIdentifier(final String dmiPluginIdentifier) { - final Map<String, String> cmHandleReferencesMap = new HashMap<>(); - for (final ModelledDmiServiceLeaves modelledDmiServiceLeaf : ModelledDmiServiceLeaves.values()) { - for (final DataNode cmHandleAsDataNode: getCmHandlesByDmiPluginIdentifierAndDmiProperty( - dmiPluginIdentifier, - modelledDmiServiceLeaf.getLeafName())) { - cmHandleReferencesMap.put(cmHandleAsDataNode.getLeaves().get("id").toString(), - cmHandleAsDataNode.getLeaves().get(ALTERNATE_ID).toString()); - } - } - return cmHandleReferencesMap; - } - private Collection<String> getCmHandleReferencesByTrustLevel(final TrustLevel targetTrustLevel, final boolean outputAlternateId) { final Collection<String> selectedCmHandleReferences = new HashSet<>(); - for (final Map.Entry<String, TrustLevel> mapEntry : trustLevelPerDmiPlugin.entrySet()) { final String dmiPluginIdentifier = mapEntry.getKey(); final TrustLevel dmiTrustLevel = mapEntry.getValue(); - final Map<String, String> candidateCmHandleReferences = - getCmHandleReferencesMapByDmiPluginIdentifier(dmiPluginIdentifier); - for (final Map.Entry<String, String> candidateCmHandleReference : candidateCmHandleReferences.entrySet()) { - final TrustLevel candidateCmHandleTrustLevel = - trustLevelPerCmHandleId.get(candidateCmHandleReference.getKey()); + final Collection<String> candidateCmHandleIds = getCmHandleReferencesByDmiPluginIdentifier( + dmiPluginIdentifier, false); + for (final String candidateCmHandleId : candidateCmHandleIds) { + final TrustLevel candidateCmHandleTrustLevel = trustLevelPerCmHandleId.get(candidateCmHandleId); final TrustLevel effectiveTrustlevel = - candidateCmHandleTrustLevel.getEffectiveTrustLevel(dmiTrustLevel); + candidateCmHandleTrustLevel.getEffectiveTrustLevel(dmiTrustLevel); if (targetTrustLevel.equals(effectiveTrustlevel)) { - if (outputAlternateId) { - selectedCmHandleReferences.add(candidateCmHandleReference.getValue()); - } else { - selectedCmHandleReferences.add(candidateCmHandleReference.getKey()); - } + selectedCmHandleReferences.add(candidateCmHandleId); } } } - return selectedCmHandleReferences; - } - - private Collection<String> collectCmHandleReferencesFromDataNodes(final Collection<DataNode> dataNodes, - final boolean outputAlternateId) { if (outputAlternateId) { - return dataNodes.stream().map(dataNode -> - (String) dataNode.getLeaves().get(ALTERNATE_ID)).collect(Collectors.toSet()); - } else { - return dataNodes.stream().map(dataNode -> - (String) dataNode.getLeaves().get("id")).collect(Collectors.toSet()); + return getAlternateIdsByCmHandleIds(selectedCmHandleReferences); } + return selectedCmHandleReferences; } private Collection<String> queryCmHandleAnyProperties( - final Map<String, String> propertyQueryPairs, - final PropertyType propertyType, final boolean outputAlternateId) { + final Map<String, String> propertyQueryPairs, + final PropertyType propertyType, final boolean outputAlternateId) { if (propertyQueryPairs.isEmpty()) { return Collections.emptySet(); } Collection<String> cmHandleReferences = null; for (final Map.Entry<String, String> publicPropertyQueryPair : propertyQueryPairs.entrySet()) { - final String cpsPath = DESCENDANT_PATH + propertyType.getYangContainerName() + "[@name=\"" - + publicPropertyQueryPair.getKey() - + "\" and @value=\"" + publicPropertyQueryPair.getValue() + "\"]"; - - final Collection<DataNode> dataNodes = queryCmHandleAncestorsByCpsPath(cpsPath, - OMIT_DESCENDANTS); + final Collection<String> cmHandleReferencesToRetain = getCmHandleReferencesByProperties(propertyType, + publicPropertyQueryPair.getKey(), publicPropertyQueryPair.getValue(), outputAlternateId); if (cmHandleReferences == null) { - cmHandleReferences = collectCmHandleReferencesFromDataNodes(dataNodes, outputAlternateId); + cmHandleReferences = cmHandleReferencesToRetain; } else { - final Collection<String> cmHandleReferencesToRetain; - cmHandleReferencesToRetain = collectCmHandleReferencesFromDataNodes(dataNodes, outputAlternateId); cmHandleReferences.retainAll(cmHandleReferencesToRetain); } if (cmHandleReferences.isEmpty()) { @@ -223,17 +189,44 @@ public class CmHandleQueryServiceImpl implements CmHandleQueryService { return cmHandleReferences; } - private Collection<DataNode> getCmHandlesByDmiPluginIdentifierAndDmiProperty(final String dmiPluginIdentifier, - final String dmiProperty) { - return cpsQueryService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, - NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@" + dmiProperty + "='" + dmiPluginIdentifier + "']", - OMIT_DESCENDANTS); + private Set<String> getIdsByDmiPluginIdentifierAndDmiProperty(final String dmiPluginIdentifier, + final String dmiProperty, + final boolean outputAlternateId) { + final String attributeName = outputAlternateId ? ALTERNATE_ID : "id"; + final String cpsPath = String.format("%s/cm-handles[@%s='%s']/@%s", + NCMP_DMI_REGISTRY_PARENT, dmiProperty, dmiPluginIdentifier, attributeName); + return cpsQueryService.queryDataLeaf(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, cpsPath, String.class); } + private Collection<String> getAlternateIdsByCmHandleIds(final Collection<String> cmHandleIds) { + + final String cpsPath = NCMP_DMI_REGISTRY_PARENT + "/cm-handles[" + + createFormattedQueryString(cmHandleIds) + "]/@alternate-id"; + + return cpsQueryService.queryDataLeaf(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, cpsPath, String.class); + } + + private Collection<String> getCmHandleReferencesByProperties(final PropertyType propertyType, + final String propertyName, + final String propertyValue, + final boolean outputAlternateId) { + final String attributeName = outputAlternateId ? ALTERNATE_ID : "id"; + final String cpsPath = String.format("//%s[@name='%s' and @value='%s']%s/@%s", + propertyType.getYangContainerName(), propertyName, propertyValue, ANCESTOR_CM_HANDLES, attributeName); + return cpsQueryService.queryDataLeaf(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, cpsPath, String.class); + } + + private String createFormattedQueryString(final Collection<String> cmHandleIds) { + return cmHandleIds.stream() + .map(cmHandleId -> "@id='" + cmHandleId + "'") + .collect(Collectors.joining(" or ")); + } + + private DataNode getCmHandleState(final String cmHandleId) { cpsValidator.validateNameCharacters(cmHandleId); final String xpath = NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='" + cmHandleId + "']/state"; return cpsDataService.getDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, xpath, OMIT_DESCENDANTS).iterator().next(); } -} +}
\ No newline at end of file diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationService.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationService.java index 75c52f3c60..ea8c3ca78d 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationService.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationService.java @@ -71,7 +71,7 @@ import org.springframework.stereotype.Service; @RequiredArgsConstructor public class CmHandleRegistrationService { - private static final int DELETE_BATCH_SIZE = 100; + private static final int DELETE_BATCH_SIZE = 300; private final CmHandleRegistrationServicePropertyHandler cmHandleRegistrationServicePropertyHandler; private final InventoryPersistence inventoryPersistence; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServicePropertyHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServicePropertyHandler.java index 3415793478..7a6cb14d17 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServicePropertyHandler.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServicePropertyHandler.java @@ -22,6 +22,7 @@ package org.onap.cps.ncmp.impl.inventory; +import static org.onap.cps.api.parameters.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS; import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLES_NOT_FOUND; import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_ALREADY_EXIST; import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_INVALID_ID; @@ -88,7 +89,7 @@ public class CmHandleRegistrationServicePropertyHandler { if (!rejectedCmHandleIds.contains(cmHandleId)) { try { final DataNode existingCmHandleDataNode = inventoryPersistence - .getCmHandleDataNodeByCmHandleId(cmHandleId).iterator().next(); + .getCmHandleDataNodeByCmHandleId(cmHandleId, INCLUDE_ALL_DESCENDANTS).iterator().next(); processUpdates(existingCmHandleDataNode, updatedNcmpServiceCmHandle); cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createSuccessResponse(cmHandleId)); } catch (final DataNodeNotFoundException e) { diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistence.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistence.java index b81b5aae70..fb7ad6b116 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistence.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistence.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022-2024 Nordix Foundation + * Copyright (C) 2022-2025 Nordix Foundation * Modifications Copyright (C) 2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,6 +27,7 @@ import java.util.Map; import org.onap.cps.api.model.DataNode; import org.onap.cps.api.model.ModuleDefinition; import org.onap.cps.api.model.ModuleReference; +import org.onap.cps.api.parameters.FetchDescendantsOption; import org.onap.cps.ncmp.api.inventory.models.CompositeState; import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle; @@ -125,9 +126,11 @@ public interface InventoryPersistence extends NcmpPersistence { * Get data node with the given cm handle id. * * @param cmHandleId cmHandle ID + * @param fetchDescendantsOption fetchDescendantsOption * @return data node */ - Collection<DataNode> getCmHandleDataNodeByCmHandleId(String cmHandleId); + Collection<DataNode> getCmHandleDataNodeByCmHandleId(String cmHandleId, + FetchDescendantsOption fetchDescendantsOption); /** * Get yang model cm handle with the given alternate id. diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImpl.java index e145c62921..cf98b31614 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImpl.java @@ -59,7 +59,7 @@ import org.springframework.stereotype.Component; @Component public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements InventoryPersistence { - private static final int CMHANDLE_BATCH_SIZE = 100; + private static final int CMHANDLE_BATCH_SIZE = 300; private final CpsModuleService cpsModuleService; private final CpsValidator cpsValidator; @@ -117,7 +117,8 @@ public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements Inv @Override public YangModelCmHandle getYangModelCmHandle(final String cmHandleId) { cpsValidator.validateNameCharacters(cmHandleId); - final DataNode dataNode = getCmHandleDataNodeByCmHandleId(cmHandleId).iterator().next(); + final DataNode dataNode = + getCmHandleDataNodeByCmHandleId(cmHandleId, INCLUDE_ALL_DESCENDANTS).iterator().next(); return YangDataConverter.toYangModelCmHandle(dataNode); } @@ -144,7 +145,7 @@ public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements Inv final Collection<DataNode> cmHandlesAsDataNodes = cmHandleQueryService.queryNcmpRegistryByCpsPath( - cpsPathForCmHandlesByReferences, INCLUDE_ALL_DESCENDANTS); + cpsPathForCmHandlesByReferences, INCLUDE_ALL_DESCENDANTS, cmHandleReferences.size()); return YangDataConverter.toYangModelCmHandles(cmHandlesAsDataNodes); } @@ -185,15 +186,16 @@ public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements Inv } @Override - public Collection<DataNode> getCmHandleDataNodeByCmHandleId(final String cmHandleId) { - return this.getDataNode(getXPathForCmHandleById(cmHandleId)); + public Collection<DataNode> getCmHandleDataNodeByCmHandleId(final String cmHandleId, + final FetchDescendantsOption fetchDescendantsOption) { + return this.getDataNode(getXPathForCmHandleById(cmHandleId), fetchDescendantsOption); } @Override public YangModelCmHandle getYangModelCmHandleByAlternateId(final String alternateId) { final String cpsPathForCmHandleByAlternateId = getCpsPathForCmHandleByAlternateId(alternateId); final Collection<DataNode> dataNodes = cmHandleQueryService - .queryNcmpRegistryByCpsPath(cpsPathForCmHandleByAlternateId, OMIT_DESCENDANTS); + .queryNcmpRegistryByCpsPath(cpsPathForCmHandleByAlternateId, OMIT_DESCENDANTS, 1); if (dataNodes.isEmpty()) { throw new CmHandleNotFoundException(alternateId); } @@ -207,7 +209,7 @@ public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements Inv } final String cpsPathForCmHandlesByAlternateIds = getCpsPathForCmHandlesByAlternateIds(alternateIds); final Collection<DataNode> dataNodes = cmHandleQueryService.queryNcmpRegistryByCpsPath( - cpsPathForCmHandlesByAlternateIds, INCLUDE_ALL_DESCENDANTS); + cpsPathForCmHandlesByAlternateIds, INCLUDE_ALL_DESCENDANTS, alternateIds.size()); return YangDataConverter.toYangModelCmHandles(dataNodes); } @@ -233,7 +235,7 @@ public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements Inv @Override public boolean isExistingCmHandleId(final String cmHandleId) { try { - return !getCmHandleDataNodeByCmHandleId(cmHandleId).isEmpty(); + return !getCmHandleDataNodeByCmHandleId(cmHandleId, OMIT_DESCENDANTS).isEmpty(); } catch (final DataNodeNotFoundException exception) { return false; } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceImpl.java index 428c6f6491..4c1032efad 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceImpl.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceImpl.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022-2024 Nordix Foundation + * Copyright (C) 2022-2025 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,13 +62,13 @@ public class ParameterizedCmHandleQueryServiceImpl implements ParameterizedCmHan @Override public Collection<String> queryCmHandleReferenceIds( - final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, - final boolean outputAlternateId) { + final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, + final boolean outputAlternateId) { return executeQueries(cmHandleQueryServiceParameters, outputAlternateId, - this::executeCpsPathQuery, - this::queryCmHandlesByPublicProperties, - this::executeModuleNameQuery, - this::queryCmHandlesByTrustLevel); + this::executeCpsPathQuery, + this::queryCmHandlesByPublicProperties, + this::executeModuleNameQuery, + this::queryCmHandlesByTrustLevel); } @Override @@ -84,7 +84,7 @@ public class ParameterizedCmHandleQueryServiceImpl implements ParameterizedCmHan @Override public Collection<NcmpServiceCmHandle> queryCmHandles( - final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) { + final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) { if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) { return getAllCmHandles(); @@ -111,15 +111,11 @@ public class ParameterizedCmHandleQueryServiceImpl implements ParameterizedCmHan } final String dmiPluginIdentifierValue = dmiPropertyQueryPairs - .get(PropertyType.DMI_PLUGIN.getYangContainerName()); + .get(PropertyType.DMI_PLUGIN.getYangContainerName()); + + return cmHandleQueryService.getCmHandleReferencesByDmiPluginIdentifier( + dmiPluginIdentifierValue, outputAlternateId); - if (outputAlternateId) { - return - cmHandleQueryService.getCmHandleReferencesMapByDmiPluginIdentifier(dmiPluginIdentifierValue).values(); - } else { - return cmHandleQueryService.getCmHandleReferencesByDmiPluginIdentifier(dmiPluginIdentifierValue, - outputAlternateId); - } } private Collection<String> queryCmHandlesByPrivateProperties( @@ -175,7 +171,7 @@ public class ParameterizedCmHandleQueryServiceImpl implements ParameterizedCmHan private Collection<String> executeCpsPathQuery( final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, final boolean outputAlternateId) { final Map<String, String> cpsPathCondition - = getCpsPathCondition(cmHandleQueryServiceParameters.getCmHandleQueryParameters()); + = getCpsPathCondition(cmHandleQueryServiceParameters.getCmHandleQueryParameters()); if (!validateCpsPathConditionProperties(cpsPathCondition)) { return Collections.emptySet(); } @@ -185,8 +181,8 @@ public class ParameterizedCmHandleQueryServiceImpl implements ParameterizedCmHan } try { cpsPathQueryResult = collectCmHandleReferencesFromDataNodes( - cmHandleQueryService.queryCmHandleAncestorsByCpsPath(cpsPathCondition.get("cpsPath"), OMIT_DESCENDANTS), - outputAlternateId); + cmHandleQueryService.queryCmHandleAncestorsByCpsPath(cpsPathCondition.get("cpsPath"), + OMIT_DESCENDANTS), outputAlternateId); } catch (final PathParsingException pathParsingException) { throw new DataValidationException(pathParsingException.getMessage(), pathParsingException.getDetails(), pathParsingException); @@ -211,7 +207,7 @@ public class ParameterizedCmHandleQueryServiceImpl implements ParameterizedCmHan } private Map<String, String> getPropertyPairs(final List<ConditionProperties> conditionProperties, - final String queryProperty) { + final String queryProperty) { final Map<String, String> result = new HashMap<>(); getConditions(conditionProperties, queryProperty).forEach(result::putAll); return result; @@ -229,18 +225,18 @@ public class ParameterizedCmHandleQueryServiceImpl implements ParameterizedCmHan private Collection<String> getAllCmHandleReferences(final boolean outputAlternateId) { final DataNode dataNode = inventoryPersistence.getDataNode(NCMP_DMI_REGISTRY_PARENT, DIRECT_CHILDREN_ONLY) - .iterator().next(); + .iterator().next(); return collectCmHandleReferencesFromDataNodes(dataNode.getChildDataNodes(), outputAlternateId); } private Collection<NcmpServiceCmHandle> getNcmpServiceCmHandles(final Collection<String> cmHandleIds) { final Collection<YangModelCmHandle> yangModelcmHandles - = inventoryPersistence.getYangModelCmHandles(cmHandleIds); + = inventoryPersistence.getYangModelCmHandles(cmHandleIds); final Collection<NcmpServiceCmHandle> ncmpServiceCmHandles = new ArrayList<>(yangModelcmHandles.size()); yangModelcmHandles.forEach(yangModelcmHandle -> - ncmpServiceCmHandles.add(YangDataConverter.toNcmpServiceCmHandle(yangModelcmHandle)) + ncmpServiceCmHandles.add(YangDataConverter.toNcmpServiceCmHandle(yangModelcmHandle)) ); return ncmpServiceCmHandles; } @@ -252,15 +248,15 @@ public class ParameterizedCmHandleQueryServiceImpl implements ParameterizedCmHan private Collection<String> executeQueries(final CmHandleQueryServiceParameters cmHandleQueryServiceParameters, final boolean outputAlternateId, final BiFunction<CmHandleQueryServiceParameters, Boolean, - Collection<String>>... queryFunctions) { + Collection<String>>... queryFunctions) { if (cmHandleQueryServiceParameters.getCmHandleQueryParameters().isEmpty()) { return getAllCmHandleReferences(outputAlternateId); } Collection<String> combinedQueryResult = NO_QUERY_TO_EXECUTE; for (final BiFunction<CmHandleQueryServiceParameters, Boolean, - Collection<String>> queryFunction : queryFunctions) { + Collection<String>> queryFunction : queryFunctions) { final Collection<String> queryResult = queryFunction.apply(cmHandleQueryServiceParameters, - outputAlternateId); + outputAlternateId); if (noEntriesFoundCanStopQuerying(queryResult)) { return Collections.emptySet(); } @@ -288,13 +284,13 @@ public class ParameterizedCmHandleQueryServiceImpl implements ParameterizedCmHan } private Collection<String> collectCmHandleReferencesFromDataNodes(final Collection<DataNode> dataNodes, - final boolean outputAlternateId) { + final boolean outputAlternateId) { if (outputAlternateId) { return dataNodes.stream().map(dataNode -> - (String) dataNode.getLeaves().get("alternate-id")).collect(Collectors.toSet()); + (String) dataNode.getLeaves().get("alternate-id")).collect(Collectors.toSet()); } else { return dataNodes.stream().map(dataNode -> - (String) dataNode.getLeaves().get("id")).collect(Collectors.toSet()); + (String) dataNode.getLeaves().get("id")).collect(Collectors.toSet()); } } } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncWatchdog.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncWatchdog.java index 6eefedb633..8c9ec03dd9 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncWatchdog.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/sync/ModuleSyncWatchdog.java @@ -44,7 +44,7 @@ public class ModuleSyncWatchdog { private final ModuleSyncTasks moduleSyncTasks; private final IMap<String, String> cpsAndNcmpLock; - private static final int MODULE_SYNC_BATCH_SIZE = 100; + private static final int MODULE_SYNC_BATCH_SIZE = 300; private static final String VALUE_FOR_HAZELCAST_IN_PROGRESS_MAP = "Started"; /** diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumer.java index efcbb78ace..44befab574 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumer.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/inventory/trustlevel/DeviceTrustLevelMessageConsumer.java @@ -27,11 +27,13 @@ import org.apache.kafka.clients.consumer.ConsumerRecord; import org.onap.cps.ncmp.api.inventory.models.TrustLevel; import org.onap.cps.ncmp.events.trustlevel.DeviceTrustLevel; import org.onap.cps.ncmp.utils.events.CloudEventMapper; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.kafka.annotation.KafkaListener; import org.springframework.stereotype.Component; @Component @RequiredArgsConstructor +@ConditionalOnProperty(name = "notification.enabled", havingValue = "true", matchIfMissing = true) public class DeviceTrustLevelMessageConsumer { private static final String CLOUD_EVENT_ID_HEADER_NAME = "ce_id"; diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/AlternateIdMatcher.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/AlternateIdMatcher.java index b97da2977a..750a5050f2 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/AlternateIdMatcher.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/utils/AlternateIdMatcher.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2024 Nordix Foundation + * Copyright (C) 2024-2025 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import org.onap.cps.ncmp.api.exceptions.CmHandleNotFoundException; import org.onap.cps.ncmp.exceptions.NoAlternateIdMatchFoundException; import org.onap.cps.ncmp.impl.inventory.InventoryPersistence; import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle; +import org.onap.cps.utils.CpsValidator; import org.springframework.stereotype.Service; @Service @@ -33,6 +34,7 @@ import org.springframework.stereotype.Service; public class AlternateIdMatcher { private final InventoryPersistence inventoryPersistence; + private final CpsValidator cpsValidator; /** * Get yang model cm handle that matches longest alternate id by removing elements @@ -64,11 +66,22 @@ public class AlternateIdMatcher { * @return cm handle id string */ public String getCmHandleId(final String cmHandleReference) { + if (cpsValidator.isValidName(cmHandleReference)) { + return getCmHandleIdTryingStandardIdFirst(cmHandleReference); + } + return getCmHandleIdByAlternateId(cmHandleReference); + } + + private String getCmHandleIdByAlternateId(final String cmHandleReference) { + // Please note: because of cm handle id validation rules this case does NOT need to try by (standard) id + return inventoryPersistence.getYangModelCmHandleByAlternateId(cmHandleReference).getId(); + } + + private String getCmHandleIdTryingStandardIdFirst(final String cmHandleReference) { if (inventoryPersistence.isExistingCmHandleId(cmHandleReference)) { return cmHandleReference; - } else { - return inventoryPersistence.getYangModelCmHandleByAlternateId(cmHandleReference).getId(); } + return inventoryPersistence.getYangModelCmHandleByAlternateId(cmHandleReference).getId(); } private String getParentPath(final String path, final String separator) { diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/CmAvcEventPublisher.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/CmAvcEventPublisher.java index bdc7899724..2bb35864d3 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/CmAvcEventPublisher.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/CmAvcEventPublisher.java @@ -20,6 +20,8 @@ package org.onap.cps.ncmp.utils.events; +import static org.onap.cps.ncmp.events.NcmpEventDataSchema.INVENTORY_EVENTS_V1; + import io.cloudevents.CloudEvent; import java.util.Collections; import java.util.HashMap; @@ -51,9 +53,13 @@ public class CmAvcEventPublisher { final AvcEvent avcEvent = buildAvcEvent(attributeName, oldAttributeValue, newAttributeValue); final Map<String, String> extensions = createAvcEventExtensions(eventKey); - final CloudEvent avcCloudEvent = - NcmpEvent.builder().type(AvcEvent.class.getTypeName()) - .data(avcEvent).extensions(extensions).build().asCloudEvent(); + final CloudEvent avcCloudEvent = NcmpEvent.builder() + .type(AvcEvent.class.getTypeName()) + .dataSchema(INVENTORY_EVENTS_V1.getDataSchema()) + .data(avcEvent) + .extensions(extensions) + .build() + .asCloudEvent(); eventsPublisher.publishCloudEvent(ncmpInventoryEventsTopicName, eventKey, avcCloudEvent); } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/NcmpEvent.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/NcmpEvent.java index 8d3190eb00..6db962c068 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/NcmpEvent.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/utils/events/NcmpEvent.java @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2023-2024 Nordix Foundation + * Copyright (C) 2023-2025 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,12 +34,11 @@ import org.onap.cps.utils.JsonObjectMapper; @Builder public class NcmpEvent { + private String dataSchema; private Object data; private Map<String, String> extensions; private String type; @Builder.Default - private static final String CLOUD_EVENT_SPEC_VERSION_V1 = "1.0.0"; - @Builder.Default private static final String CLOUD_EVENT_SOURCE = "NCMP"; /** @@ -53,7 +52,7 @@ public class NcmpEvent { .withId(UUID.randomUUID().toString()) .withSource(URI.create(CLOUD_EVENT_SOURCE)) .withType(type) - .withDataSchema(URI.create("urn:cps:" + type + ":" + CLOUD_EVENT_SPEC_VERSION_V1)) + .withDataSchema(URI.create(dataSchema)) .withTime(EventDateTimeFormatter.toIsoOffsetDateTime( EventDateTimeFormatter.getCurrentIsoFormattedDateTime())) .withData(jsonObjectMapper.asJsonBytes(data)); diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiInEventProducerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiInEventProducerSpec.groovy index 34fa4549f5..3bf4c2c160 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiInEventProducerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/dmi/DmiInEventProducerSpec.groovy @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (c) 2024 Nordix Foundation. + * Copyright (c) 2024-2025 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,19 +23,23 @@ package org.onap.cps.ncmp.impl.cmnotificationsubscription.dmi import com.fasterxml.jackson.databind.ObjectMapper import io.cloudevents.CloudEvent import org.onap.cps.events.EventsPublisher +import org.onap.cps.ncmp.config.CpsApplicationContext import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_dmi.CmHandle import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_dmi.Data import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_dmi.DmiInEvent import org.onap.cps.ncmp.utils.events.CloudEventMapper import org.onap.cps.utils.JsonObjectMapper +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.test.context.ContextConfiguration import spock.lang.Specification +@SpringBootTest(classes = [ObjectMapper, JsonObjectMapper]) +@ContextConfiguration(classes = [CpsApplicationContext]) class DmiInEventProducerSpec extends Specification { def mockEventsPublisher = Mock(EventsPublisher) - def jsonObjectMapper = new JsonObjectMapper(new ObjectMapper()) - def objectUnderTest = new DmiInEventProducer(mockEventsPublisher, jsonObjectMapper) + def objectUnderTest = new DmiInEventProducer(mockEventsPublisher) def 'Create and Publish Cm Notification Subscription DMI In Event'() { given: 'a cm subscription for a dmi plugin' diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventProducerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventProducerSpec.groovy index afa2e9874e..fde7e182d0 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventProducerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/cmnotificationsubscription/ncmp/NcmpOutEventProducerSpec.groovy @@ -1,23 +1,47 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2025 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + package org.onap.cps.ncmp.impl.cmnotificationsubscription.ncmp import com.fasterxml.jackson.databind.ObjectMapper import io.cloudevents.CloudEvent import org.onap.cps.events.EventsPublisher +import org.onap.cps.ncmp.config.CpsApplicationContext import org.onap.cps.ncmp.impl.cmnotificationsubscription.cache.DmiCacheHandler import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_client.Data import org.onap.cps.ncmp.impl.cmnotificationsubscription_1_0_0.ncmp_to_client.NcmpOutEvent import org.onap.cps.ncmp.utils.events.CloudEventMapper import org.onap.cps.utils.JsonObjectMapper +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.test.context.ContextConfiguration import spock.lang.Specification +@SpringBootTest(classes = [ObjectMapper, JsonObjectMapper]) +@ContextConfiguration(classes = [CpsApplicationContext]) class NcmpOutEventProducerSpec extends Specification { def mockEventsPublisher = Mock(EventsPublisher) - def jsonObjectMapper = new JsonObjectMapper(new ObjectMapper()) def mockNcmpOutEventMapper = Mock(NcmpOutEventMapper) def mockDmiCacheHandler = Mock(DmiCacheHandler) - def objectUnderTest = new NcmpOutEventProducer(mockEventsPublisher, jsonObjectMapper, mockNcmpOutEventMapper, mockDmiCacheHandler) + def objectUnderTest = new NcmpOutEventProducer(mockEventsPublisher, mockNcmpOutEventMapper, mockDmiCacheHandler) def 'Create and #scenario Cm Notification Subscription NCMP out event'() { given: 'a cm subscription response for the client' @@ -102,5 +126,4 @@ class NcmpOutEventProducerSpec extends Specification { 0 * mockEventsPublisher.publishCloudEvent(*_) } - } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/DmiDataOperationsSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/DmiDataOperationsSpec.groovy index 01a08e7bb5..3dd2eabe21 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/DmiDataOperationsSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/DmiDataOperationsSpec.groovy @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2021-2024 Nordix Foundation + * Copyright (C) 2021-2025 Nordix Foundation * Modifications Copyright (C) 2022 Bell Canada * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,8 +22,6 @@ package org.onap.cps.ncmp.impl.data import com.fasterxml.jackson.databind.ObjectMapper -import org.onap.cps.api.exceptions.DataNodeNotFoundException -import org.onap.cps.api.exceptions.DataValidationException import org.onap.cps.events.EventsPublisher import org.onap.cps.ncmp.api.data.models.CmResourceAddress import org.onap.cps.ncmp.api.data.models.DataOperationRequest @@ -86,6 +84,7 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec { def 'call get resource data for #expectedDataStore from DMI without topic #scenario.'() { given: 'a cm handle for #cmHandleId' + alternateIdMatcher.getCmHandleId(cmHandleId) >> cmHandleId mockYangModelCmHandleRetrieval(dmiProperties) and: 'a positive response from DMI service when it is called with the expected parameters' def responseFromDmi = Mono.just(new ResponseEntity<Object>('{some-key:some-value}', HttpStatus.OK)) @@ -206,33 +205,6 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec { CmHandleState.ADVISED || true } - def 'Resolving cm handle references with cm handle id.'() { - given: 'a resource address with a cm handle id' - def cmResourceAddress = new CmResourceAddress('some store', 'cm-handle-id', 'some resource') - and: 'the given cm handle id is available in the inventory' - mockInventoryPersistence.getYangModelCmHandle('cm-handle-id') >> yangModelCmHandle - expect: 'resolving the cm handle id returns the cm handle' - assert objectUnderTest.resolveYangModelCmHandleFromCmHandleReference(cmResourceAddress) == yangModelCmHandle - } - - def 'Resolving cm handle references with alternate id #scenario.'() { - given: 'a resource with a alternate id' - def cmResourceAddress = new CmResourceAddress('some store', alternateId, 'some resource') - and: 'the alternate id cannot be found in the inventory directly and that results in an exception' - mockInventoryPersistence.getYangModelCmHandle(alternateId) >> { throw errorThrownDuringCmHandleIdSearch } - and: 'the alternate id can be matched to a cm handle id' - alternateIdMatcher.getCmHandleId(alternateId) >> 'cm-handle-id' - and: 'that cm handle id is available in the inventory' - mockInventoryPersistence.getYangModelCmHandle('cm-handle-id') >> yangModelCmHandle - expect: 'resolving that cm handle id returns the cm handle' - assert objectUnderTest.resolveYangModelCmHandleFromCmHandleReference(cmResourceAddress) == yangModelCmHandle - where: 'the following alternate ids are used' - scenario | alternateId | errorThrownDuringCmHandleIdSearch - 'alternate id with no special characters' | 'alternate-id' | new DataNodeNotFoundException('','') - 'alternate id with special characters' | 'alternate#id' | new DataValidationException('','') - } - - def extractDataValue(actualDataOperationCloudEvent) { return toTargetEvent(actualDataOperationCloudEvent, DataOperationEvent).data.responses[0] } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImplSpec.groovy index 1cbdc7beca..6ac42db782 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImplSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleQueryServiceImplSpec.groovy @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022-2024 Nordix Foundation + * Copyright (C) 2022-2025 Nordix Foundation * Modifications Copyright (C) 2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -51,7 +51,7 @@ class CmHandleQueryServiceImplSpec extends Specification { def static sampleDataNodes = [new DataNode(xpath: "/dmi-registry/cm-handles[@id='ch-1']"), new DataNode(xpath: "/dmi-registry/cm-handles[@id='ch-2']")] - def dataNodeWithPrivateField = '//additional-properties[@name=\"Contact3\" and @value=\"newemailforstore3@bookstore.com\"]/ancestor::cm-handles' + def cpsPathWithPrivateField = '//additional-properties[@name=\'Contact3\' and @value=\'newemailforstore3@bookstore.com\']/ancestor::cm-handles/@id' def static pnfDemo = createDataNode('PNFDemo') def static pnfDemo2 = createDataNode('PNFDemo2') @@ -86,21 +86,21 @@ class CmHandleQueryServiceImplSpec extends Specification { } def 'Query cm handles on trust level'() { - given: 'query properties for trust level COMPLETE' - def trustLevelPropertyQueryPairs = ['trustLevel' : TrustLevel.COMPLETE.toString()] + given: 'query properties for #trustLevel' + def trustLevelPropertyQueryPairs = ['trustLevel' : trustLevel.toString()] and: 'the dmi cache has been initialised and "knows" about my-dmi-plugin-identifier' - trustLevelPerDmiPlugin.put('my-dmi-plugin-identifier', TrustLevel.COMPLETE) + trustLevelPerDmiPlugin.put('my-dmi-plugin-identifier', trustLevel) and: 'the DataNodes queried for a given cpsPath are returned from the persistence service' mockResponses() when: 'the query is run' def result = objectUnderTest.queryCmHandlesByTrustLevel(trustLevelPropertyQueryPairs, outputAlternateId) then: 'the result contain trusted cmHandle reference' - assert result.size() == 1 - assert result[0] == expectedCmHandleReference + assert result as Set == expectedCmHandleReference as Set where: 'the following data is used' - senario | outputAlternateId | expectedCmHandleReference - 'output cmHandleId' | false | 'PNFDemo' - 'output AlternateId' | true | 'alt-PNFDemo' + senario | outputAlternateId | expectedCmHandleReference | trustLevel || resultSize + 'output cmHandleId for trustLevel Complete' | false | ['PNFDemo'] | TrustLevel.COMPLETE || 1 + 'output alternateId for trustLevel Complete'| true | ['alt-PNFDemo'] | TrustLevel.COMPLETE || 1 + 'output alternateIds for trustLevel None' | true | ['alt-PNFDemo2', 'alt-PNFDemo', 'alt-PNFDemo4']| TrustLevel.NONE || 3 } def 'Query CmHandles using empty public properties query pair.'() { @@ -119,7 +119,7 @@ class CmHandleQueryServiceImplSpec extends Specification { def 'Query CmHandles by a private field\'s value.'() { given: 'a data node exists with a certain additional-property' - mockCpsQueryService.queryDataNodes(_, _, dataNodeWithPrivateField, _) >> [pnfDemo5] + mockCpsQueryService.queryDataLeaf(_, _, cpsPathWithPrivateField, _) >> [pnfDemo5.getLeaves().get('id')] when: 'a query on CmHandle private properties is executed using a map' def result = objectUnderTest.queryCmHandleAdditionalProperties(['Contact3': 'newemailforstore3@bookstore.com'], false) then: 'one cm handle is returned' @@ -131,7 +131,7 @@ class CmHandleQueryServiceImplSpec extends Specification { def cmHandleState = CmHandleState.ADVISED and: 'the persistence service returns a list of data nodes' mockCpsQueryService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, - "//state[@cm-handle-state='ADVISED']", OMIT_DESCENDANTS) >> sampleDataNodes + "//state[@cm-handle-state='ADVISED']", OMIT_DESCENDANTS, 0) >> sampleDataNodes when: 'cm handles are fetched by state' def result = objectUnderTest.queryCmHandleIdsByState(cmHandleState) then: 'the returned result matches the result from the persistence service' @@ -143,8 +143,8 @@ class CmHandleQueryServiceImplSpec extends Specification { def cmHandleState = state and: 'the persistence service returns a list of data nodes' mockCpsDataService.getDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, - NCMP_DMI_REGISTRY_PARENT + '/cm-handles[@id=\'some-cm-handle\']/state', - OMIT_DESCENDANTS) >> [new DataNode(leaves: ['cm-handle-state': 'READY'])] + NCMP_DMI_REGISTRY_PARENT + '/cm-handles[@id=\'some-cm-handle\']/state', + OMIT_DESCENDANTS) >> [new DataNode(leaves: ['cm-handle-state': 'READY'])] when: 'cm handles are compared by state' def result = objectUnderTest.cmHandleHasState('some-cm-handle', cmHandleState) then: 'the returned result matches the expected result from the persistence service' @@ -160,8 +160,8 @@ class CmHandleQueryServiceImplSpec extends Specification { def cmHandleState = CmHandleState.READY and: 'cps data service returns a list of data nodes' mockCpsDataService.getDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, - NCMP_DMI_REGISTRY_PARENT + '/cm-handles[@id=\'some-cm-handle\']/state', - OMIT_DESCENDANTS) >> [new DataNode(leaves: ['cm-handle-state': 'READY'])] + NCMP_DMI_REGISTRY_PARENT + '/cm-handles[@id=\'some-cm-handle\']/state', + OMIT_DESCENDANTS) >> [new DataNode(leaves: ['cm-handle-state': 'READY'])] when: 'cm handles are fetched by state and id' def result = objectUnderTest.getCmHandleState('some-cm-handle') then: 'the returned result is a list of data nodes returned by cps data service' @@ -169,11 +169,9 @@ class CmHandleQueryServiceImplSpec extends Specification { } def 'Retrieve Cm Handles By Operational Sync State : UNSYNCHRONIZED'() { - given: 'a cm handle state to query' - def cmHandleState = CmHandleState.READY - and: 'cps data service returns a list of data nodes' + given: 'cps data service returns a list of data nodes' mockCpsQueryService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, - '//state/datastores/operational[@sync-state="'+'UNSYNCHRONIZED'+'"]/ancestor::cm-handles', OMIT_DESCENDANTS) >> sampleDataNodes + '//state/datastores/operational[@sync-state="'+'UNSYNCHRONIZED'+'"]/ancestor::cm-handles', OMIT_DESCENDANTS, 0) >> sampleDataNodes when: 'cm handles are fetched by the UNSYNCHRONIZED operational sync state' def result = objectUnderTest.queryCmHandlesByOperationalSyncState(DataStoreSyncState.UNSYNCHRONIZED) then: 'the returned result is a list of data nodes returned by cps data service' @@ -186,7 +184,7 @@ class CmHandleQueryServiceImplSpec extends Specification { def cpsPath = "//state[@cm-handle-state='LOCKED']" and: 'cps data service returns a valid data node for cm handle ancestor' mockCpsQueryService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, - cpsPath + '/ancestor::cm-handles', INCLUDE_ALL_DESCENDANTS) + cpsPath + '/ancestor::cm-handles', INCLUDE_ALL_DESCENDANTS, 0) >> Arrays.asList(cmHandleDataNode) when: 'get cm handles by cps path is invoked' def result = objectUnderTest.queryCmHandleAncestorsByCpsPath(cpsPath, INCLUDE_ALL_DESCENDANTS) @@ -200,8 +198,8 @@ class CmHandleQueryServiceImplSpec extends Specification { def cpsPath = "//cm-handles[@alternate-id='1']" and: 'cps data service returns a valid data node' mockCpsQueryService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, - cpsPath, INCLUDE_ALL_DESCENDANTS) - >> Arrays.asList(cmHandleDataNode) + cpsPath, INCLUDE_ALL_DESCENDANTS, 0) + >> Arrays.asList(cmHandleDataNode) when: 'get cm handles by cps path is invoked' def result = objectUnderTest.queryCmHandleAncestorsByCpsPath(cpsPath, INCLUDE_ALL_DESCENDANTS) then: 'the returned result is a list of data nodes returned by cps data service' @@ -223,18 +221,8 @@ class CmHandleQueryServiceImplSpec extends Specification { 'output is for cm handle ids' | false || ['PNFDemo', 'PNFDemo2', 'PNFDemo4'] } - def 'Get all alternateIds by dmi plugin identifier'() { - given: 'the DataNodes queried for a given cpsPath are returned from the persistence service.' - mockResponses() - when: 'cm Handles are fetched for a given dmi plugin identifier' - def result = objectUnderTest.getCmHandleReferencesMapByDmiPluginIdentifier('my-dmi-plugin-identifier').values() - then: 'result is the correct size' - assert result.size() == 3 - and: 'result contains the correct alternate Ids' - assert result.containsAll('alt-PNFDemo', 'alt-PNFDemo2', 'alt-PNFDemo4') - } - void mockResponses() { + mockCpsQueryService.queryDataNodes(_, _, '//public-properties[@name=\"Contact\" and @value=\"newemailforstore@bookstore.com\"]/ancestor::cm-handles', _) >> [pnfDemo, pnfDemo2, pnfDemo4] mockCpsQueryService.queryDataNodes(_, _, '//public-properties[@name=\"wont_match\" and @value=\"wont_match\"]/ancestor::cm-handles', _) >> [] mockCpsQueryService.queryDataNodes(_, _, '//public-properties[@name=\"Contact2\" and @value=\"newemailforstore2@bookstore.com\"]/ancestor::cm-handles', _) >> [pnfDemo4] @@ -244,6 +232,23 @@ class CmHandleQueryServiceImplSpec extends Specification { mockCpsQueryService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, '/dmi-registry/cm-handles[@dmi-service-name=\'my-dmi-plugin-identifier\']', OMIT_DESCENDANTS) >> [pnfDemo, pnfDemo2] mockCpsQueryService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, '/dmi-registry/cm-handles[@dmi-data-service-name=\'my-dmi-plugin-identifier\']', OMIT_DESCENDANTS) >> [pnfDemo, pnfDemo4] mockCpsQueryService.queryDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, '/dmi-registry/cm-handles[@dmi-model-service-name=\'my-dmi-plugin-identifier\']', OMIT_DESCENDANTS) >> [pnfDemo2, pnfDemo4] + + mockCpsQueryService.queryDataLeaf(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, '/dmi-registry/cm-handles[@dmi-service-name=\'my-dmi-plugin-identifier\']/@id', _) >> [pnfDemo.getLeaves().get('id'), pnfDemo2.getLeaves().get('id')] + mockCpsQueryService.queryDataLeaf(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, '/dmi-registry/cm-handles[@dmi-data-service-name=\'my-dmi-plugin-identifier\']/@id', _) >> [pnfDemo.getLeaves().get('id'), pnfDemo4.getLeaves().get('id')] + mockCpsQueryService.queryDataLeaf(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, '/dmi-registry/cm-handles[@dmi-model-service-name=\'my-dmi-plugin-identifier\']/@id', _) >> [pnfDemo2.getLeaves().get('id'), pnfDemo4.getLeaves().get('id')] + + mockCpsQueryService.queryDataLeaf(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, '/dmi-registry/cm-handles[@dmi-service-name=\'my-dmi-plugin-identifier\']/@alternate-id', _) >> [pnfDemo.getLeaves().get('alternate-id'), pnfDemo2.getLeaves().get('alternate-id')] + mockCpsQueryService.queryDataLeaf(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, '/dmi-registry/cm-handles[@dmi-data-service-name=\'my-dmi-plugin-identifier\']/@alternate-id', _) >> [pnfDemo.getLeaves().get('alternate-id'), pnfDemo4.getLeaves().get('alternate-id')] + mockCpsQueryService.queryDataLeaf(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, '/dmi-registry/cm-handles[@dmi-model-service-name=\'my-dmi-plugin-identifier\']/@alternate-id', _) >> [pnfDemo2.getLeaves().get('alternate-id'), pnfDemo4.getLeaves().get('alternate-id')] + mockCpsQueryService.queryDataLeaf(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, '/dmi-registry/cm-handles[@id=\'PNFDemo\']/@alternate-id', _) >> [pnfDemo.getLeaves().get('alternate-id')] + mockCpsQueryService.queryDataLeaf(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, '/dmi-registry/cm-handles[@id=\'PNFDemo2\' or @id=\'PNFDemo\' or @id=\'PNFDemo4\']/@alternate-id', _) >> [pnfDemo2.getLeaves().get('alternate-id'), pnfDemo.getLeaves().get('alternate-id'), pnfDemo4.getLeaves().get('alternate-id')] + + mockCpsQueryService.queryDataLeaf(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, '//public-properties[@name=\'Contact\' and @value=\'newemailforstore@bookstore.com\']/ancestor::cm-handles/@id',_) >> [pnfDemo.getLeaves().get('id'), pnfDemo2.getLeaves().get('id'), pnfDemo4.getLeaves().get('id')] + mockCpsQueryService.queryDataLeaf(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, '//public-properties[@name=\'Contact\' and @value=\'newemailforstore@bookstore.com\']/ancestor::cm-handles/@alternate-id',_) >> [pnfDemo.getLeaves().get('alternate-id'), pnfDemo2.getLeaves().get('alternate-id'), pnfDemo4.getLeaves().get('alternate-id')] + mockCpsQueryService.queryDataLeaf(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,'//public-properties[@name=\'Contact2\' and @value=\'newemailforstore2@bookstore.com\']/ancestor::cm-handles/@alternate-id', _) >> [pnfDemo4.getLeaves().get('alternate-id')] + mockCpsQueryService.queryDataLeaf(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,'//public-properties[@name=\'Contact2\' and @value=\'newemailforstore2@bookstore.com\']/ancestor::cm-handles/@id', _) >> [pnfDemo4.getLeaves().get('id')] + mockCpsQueryService.queryDataLeaf(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,'//public-properties[@name=\'Contact2\' and @value=\'\']/ancestor::cm-handles/@id', _) >> [] + mockCpsQueryService.queryDataLeaf(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, '//public-properties[@name=\'wont_match\' and @value=\'wont_match\']/ancestor::cm-handles/@id', _) >> [] } def static createDataNode(dataNodeId) { diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServicePropertyHandlerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServicePropertyHandlerSpec.groovy index 70bd418026..31610edec5 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServicePropertyHandlerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/CmHandleRegistrationServicePropertyHandlerSpec.groovy @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022-2024 Nordix Foundation + * Copyright (C) 2022-2025 Nordix Foundation * Modifications Copyright (C) 2022 Bell Canada * Modifications Copyright (C) 2024 TechMahindra Ltd. * ================================================================================ @@ -38,6 +38,7 @@ import org.onap.cps.utils.JsonObjectMapper import org.slf4j.LoggerFactory import spock.lang.Specification +import static org.onap.cps.api.parameters.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS 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.NcmpResponseStatus.UNKNOWN_ERROR @@ -79,7 +80,7 @@ class CmHandleRegistrationServicePropertyHandlerSpec extends Specification { def 'Update CM Handle Public Properties: #scenario'() { given: 'the CPS service return a CM handle' - mockInventoryPersistence.getCmHandleDataNodeByCmHandleId(cmHandleId) >> cmHandleDataNodeAsCollection + mockInventoryPersistence.getCmHandleDataNodeByCmHandleId(cmHandleId, INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNodeAsCollection and: 'an update cm handle request with public properties updates' def cmHandleUpdateRequest = [new NcmpServiceCmHandle(cmHandleId: cmHandleId, publicProperties: updatedPublicProperties)] when: 'update data node leaves is called with the update request' @@ -101,7 +102,7 @@ class CmHandleRegistrationServicePropertyHandlerSpec extends Specification { def 'Update DMI Properties: #scenario'() { given: 'the CPS service return a CM handle' - mockInventoryPersistence.getCmHandleDataNodeByCmHandleId(cmHandleId) >> cmHandleDataNodeAsCollection + mockInventoryPersistence.getCmHandleDataNodeByCmHandleId(cmHandleId, INCLUDE_ALL_DESCENDANTS) >> cmHandleDataNodeAsCollection and: 'an update cm handle request with DMI properties updates' def cmHandleUpdateRequest = [new NcmpServiceCmHandle(cmHandleId: cmHandleId, dmiProperties: updatedDmiProperties)] when: 'update data node leaves is called with the update request' @@ -125,7 +126,7 @@ class CmHandleRegistrationServicePropertyHandlerSpec extends Specification { def 'Update CM Handle Properties, remove all properties: #scenario'() { given: 'the CPS service return a CM handle' def cmHandleDataNode = new DataNode(xpath: cmHandleXpath, leaves: ['id': cmHandleId], childDataNodes: originalPropertyDataNodes) - mockInventoryPersistence.getCmHandleDataNodeByCmHandleId(cmHandleId) >> [cmHandleDataNode] + mockInventoryPersistence.getCmHandleDataNodeByCmHandleId(cmHandleId, INCLUDE_ALL_DESCENDANTS) >> [cmHandleDataNode] and: 'an update cm handle request that removes all public properties(existing and non-existing)' def cmHandleUpdateRequest = [new NcmpServiceCmHandle(cmHandleId: cmHandleId, publicProperties: ['publicProp3': null, 'publicProp4': null])] when: 'update data node leaves is called with the update request' @@ -204,7 +205,7 @@ class CmHandleRegistrationServicePropertyHandlerSpec extends Specification { def cmHandleUpdateRequest = [new NcmpServiceCmHandle(cmHandleId: cmHandleId, alternateId: 'alt-1')] and: 'a data node found' def dataNode = new DataNode(xpath: cmHandleXpath, leaves: ['id': cmHandleId, 'alternate-id': 'alt-1']) - mockInventoryPersistence.getCmHandleDataNodeByCmHandleId(cmHandleId) >> [dataNode] + mockInventoryPersistence.getCmHandleDataNodeByCmHandleId(cmHandleId, INCLUDE_ALL_DESCENDANTS) >> [dataNode] when: 'cm handle properties is updated' def response = objectUnderTest.updateCmHandleProperties(cmHandleUpdateRequest) then: 'the update is delegated to cps data service with correct parameters' @@ -224,7 +225,7 @@ class CmHandleRegistrationServicePropertyHandlerSpec extends Specification { def updatedNcmpServiceCmHandles = [new NcmpServiceCmHandle(cmHandleId: cmHandleId, alternateId: 'alt-1')] and: 'a data node found' def dataNode = new DataNode(xpath: cmHandleXpath, leaves: ['id': cmHandleId, 'alternate-id': 'alt-1']) - mockInventoryPersistence.getCmHandleDataNodeByCmHandleId(cmHandleId) >> [dataNode] + mockInventoryPersistence.getCmHandleDataNodeByCmHandleId(cmHandleId, INCLUDE_ALL_DESCENDANTS) >> [dataNode] when: 'attempt to update the cm handle' def response = objectUnderTest.updateCmHandleProperties(updatedNcmpServiceCmHandles) then: 'the update is NOT delegated to cps data service' diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImplSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImplSpec.groovy index 0ed9dd8aae..5619c5ac57 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImplSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/InventoryPersistenceImplSpec.groovy @@ -34,7 +34,6 @@ import org.onap.cps.api.exceptions.DataValidationException import org.onap.cps.api.model.DataNode import org.onap.cps.api.model.ModuleDefinition import org.onap.cps.api.model.ModuleReference -import org.onap.cps.api.parameters.FetchDescendantsOption import org.onap.cps.utils.CpsValidator import org.onap.cps.ncmp.api.exceptions.CmHandleNotFoundException import org.onap.cps.ncmp.api.inventory.models.CompositeState @@ -165,7 +164,7 @@ class InventoryPersistenceImplSpec extends Specification { def "Retrieve multiple YangModelCmHandles using cm handle references"() { given: 'the cps data service returns 2 data nodes from the DMI registry' def dataNodes = [new DataNode(xpath: xpath, leaves: ['id': cmHandleId, 'alternate-id':alternateId]), new DataNode(xpath: xpath2, leaves: ['id': cmHandleId2,'alternate-id':alternateId2])] - mockCmHandleQueries.queryNcmpRegistryByCpsPath(_, INCLUDE_ALL_DESCENDANTS) >> dataNodes + mockCmHandleQueries.queryNcmpRegistryByCpsPath(_, INCLUDE_ALL_DESCENDANTS, _) >> dataNodes when: 'retrieving the yang modelled cm handle' def results = objectUnderTest.getYangModelCmHandlesFromCmHandleReferences([cmHandleId, cmHandleId2]) then: 'verify both have returned and cmhandleIds are correct' @@ -179,7 +178,7 @@ class InventoryPersistenceImplSpec extends Specification { def dataNode = new DataNode(leaves: ['cm-handle-state': 'ADVISED']) and: 'cps data service returns a valid data node' mockCpsDataService.getDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, - '/dmi-registry/cm-handles[@id=\'Some-Cm-Handle\']/state', FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS) >> [dataNode] + '/dmi-registry/cm-handles[@id=\'Some-Cm-Handle\']/state', INCLUDE_ALL_DESCENDANTS) >> [dataNode] when: 'get cm handle state is invoked' def result = objectUnderTest.getCmHandleState(cmHandleId) then: 'result has returned the correct cm handle state' @@ -302,7 +301,7 @@ class InventoryPersistenceImplSpec extends Specification { given: 'expected xPath to get cmHandle data node' def expectedXPath = '/dmi-registry/cm-handles[@id=\'sample cmHandleId\']' when: 'the method to get data nodes is called' - objectUnderTest.getCmHandleDataNodeByCmHandleId('sample cmHandleId') + objectUnderTest.getCmHandleDataNodeByCmHandleId('sample cmHandleId', INCLUDE_ALL_DESCENDANTS) then: 'the data persistence service method to get cmHandle data node is invoked once with expected xPath' 1 * mockCpsDataService.getDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, expectedXPath, INCLUDE_ALL_DESCENDANTS) } @@ -312,7 +311,7 @@ class InventoryPersistenceImplSpec extends Specification { def expectedXPath = '/dmi-registry/cm-handles[@alternate-id=\'alternate id\']' def expectedDataNode = new DataNode(xpath: expectedXPath, leaves: [id: 'id', alternateId: 'alternate id']) and: 'query service is invoked with expected xpath' - mockCmHandleQueries.queryNcmpRegistryByCpsPath(expectedXPath, OMIT_DESCENDANTS) >> [expectedDataNode] + mockCmHandleQueries.queryNcmpRegistryByCpsPath(expectedXPath, OMIT_DESCENDANTS, _) >> [expectedDataNode] mockYangDataConverter.toYangModelCmHandle(expectedDataNode) >> new YangModelCmHandle(id: 'id') expect: 'getting the yang model cm handle' assert objectUnderTest.getYangModelCmHandleByAlternateId('alternate id') == new YangModelCmHandle(id: 'id') @@ -382,21 +381,21 @@ class InventoryPersistenceImplSpec extends Specification { def 'CM handle exists'() { given: 'data service returns a datanode with correct cm handle id' - mockCpsDataService.getDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, xpath, INCLUDE_ALL_DESCENDANTS) >> [dataNode] + mockCpsDataService.getDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, xpath, OMIT_DESCENDANTS) >> [dataNode] expect: 'cm handle exists for given cm handle id' assert true == objectUnderTest.isExistingCmHandleId(cmHandleId) } def 'CM handle does not exist, empty dataNode collection returned'() { given: 'data service returns an empty datanode' - mockCpsDataService.getDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, xpath, INCLUDE_ALL_DESCENDANTS) >> [] + mockCpsDataService.getDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, xpath, OMIT_DESCENDANTS) >> [] expect: 'false is returned for non-existent cm handle' assert false == objectUnderTest.isExistingCmHandleId(cmHandleId) } def 'CM handle does not exist, exception thrown'() { given: 'data service throws an exception' - mockCpsDataService.getDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, "/dmi-registry/cm-handles[@id='non-existent-cm-handle']", INCLUDE_ALL_DESCENDANTS) >> {throw new DataNodeNotFoundException('','')} + mockCpsDataService.getDataNodes(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, "/dmi-registry/cm-handles[@id='non-existent-cm-handle']", OMIT_DESCENDANTS) >> {throw new DataNodeNotFoundException('','')} expect: 'false is returned for non-existent cm handle' assert false == objectUnderTest.isExistingCmHandleId('non-existent-cm-handle') } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceSpec.groovy index bf6ea36d65..7ba2bdf1e3 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/inventory/ParameterizedCmHandleQueryServiceSpec.groovy @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2022-2024 Nordix Foundation + * Copyright (C) 2022-2025 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -206,7 +206,7 @@ class ParameterizedCmHandleQueryServiceSpec extends Specification { def conditionProperties = createConditionProperties('cmHandleWithDmiPlugin', [['some-key': 'some-value']]) cmHandleQueryParameters.setCmHandleQueryParameters([conditionProperties]) and: 'the inventoryPersistence returns different CmHandleIds' - partiallyMockedCmHandleQueries.getCmHandleReferencesMapByDmiPluginIdentifier(*_) >> [:] + partiallyMockedCmHandleQueries.getCmHandleReferencesByDmiPluginIdentifier(_,_) >> [] when: 'the query executed' def result = objectUnderTestWithPartiallyMockedQueries.queryCmHandleIdsForInventory(cmHandleQueryParameters, true) then: 'the expected number of results are returned.' diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/utils/AlternateIdMatcherSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/utils/AlternateIdMatcherSpec.groovy index a6d21afd30..b59dd1a55f 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/utils/AlternateIdMatcherSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/utils/AlternateIdMatcherSpec.groovy @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2024 Nordix Foundation + * Copyright (C) 2024-2025 Nordix Foundation * ================================================================================ * Licensed under the Apache License, Version 2.0 (the 'License'); * you may not use this file except in compliance with the License. @@ -24,12 +24,18 @@ import org.onap.cps.ncmp.api.exceptions.CmHandleNotFoundException import org.onap.cps.ncmp.exceptions.NoAlternateIdMatchFoundException import org.onap.cps.ncmp.impl.inventory.InventoryPersistence import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle +import org.onap.cps.utils.CpsValidatorImpl +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.test.context.ContextConfiguration import spock.lang.Specification +@SpringBootTest +@ContextConfiguration(classes = [InventoryPersistence]) class AlternateIdMatcherSpec extends Specification { def mockInventoryPersistence = Mock(InventoryPersistence) - def objectUnderTest = new AlternateIdMatcher(mockInventoryPersistence) + + def objectUnderTest = new AlternateIdMatcher(mockInventoryPersistence, new CpsValidatorImpl()) def setup() { given: 'cm handle in the registry with alternate id /a/b' @@ -68,17 +74,22 @@ class AlternateIdMatcherSpec extends Specification { 'no match at all' | '/x/y' } - def 'Get cmHandle id from passed cmHandleReference (cmHandleId scenario)' () { - when: 'a cmHandleCmReference is passed in' + def 'Get cm handle id from a cm handle reference that is a #scenario id.' () { + given: 'inventory persistence service confirms the reference exists as an id or not (#isExistingCmHandleId)' + mockInventoryPersistence.isExistingCmHandleId(cmHandleReference) >> isExistingCmHandleId + when: 'getting a cm handle id from the reference' def result = objectUnderTest.getCmHandleId(cmHandleReference) - then: 'the inventory persistence service returns a cm handle (or not)' - mockInventoryPersistence.isExistingCmHandleId(cmHandleReference) >> existingCmHandleIdResponse - mockInventoryPersistence.getYangModelCmHandleByAlternateId(cmHandleReference) >> alternateIdGetResponse - and: 'correct result is returned' - assert result == cmHandleReference + then: 'a call to find the cm handle by alternate id is only made when needed' + if (isExistingCmHandleId) { + 0 * mockInventoryPersistence.getYangModelCmHandleByAlternateId(*_) + } else { + 1 * mockInventoryPersistence.getYangModelCmHandleByAlternateId(cmHandleReference) >> new YangModelCmHandle(id: 'ch-id-2') + } + and: 'the expected cm handle id is returned' + assert result == expectedCmHandleId where: 'the following parameters are used' - cmHandleReference | existingCmHandleIdResponse | alternateIdGetResponse - 'ch-1' | true | '' - 'alt-1' | false | new YangModelCmHandle(id: 'alt-1') + scenario | cmHandleReference | isExistingCmHandleId || expectedCmHandleId + 'standard' | 'ch-id-1' | true || 'ch-id-1' + 'alternate' | 'alt-id=1' | false || 'ch-id-2' } } |