From 9f1a941f436f9ed6d84c5dbcf9c71b29aea0bfc8 Mon Sep 17 00:00:00 2001 From: emaclee Date: Mon, 28 Apr 2025 11:13:15 +0100 Subject: [PATCH] Use Alternate Id to CM-handle ID map for DCM write datajobs Issue-Id: CPS-2743 Change-Id: I1663d8aab4a3d4cee898a3171dad926643ccbe79 Signed-off-by: emaclee --- .../ncmp/impl/datajobs/WriteRequestExaminer.java | 29 +++++++----------- .../cps/ncmp/impl/utils/AlternateIdMatcher.java | 14 ++++----- .../impl/datajobs/WriteRequestExaminerSpec.groovy | 35 +++++++++++++--------- .../ncmp/impl/utils/AlternateIdMatcherSpec.groovy | 10 +++---- 4 files changed, 40 insertions(+), 48 deletions(-) diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/WriteRequestExaminer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/WriteRequestExaminer.java index f189edc89a..7d08d91cc4 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/WriteRequestExaminer.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/datajobs/WriteRequestExaminer.java @@ -32,19 +32,20 @@ import org.onap.cps.ncmp.api.datajobs.models.ProducerKey; import org.onap.cps.ncmp.api.datajobs.models.WriteOperation; import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle; import org.onap.cps.ncmp.impl.dmi.DmiServiceNameResolver; -import org.onap.cps.ncmp.impl.inventory.ParameterizedCmHandleQueryService; +import org.onap.cps.ncmp.impl.inventory.InventoryPersistence; import org.onap.cps.ncmp.impl.models.RequiredDmiService; import org.onap.cps.ncmp.impl.utils.AlternateIdMatcher; +import org.onap.cps.ncmp.impl.utils.YangDataConverter; import org.springframework.stereotype.Service; @Slf4j @Service @RequiredArgsConstructor public class WriteRequestExaminer { + private static final String PATH_SEPARATOR = "/"; private final AlternateIdMatcher alternateIdMatcher; - private final ParameterizedCmHandleQueryService parameterizedCmHandleQueryService; - private static final String PATH_SEPARATOR = "/"; + private final InventoryPersistence inventoryPersistence; /** * Splitting incoming data job write request into Dmi Write Operations by ProducerKey. @@ -56,30 +57,20 @@ public class WriteRequestExaminer { public Map> splitDmiWriteOperationsFromRequest( final String dataJobId, final DataJobWriteRequest dataJobWriteRequest) { final Map> dmiWriteOperationsPerProducerKey = new HashMap<>(); - final Map cmHandlePerAlternateId = getAllNcmpServiceCmHandlesWithoutProperties(); for (final WriteOperation writeOperation : dataJobWriteRequest.data()) { - examineWriteOperation(dataJobId, dmiWriteOperationsPerProducerKey, writeOperation, cmHandlePerAlternateId); + examineWriteOperation(dataJobId, dmiWriteOperationsPerProducerKey, writeOperation); } return dmiWriteOperationsPerProducerKey; } - private Map getAllNcmpServiceCmHandlesWithoutProperties() { - final Map ncmpServiceCmHandles = new HashMap<>(); - for (final NcmpServiceCmHandle ncmpServiceCmHandle - : parameterizedCmHandleQueryService.getAllCmHandlesWithoutProperties()) { - ncmpServiceCmHandles.put(ncmpServiceCmHandle.getAlternateId(), ncmpServiceCmHandle); - } - return ncmpServiceCmHandles; - } - private void examineWriteOperation(final String dataJobId, final Map> dmiWriteOperationsPerProducerKey, - final WriteOperation writeOperation, - final Map cmHandlePerAlternateId) { + final WriteOperation writeOperation) { log.debug("data job id for write operation is: {}", dataJobId); - final NcmpServiceCmHandle ncmpServiceCmHandle = alternateIdMatcher - .getCmHandleByLongestMatchingAlternateId(writeOperation.path(), PATH_SEPARATOR, cmHandlePerAlternateId); - + final String cmHandleId = alternateIdMatcher + .getCmHandleIdByLongestMatchingAlternateId(writeOperation.path(), PATH_SEPARATOR); + final NcmpServiceCmHandle ncmpServiceCmHandle = YangDataConverter.toNcmpServiceCmHandle( + inventoryPersistence.getYangModelCmHandle(cmHandleId)); final DmiWriteOperation dmiWriteOperation = createDmiWriteOperation(writeOperation, ncmpServiceCmHandle); final ProducerKey producerKey = createProducerKey(ncmpServiceCmHandle); 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 3a0201e029..bd5210f8b4 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 @@ -21,12 +21,10 @@ package org.onap.cps.ncmp.impl.utils; import com.hazelcast.map.IMap; -import java.util.Map; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.onap.cps.ncmp.api.exceptions.CmHandleNotFoundException; -import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle; import org.onap.cps.ncmp.exceptions.NoAlternateIdMatchFoundException; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; @@ -46,18 +44,16 @@ public class AlternateIdMatcher { * * @param alternateId alternate ID * @param separator a string that separates each element from the next. - * @param cmHandlePerAlternateId all CM-handles by alternate ID * @return ncmp service cm handle */ - public NcmpServiceCmHandle getCmHandleByLongestMatchingAlternateId( - final String alternateId, final String separator, - final Map cmHandlePerAlternateId) { + public String getCmHandleIdByLongestMatchingAlternateId( + final String alternateId, final String separator) { final String[] splitPath = alternateId.split("#", 2); String bestMatch = splitPath[0]; while (StringUtils.isNotEmpty(bestMatch)) { - final NcmpServiceCmHandle ncmpServiceCmHandle = cmHandlePerAlternateId.get(bestMatch); - if (ncmpServiceCmHandle != null) { - return ncmpServiceCmHandle; + final String cmHandleId = cmHandleIdPerAlternateId.get(bestMatch); + if (cmHandleId != null) { + return cmHandleId; } bestMatch = getParentPath(bestMatch, separator); } diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/WriteRequestExaminerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/WriteRequestExaminerSpec.groovy index d051927b3d..8f37f6e66f 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/WriteRequestExaminerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/datajobs/WriteRequestExaminerSpec.groovy @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2024 Nordix Foundation + * Copyright (C) 2024-2025 OpenInfra Foundation Europe. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,27 +23,34 @@ package org.onap.cps.ncmp.impl.datajobs import org.onap.cps.ncmp.api.datajobs.models.DataJobWriteRequest import org.onap.cps.ncmp.api.datajobs.models.WriteOperation import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle -import org.onap.cps.ncmp.impl.inventory.ParameterizedCmHandleQueryService +import org.onap.cps.ncmp.impl.inventory.InventoryPersistence +import org.onap.cps.ncmp.impl.inventory.models.YangModelCmHandle import org.onap.cps.ncmp.impl.utils.AlternateIdMatcher import spock.lang.Specification class WriteRequestExaminerSpec extends Specification { def mockAlternateIdMatcher = Mock(AlternateIdMatcher) - def mockParameterizedCmHandleQueryService = Mock(ParameterizedCmHandleQueryService) - def objectUnderTest = new WriteRequestExaminer(mockAlternateIdMatcher, mockParameterizedCmHandleQueryService) + def mockInventoryPersistence = Mock(InventoryPersistence) + def objectUnderTest = new WriteRequestExaminer(mockAlternateIdMatcher, mockInventoryPersistence) def setup() { - def ch1 = new NcmpServiceCmHandle(cmHandleId: 'ch1', dmiServiceName: 'dmiA', moduleSetTag: 'someModuleSetTag', alternateId: 'fdn1', dataProducerIdentifier: 'p1') - def ch2 = new NcmpServiceCmHandle(cmHandleId: 'ch2', dmiServiceName: 'dmiA', moduleSetTag: 'someModuleSetTag', alternateId: 'fdn2', dataProducerIdentifier: 'p1') - def ch3 = new NcmpServiceCmHandle(cmHandleId: 'ch3', dmiServiceName: 'dmiA', moduleSetTag: 'someModuleSetTag', alternateId: 'fdn3', dataProducerIdentifier: 'p2') - def ch4 = new NcmpServiceCmHandle(cmHandleId: 'ch4', dmiServiceName: 'dmiB', moduleSetTag: 'someModuleSetTag', alternateId: 'fdn4', dataProducerIdentifier: 'p1') - def cmHandlePerAlternateId = ['fdn1': ch1, 'fdn2': ch2, 'fdn3': ch3, 'fdn4': ch4] - mockAlternateIdMatcher.getCmHandleByLongestMatchingAlternateId('fdn1', '/', cmHandlePerAlternateId) >> ch1 - mockAlternateIdMatcher.getCmHandleByLongestMatchingAlternateId('fdn2', '/', cmHandlePerAlternateId) >> ch2 - mockAlternateIdMatcher.getCmHandleByLongestMatchingAlternateId('fdn3', '/', cmHandlePerAlternateId) >> ch3 - mockAlternateIdMatcher.getCmHandleByLongestMatchingAlternateId('fdn4', '/', cmHandlePerAlternateId) >> ch4 - mockParameterizedCmHandleQueryService.getAllCmHandlesWithoutProperties() >> [ch1, ch2, ch3, ch4] + def yangModelCmHandle1 = new YangModelCmHandle(id: 'ch1', dmiServiceName: 'dmiA', dmiProperties: [], + publicProperties: [], compositeState: null, moduleSetTag: '', alternateId: '', dataProducerIdentifier: 'p1') + def yangModelCmHandle2 = new YangModelCmHandle(id: 'ch2', dmiServiceName: 'dmiA', dmiProperties: [], + publicProperties: [], compositeState: null, moduleSetTag: '', alternateId: '', dataProducerIdentifier: 'p1') + def yangModelCmHandle3 = new YangModelCmHandle(id: 'ch3', dmiServiceName: 'dmiA', dmiProperties: [], + publicProperties: [], compositeState: null, moduleSetTag: '', alternateId: '', dataProducerIdentifier: 'p2') + def yangModelCmHandle4 = new YangModelCmHandle(id: 'ch4', dmiServiceName: 'dmiB', dmiProperties: [], + publicProperties: [], compositeState: null, moduleSetTag: '', alternateId: '', dataProducerIdentifier: 'p1') + mockInventoryPersistence.getYangModelCmHandle('ch1') >> yangModelCmHandle1 + mockInventoryPersistence.getYangModelCmHandle('ch2') >> yangModelCmHandle2 + mockInventoryPersistence.getYangModelCmHandle('ch3') >> yangModelCmHandle3 + mockInventoryPersistence.getYangModelCmHandle('ch4') >> yangModelCmHandle4 + mockAlternateIdMatcher.getCmHandleIdByLongestMatchingAlternateId('fdn1', '/') >> 'ch1' + mockAlternateIdMatcher.getCmHandleIdByLongestMatchingAlternateId('fdn2', '/') >> 'ch2' + mockAlternateIdMatcher.getCmHandleIdByLongestMatchingAlternateId('fdn3', '/') >> 'ch3' + mockAlternateIdMatcher.getCmHandleIdByLongestMatchingAlternateId('fdn4', '/') >> 'ch4' } def 'Create a map of dmi write requests per producer key with #scenario.'() { 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 984d45e420..84a0507f6c 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 @@ -22,7 +22,6 @@ package org.onap.cps.ncmp.impl.utils import com.hazelcast.map.IMap import org.onap.cps.ncmp.api.exceptions.CmHandleNotFoundException -import org.onap.cps.ncmp.api.inventory.models.NcmpServiceCmHandle import org.onap.cps.ncmp.exceptions.NoAlternateIdMatchFoundException import spock.lang.Specification @@ -33,11 +32,10 @@ class AlternateIdMatcherSpec extends Specification { def objectUnderTest = new AlternateIdMatcher(mockCmHandleIdPerAlternateId) def 'Finding longest alternate id matches.'() { - given: 'a cm handle with alternate id /a/b in the cached map of all cm handles' - def ch1 = new NcmpServiceCmHandle(cmHandleId: 'ch1', alternateId: '/a/b') - def cmHandlePerAlternateId = ['/a/b': ch1] + given: + mockCmHandleIdPerAlternateId.get('/a/b') >> 'ch1' expect: 'querying for alternate id a matching result found' - assert objectUnderTest.getCmHandleByLongestMatchingAlternateId(targetAlternateId, '/', cmHandlePerAlternateId) != null + assert objectUnderTest.getCmHandleIdByLongestMatchingAlternateId(targetAlternateId, '/') != null where: 'the following parameters are used' scenario | targetAlternateId 'exact match' | '/a/b' @@ -52,7 +50,7 @@ class AlternateIdMatcherSpec extends Specification { def 'Attempt to find longest alternate id match without any matches.'() { when: 'attempt to find alternateId' - objectUnderTest.getCmHandleByLongestMatchingAlternateId(targetAlternateId, '/', [:]) + objectUnderTest.getCmHandleIdByLongestMatchingAlternateId(targetAlternateId, '/') then: 'no alternate id match found exception thrown' def thrown = thrown(NoAlternateIdMatchFoundException) and: 'the exception has the relevant details from the error response' -- 2.16.6