diff options
author | seanbeirne <sean.beirne@est.tech> | 2024-07-17 11:35:22 +0100 |
---|---|---|
committer | Priyank Maheshwari <priyank.maheshwari@est.tech> | 2024-08-12 12:12:20 +0000 |
commit | 117dcc8b8e0a7aa36c6f9f125d37381dabd2ad93 (patch) | |
tree | 794eaa6049dbba464937cc45b4e96b8691e942dc /cps-ncmp-service | |
parent | d3c1e7246ab4f41cf3dad97e559ca2736b0014cf (diff) |
Support alternate Id interface for CPS-E-05 #2
- Supports Alternate Ids for getResourceDataForCmHandle
Issue-Id: CPS-2279
Change-Id: I1f145308cec5b545fab2d5c96efbc00fc3a110f4
Signed-off-by: seanbeirne <sean.beirne@est.tech>
Diffstat (limited to 'cps-ncmp-service')
11 files changed, 111 insertions, 25 deletions
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/models/CmResourceAddress.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/models/CmResourceAddress.java index e93aa4c603..98a343b92e 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/models/CmResourceAddress.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/data/models/CmResourceAddress.java @@ -20,6 +20,22 @@ package org.onap.cps.ncmp.api.data.models; -public record CmResourceAddress(String datastoreName, String cmHandleId, String resourceIdentifier) { +import lombok.AccessLevel; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.onap.cps.ncmp.config.CpsApplicationContext; +import org.onap.cps.ncmp.impl.utils.AlternateIdMatcher; +@Getter +@RequiredArgsConstructor +public class CmResourceAddress { + + private final String datastoreName; + @Getter(AccessLevel.NONE) + private final String cmHandleReference; + private final String resourceIdentifier; + + public String getResolvedCmHandleId() { + return CpsApplicationContext.getCpsBean(AlternateIdMatcher.class).getCmHandleId(cmHandleReference); + } } 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 4cbf9d4b3b..90783a829a 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 @@ -92,12 +92,12 @@ public class DmiDataOperations { final String topic, final String requestId, final String authorization) { - final YangModelCmHandle yangModelCmHandle = getYangModelCmHandle(cmResourceAddress.cmHandleId()); + final YangModelCmHandle yangModelCmHandle = getYangModelCmHandle(cmResourceAddress.getResolvedCmHandleId()); final CmHandleState cmHandleState = yangModelCmHandle.getCompositeState().getCmHandleState(); validateIfCmHandleStateReady(yangModelCmHandle, cmHandleState); final String jsonRequestBody = getDmiRequestBody(READ, requestId, null, null, yangModelCmHandle); final UrlTemplateParameters urlTemplateParameters = getUrlTemplateParameters(cmResourceAddress - .datastoreName(), yangModelCmHandle, cmResourceAddress.resourceIdentifier(), options, topic); + .getDatastoreName(), yangModelCmHandle, cmResourceAddress.getResourceIdentifier(), options, topic); return dmiRestClient.asynchronousPostOperationWithJsonData(DATA, urlTemplateParameters, jsonRequestBody, READ, authorization); } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NcmpCachedResourceRequestHandler.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NcmpCachedResourceRequestHandler.java index bff2f6390c..01022cc03e 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NcmpCachedResourceRequestHandler.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NcmpCachedResourceRequestHandler.java @@ -61,9 +61,9 @@ public class NcmpCachedResourceRequestHandler extends NcmpDatastoreRequestHandle final String authorization) { final FetchDescendantsOption fetchDescendantsOption = getFetchDescendantsOption(includeDescendants); - final DataNode dataNode = cpsDataService.getDataNodes(cmResourceAddress.datastoreName(), - cmResourceAddress.cmHandleId(), - cmResourceAddress.resourceIdentifier(), + final DataNode dataNode = cpsDataService.getDataNodes(cmResourceAddress.getDatastoreName(), + cmResourceAddress.getResolvedCmHandleId(), + cmResourceAddress.getResourceIdentifier(), fetchDescendantsOption).iterator().next(); return Mono.justOrEmpty(dataNode); } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NetworkCmProxyFacade.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NetworkCmProxyFacade.java index 503915716e..b97088a5e0 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NetworkCmProxyFacade.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/impl/data/NetworkCmProxyFacade.java @@ -33,6 +33,7 @@ import org.onap.cps.ncmp.api.data.models.CmResourceAddress; import org.onap.cps.ncmp.api.data.models.DataOperationRequest; import org.onap.cps.ncmp.api.data.models.DatastoreType; import org.onap.cps.ncmp.api.data.models.OperationType; +import org.onap.cps.ncmp.impl.utils.AlternateIdMatcher; import org.onap.cps.spi.model.DataNode; import org.springframework.stereotype.Service; @@ -44,34 +45,35 @@ public class NetworkCmProxyFacade { private final NcmpCachedResourceRequestHandler ncmpCachedResourceRequestHandler; private final NcmpPassthroughResourceRequestHandler ncmpPassthroughResourceRequestHandler; private final DmiDataOperations dmiDataOperations; + private final AlternateIdMatcher alternateIdMatcher; /** * Fetches resource data for a given data store using DMI (Data Management Interface). * This method retrieves data based on the provided CmResourceAddress and additional query parameters. * It supports asynchronous processing and handles authorization if required. * - * @param cmResourceAddress The target data store, including the CM handle and resource identifier. - * This parameter must not be null. - * @param options Additional query parameters that may influence the data retrieval process, - * such as filters or limits. This parameter can be null. - * @param topic The topic name for triggering asynchronous responses. If specified, - * the response will be sent to this topic. This parameter can be null. - * @param includeDescendants include (all) descendants or not - * @param authorization The contents of the Authorization header. This parameter can be null - * if authorization is not required. + * @param cmResourceAddress The target data store, including the CM handle and resource identifier. + * This parameter must not be null. + * @param optionsParamInQuery Additional query parameters that may influence the data retrieval process, + * such as filters or limits. This parameter can be null. + * @param topicParamInQuery The topic name for triggering asynchronous responses. If specified, + * the response will be sent to this topic. This parameter can be null. + * @param includeDescendants include (all) descendants or not + * @param authorization The contents of the Authorization header. This parameter can be null + * if authorization is not required. * @return the result object, depends on use op topic. With topic a map object with request id is returned * otherwise the result of the request. */ public Object getResourceDataForCmHandle(final CmResourceAddress cmResourceAddress, - final String options, - final String topic, + final String optionsParamInQuery, + final String topicParamInQuery, final Boolean includeDescendants, final String authorization) { - final NcmpDatastoreRequestHandler ncmpDatastoreRequestHandler - = getNcmpDatastoreRequestHandler(cmResourceAddress.datastoreName()); - return ncmpDatastoreRequestHandler.executeRequest(cmResourceAddress, options, topic, includeDescendants, - authorization); + final NcmpDatastoreRequestHandler ncmpDatastoreRequestHandler + = getNcmpDatastoreRequestHandler(cmResourceAddress.getDatastoreName()); + return ncmpDatastoreRequestHandler.executeRequest(cmResourceAddress, optionsParamInQuery, + topicParamInQuery, includeDescendants, authorization); } /** @@ -117,7 +119,6 @@ public class NetworkCmProxyFacade { operationType, requestData, dataType, authorization); } - private NcmpDatastoreRequestHandler getNcmpDatastoreRequestHandler(final String datastoreName) { if (OPERATIONAL.equals(DatastoreType.fromDatastoreName(datastoreName))) { return ncmpCachedResourceRequestHandler; 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 cb4b04e4a0..beef752ef1 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 @@ -144,4 +144,12 @@ public interface InventoryPersistence extends NcmpPersistence { * @return Collection of CM handle Ids */ Collection<String> getCmHandleIdsWithGivenModules(Collection<String> moduleNamesForQuery); + + /** + * Check database if cm handle id exists if not return false. + * + * @param cmHandleId cmHandle Id + * @return Boolean + */ + boolean isExistingCmHandleId(String cmHandleId); } 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 0ca2cd3407..083b25db3d 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 @@ -195,6 +195,15 @@ public class InventoryPersistenceImpl extends NcmpPersistenceImpl implements Inv return cpsAnchorService.queryAnchorNames(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, moduleNamesForQuery); } + @Override + public boolean isExistingCmHandleId(final String cmHandleId) { + try { + return getCmHandleDataNodeByCmHandleId(cmHandleId).size() > 0; + } catch (final DataNodeNotFoundException exception) { + return false; + } + } + private static String getXPathForCmHandleById(final String cmHandleId) { return NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='" + cmHandleId + "']"; } 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 832e576d55..c408ff9b13 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 @@ -56,6 +56,21 @@ public class AlternateIdMatcher { throw new NoAlternateIdMatchFoundException(alternateId); } + /** + * Get cm handle Id from given cmHandleReference. + * + * @param cmHandleReference alternate ID + * @return cm handle id string + */ + public String getCmHandleId(final String cmHandleReference) { + if (inventoryPersistence.isExistingCmHandleId(cmHandleReference)) { + return cmHandleReference; + } else { + return inventoryPersistence.getCmHandleDataNodeByAlternateId(cmHandleReference) + .getLeaves().get("id").toString(); + } + } + private String getParentPath(final String path, final String separator) { final int lastSeparatorIndex = path.lastIndexOf(separator); return lastSeparatorIndex < 0 ? "" : path.substring(0, lastSeparatorIndex); 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 970444f643..8b369bf549 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 @@ -32,6 +32,7 @@ import org.onap.cps.ncmp.impl.dmi.DmiOperationsBaseSpec import org.onap.cps.ncmp.impl.dmi.DmiProperties import org.onap.cps.ncmp.impl.dmi.UrlTemplateParameters import org.onap.cps.ncmp.impl.inventory.models.CmHandleState +import org.onap.cps.ncmp.impl.utils.AlternateIdMatcher import org.onap.cps.ncmp.utils.TestUtils import org.onap.cps.utils.JsonObjectMapper import org.spockframework.spring.SpringBean @@ -76,6 +77,9 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec { @SpringBean PolicyExecutor policyExecutor = Mock() + @SpringBean + AlternateIdMatcher alternateIdMatcher = Mock() + def 'call get resource data for #expectedDataStore from DMI without topic #scenario.'() { given: 'a cm handle for #cmHandleId' mockYangModelCmHandleRetrieval(dmiProperties) @@ -86,6 +90,7 @@ class DmiDataOperationsSpec extends DmiOperationsBaseSpec { mockDmiRestClient.asynchronousPostOperationWithJsonData(DATA, expectedUrlTemplateWithVariables, expectedJson, READ, NO_AUTH_HEADER) >> responseFromDmi when: 'get resource data is invoked' def cmResourceAddress = new CmResourceAddress(expectedDataStore.datastoreName, cmHandleId, resourceIdentifier) + alternateIdMatcher.getCmHandleId(cmHandleId) >> cmHandleId def result = objectUnderTest.getResourceDataFromDmi(cmResourceAddress, expectedOptions, NO_TOPIC, NO_REQUEST_ID, NO_AUTH_HEADER).block() then: 'the result is the response from the DMI service' assert result.body == '{some-key:some-value}' diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/NcmpCachedResourceRequestHandlerSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/NcmpCachedResourceRequestHandlerSpec.groovy index 9c696dcc7a..314b76183e 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/NcmpCachedResourceRequestHandlerSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/NcmpCachedResourceRequestHandlerSpec.groovy @@ -21,19 +21,35 @@ package org.onap.cps.ncmp.impl.data import org.onap.cps.api.CpsDataService +import org.onap.cps.events.EventsPublisher import org.onap.cps.ncmp.api.data.models.CmResourceAddress +import org.onap.cps.ncmp.config.CpsApplicationContext +import org.onap.cps.ncmp.impl.dmi.DmiProperties +import org.onap.cps.ncmp.impl.utils.AlternateIdMatcher import org.onap.cps.spi.model.DataNode +import org.spockframework.spring.SpringBean +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.context.ApplicationContext +import org.springframework.test.context.ContextConfiguration import reactor.core.publisher.Mono import spock.lang.Specification import static org.onap.cps.spi.FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS import static org.onap.cps.spi.FetchDescendantsOption.OMIT_DESCENDANTS +@SpringBootTest +@ContextConfiguration(classes = [CpsApplicationContext]) class NcmpCachedResourceRequestHandlerSpec extends Specification { def cpsDataService = Mock(CpsDataService) def networkCmProxyQueryService= Mock(NetworkCmProxyQueryService) + @SpringBean + AlternateIdMatcher alternateIdMatcher = Mock() + + @SpringBean + ApplicationContext applicationContext = Mock() + def objectUnderTest = new NcmpCachedResourceRequestHandler(cpsDataService, networkCmProxyQueryService) def 'Execute a request with include descendants = #includeDescendants.'() { @@ -54,6 +70,7 @@ class NcmpCachedResourceRequestHandlerSpec extends Specification { def dataNode2 = new DataNode(xpath:'p2') cpsDataService.getDataNodes('datastore','ch-1','resource',OMIT_DESCENDANTS) >> [dataNode1, dataNode2] when: 'getting the resource data' + alternateIdMatcher.getCmHandleId('ch-1') >> 'ch-1' def result = objectUnderTest.getResourceDataForCmHandle(cmResourceAddress, 'options', 'topic', 'request id', false, 'authorization') then: 'the result is a "Mono" holding just the first data node' assert result instanceof Mono diff --git a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/NetworkCmProxyFacadeSpec.groovy b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/NetworkCmProxyFacadeSpec.groovy index f4e449904b..5f83ad5f83 100644 --- a/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/NetworkCmProxyFacadeSpec.groovy +++ b/cps-ncmp-service/src/test/groovy/org/onap/cps/ncmp/impl/data/NetworkCmProxyFacadeSpec.groovy @@ -26,6 +26,7 @@ package org.onap.cps.ncmp.impl.data import org.onap.cps.ncmp.api.data.models.CmResourceAddress import org.onap.cps.ncmp.api.data.models.DataOperationRequest +import org.onap.cps.ncmp.impl.utils.AlternateIdMatcher import org.onap.cps.spi.model.DataNode import reactor.core.publisher.Mono import spock.lang.Specification @@ -41,8 +42,9 @@ class NetworkCmProxyFacadeSpec extends Specification { def mockDmiDataOperations = Mock(DmiDataOperations) def mockNcmpCachedResourceRequestHandler = Mock(NcmpCachedResourceRequestHandler) def mockNcmpPassthroughResourceRequestHandler = Mock(NcmpPassthroughResourceRequestHandler) + def mockAlternateIdMatcher = Mock(AlternateIdMatcher) - def objectUnderTest = new NetworkCmProxyFacade(mockNcmpCachedResourceRequestHandler, mockNcmpPassthroughResourceRequestHandler, mockDmiDataOperations) + def objectUnderTest = new NetworkCmProxyFacade(mockNcmpCachedResourceRequestHandler, mockNcmpPassthroughResourceRequestHandler, mockDmiDataOperations, mockAlternateIdMatcher) def NO_TOPIC = null @@ -87,6 +89,7 @@ class NetworkCmProxyFacadeSpec extends Specification { given: 'a cm resource address for datastore operational' def cmResourceAddress = new CmResourceAddress('ncmp-datastore:operational', 'some CM Handle', 'some resource Id') and: 'get resource data from DMI is called' + mockAlternateIdMatcher.getCmHandleId('some CM Handle') >> 'some CM Handle' mockNcmpCachedResourceRequestHandler.executeRequest(cmResourceAddress, 'options', NO_TOPIC, false, 'authorization') >> Mono.just('dmi response') when: 'get resource data operational for the given cm resource address is called' @@ -103,6 +106,4 @@ class NetworkCmProxyFacadeSpec extends Specification { then: 'DMI called with correct data' 1 * mockDmiDataOperations.writeResourceDataPassThroughRunningFromDmi('testCmHandle', 'testResourceId', UPDATE, '{some-json}', 'application/json', 'authorization') } - - } 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 ad84495825..a497b4554a 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 @@ -63,4 +63,18 @@ class AlternateIdMatcherSpec extends Specification { 'no match for other child' | '/a/c' 'no match at all' | '/x/y' } + + def 'Get cmHandle id from passed cmHandleReference (cmHandleId scenario)' () { + when: 'a cmHandleCmReference is passed in' + def result = objectUnderTest.getCmHandleId(cmHandleReference) + then: 'the inventory persistence service returns a cm handle (or not)' + mockInventoryPersistence.isExistingCmHandleId(cmHandleReference) >> existingCmHandleIdResponse + mockInventoryPersistence.getCmHandleDataNodeByAlternateId(cmHandleReference) >> alternateIdGetResponse + and: 'correct result is returned' + assert result == cmHandleReference + where: + cmHandleReference | existingCmHandleIdResponse | alternateIdGetResponse + 'ch-1' | true | '' + 'alt-1' | false | new DataNode(leaves: [id:'alt-1']) + } } |