diff options
author | rajesh.kumar <rk00747546@techmahindra.com> | 2022-12-14 14:27:29 +0000 |
---|---|---|
committer | Luke Gleeson <luke.gleeson@est.tech> | 2023-03-21 09:45:16 +0000 |
commit | a317890387fdbc689f8dcd8648b5bfe3b43abd1e (patch) | |
tree | 652b78e62895aa186eb26788eb475634ce2ddce9 /cps-service | |
parent | 0b00f81b98e5fa9632b1145e49f62d0b2712f4e4 (diff) |
Query data nodes across all anchors under one dataspace
Issue-ID: CPS-1396
Change-ID: I73f97f986a817d423f93a8d922dcd9647b1412ab
Signed-off-by: rajesh.kumar <rk00747546@techmahindra.com>
Diffstat (limited to 'cps-service')
7 files changed, 108 insertions, 1 deletions
diff --git a/cps-service/src/main/java/org/onap/cps/api/CpsQueryService.java b/cps-service/src/main/java/org/onap/cps/api/CpsQueryService.java index 68ae1ebf0a..af54077fea 100644 --- a/cps-service/src/main/java/org/onap/cps/api/CpsQueryService.java +++ b/cps-service/src/main/java/org/onap/cps/api/CpsQueryService.java @@ -1,6 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2020-2022 Nordix Foundation + * Modifications Copyright (C) 2022-2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,4 +43,15 @@ public interface CpsQueryService { Collection<DataNode> queryDataNodes(String dataspaceName, String anchorName, String cpsPath, FetchDescendantsOption fetchDescendantsOption); + /** + * Get data nodes for the given dataspace across all anchors by cps path. + * + * @param dataspaceName dataspace name + * @param cpsPath CPS path + * @param fetchDescendantsOption defines whether the descendants of the node(s) found by the query should be + * included in the output + * @return a collection of data nodes + */ + Collection<DataNode> queryDataNodesAcrossAnchors(String dataspaceName, String cpsPath, + FetchDescendantsOption fetchDescendantsOption); } diff --git a/cps-service/src/main/java/org/onap/cps/api/impl/CpsQueryServiceImpl.java b/cps-service/src/main/java/org/onap/cps/api/impl/CpsQueryServiceImpl.java index a63faabac4..ac018c9e8f 100644 --- a/cps-service/src/main/java/org/onap/cps/api/impl/CpsQueryServiceImpl.java +++ b/cps-service/src/main/java/org/onap/cps/api/impl/CpsQueryServiceImpl.java @@ -1,6 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2021-2022 Nordix Foundation + * Modifications Copyright (C) 2022-2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,4 +46,11 @@ public class CpsQueryServiceImpl implements CpsQueryService { cpsValidator.validateNameCharacters(dataspaceName, anchorName); return cpsDataPersistenceService.queryDataNodes(dataspaceName, anchorName, cpsPath, fetchDescendantsOption); } + + @Override + public Collection<DataNode> queryDataNodesAcrossAnchors(final String dataspaceName, + final String cpsPath, final FetchDescendantsOption fetchDescendantsOption) { + cpsValidator.validateNameCharacters(dataspaceName); + return cpsDataPersistenceService.queryDataNodesAcrossAnchors(dataspaceName, cpsPath, fetchDescendantsOption); + } } diff --git a/cps-service/src/main/java/org/onap/cps/spi/CpsDataPersistenceService.java b/cps-service/src/main/java/org/onap/cps/spi/CpsDataPersistenceService.java index f10443fda8..540401913b 100644 --- a/cps-service/src/main/java/org/onap/cps/spi/CpsDataPersistenceService.java +++ b/cps-service/src/main/java/org/onap/cps/spi/CpsDataPersistenceService.java @@ -224,6 +224,19 @@ public interface CpsDataPersistenceService { String cpsPath, FetchDescendantsOption fetchDescendantsOption); /** + * Get a datanode by dataspace name and cps path across all anchors. + * + * @param dataspaceName dataspace name + * @param cpsPath cps path + * @param fetchDescendantsOption defines whether the descendants of the node(s) found by the query should be + * included in the output + * @return the data nodes found i.e. 0 or more data nodes + */ + List<DataNode> queryDataNodesAcrossAnchors(String dataspaceName, + String cpsPath, FetchDescendantsOption fetchDescendantsOption); + + + /** * Starts a session which allows use of locks and batch interaction with the persistence service. * * @return Session ID string diff --git a/cps-service/src/main/java/org/onap/cps/spi/model/DataNodeBuilder.java b/cps-service/src/main/java/org/onap/cps/spi/model/DataNodeBuilder.java index b23cdfc8d1..6fc36ebb61 100644 --- a/cps-service/src/main/java/org/onap/cps/spi/model/DataNodeBuilder.java +++ b/cps-service/src/main/java/org/onap/cps/spi/model/DataNodeBuilder.java @@ -3,7 +3,7 @@ * Copyright (C) 2021 Bell Canada. All rights reserved. * Modifications Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2022 Nordix Foundation. - * Modifications Copyright (C) 2022 TechMahindra Ltd. + * Modifications Copyright (C) 2022-2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,6 +54,7 @@ public class DataNodeBuilder { private String parentNodeXpath = ""; private Map<String, Serializable> leaves = Collections.emptyMap(); private Collection<DataNode> childDataNodes = Collections.emptySet(); + private String anchorName; /** * To use parent node xpath for creating {@link DataNode}. @@ -89,6 +90,17 @@ public class DataNodeBuilder { } /** + * To use anchor name for creating {@link DataNode}. + * + * @param anchorName anchor name for the data node + * @return DataNodeBuilder + */ + public DataNodeBuilder withAnchor(final String anchorName) { + this.anchorName = anchorName; + return this; + } + + /** * To use module name for prefix for creating {@link DataNode}. * * @param moduleNamePrefix module name as prefix @@ -153,6 +165,7 @@ public class DataNodeBuilder { dataNode.setModuleNamePrefix(moduleNamePrefix); dataNode.setLeaves(leaves); dataNode.setChildDataNodes(childDataNodes); + dataNode.setAnchorName(anchorName); return dataNode; } diff --git a/cps-service/src/main/java/org/onap/cps/utils/DataMapUtils.java b/cps-service/src/main/java/org/onap/cps/utils/DataMapUtils.java index 14641e05e6..b0e109bafd 100644 --- a/cps-service/src/main/java/org/onap/cps/utils/DataMapUtils.java +++ b/cps-service/src/main/java/org/onap/cps/utils/DataMapUtils.java @@ -3,6 +3,7 @@ * Copyright (C) 2021 Pantheon.tech * Modifications (C) 2021-2022 Nordix Foundation * Modifications Copyright (C) 2022 Bell Canada + * Modifications Copyright (C) 2022-2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,6 +50,20 @@ public class DataMapUtils { } /** + * Converts DataNode structure into a map including the root node identifier for a JSON response. + * + * @param dataNode data node object + * @return a map representing same data with the root node identifier + */ + public static Map<String, Object> toDataMapWithIdentifierAndAnchor(final DataNode dataNode, final String prefix) { + final String nodeIdentifierWithPrefix = getNodeIdentifierWithPrefix(dataNode.getXpath(), prefix); + final Map<String, Object> dataMap = ImmutableMap.<String, Object>builder() + .put(nodeIdentifierWithPrefix, toDataMap(dataNode)).build(); + return ImmutableMap.<String, Object>builder().put("anchorName", dataNode.getAnchorName()) + .put("dataNode", dataMap).build(); + } + + /** * Converts DataNode structure into a map for a JSON response. * * @param dataNode data node object diff --git a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy index 56c43d1633..553027a4b8 100644 --- a/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy @@ -48,4 +48,18 @@ class CpsQueryServiceImplSpec extends Specification { FetchDescendantsOption.DIRECT_CHILDREN_ONLY, new FetchDescendantsOption(10)] } + def 'Query data nodes across all anchors by cps path with #fetchDescendantsOption.'() { + given: 'a dataspace name, an anchor name and a cps path' + def dataspaceName = 'some-dataspace' + def cpsPath = '/cps-path' + when: 'queryDataNodes is invoked' + objectUnderTest.queryDataNodesAcrossAnchors(dataspaceName, cpsPath, fetchDescendantsOption) + then: 'the persistence service is called once with the correct parameters' + 1 * mockCpsDataPersistenceService.queryDataNodesAcrossAnchors(dataspaceName, cpsPath, fetchDescendantsOption) + and: 'the CpsValidator is called on the dataspaceName, schemaSetName and anchorName' + 1 * mockCpsValidator.validateNameCharacters(dataspaceName) + where: 'all fetch descendants options are supported' + fetchDescendantsOption << [FetchDescendantsOption.OMIT_DESCENDANTS, FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS] + } + } diff --git a/cps-service/src/test/groovy/org/onap/cps/utils/DataMapUtilsSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/utils/DataMapUtilsSpec.groovy index 84dddeb60e..e27b437637 100644 --- a/cps-service/src/test/groovy/org/onap/cps/utils/DataMapUtilsSpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/utils/DataMapUtilsSpec.groovy @@ -3,6 +3,7 @@ * Copyright (C) 2021 Pantheon.tech * Modifications Copyright (C) 2020-2022 Nordix Foundation * Modifications Copyright (C) 2022 Bell Canada. + * Modifications Copyright (C) 2023 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,10 +38,23 @@ class DataMapUtilsSpec extends Specification { ), ]) + def dataNodeWithAnchor = buildDataNodeWithAnchor( + "/parent", 'anchor01',[parentLeaf:'parentLeafValue', parentLeafList:['parentLeafListEntry1','parentLeafListEntry2']],[ + buildDataNode('/parent/child-list[@id=1/2]',[listElementLeaf:'listElement1leafValue'],noChildren), + buildDataNode('/parent/child-list[@id=2]',[listElementLeaf:'listElement2leafValue'],noChildren), + buildDataNode('/parent/child-object',[childLeaf:'childLeafValue'], + [buildDataNode('/parent/child-object/grand-child-object',[grandChildLeaf:'grandChildLeafValue'],noChildren)] + ), + ]) + static def buildDataNode(xpath, leaves, children) { return new DataNodeBuilder().withXpath(xpath).withLeaves(leaves).withChildDataNodes(children).build() } + static def buildDataNodeWithAnchor(xpath, anchorName, leaves, children) { + return new DataNodeBuilder().withXpath(xpath).withAnchor(anchorName).withLeaves(leaves).withChildDataNodes(children).build() + } + def 'Data node structure conversion to map.'() { when: 'data node structure is converted to a map' def result = DataMapUtils.toDataMap(dataNode) @@ -90,5 +104,23 @@ class DataMapUtilsSpec extends Specification { 'xpath contains list attributes with /' | '/bookstore/categories[@code=1/2]' | 'sampleModuleName:categories' } + + def 'Data node structure with anchor name conversion to map with root node identifier.'() { + when: 'data node structure is converted to a map with root node identifier' + def result = DataMapUtils.toDataMapWithIdentifierAndAnchor(dataNodeWithAnchor, dataNodeWithAnchor.moduleNamePrefix) + then: 'root node leaves are populated under its node identifier' + def parentNode = result.get("dataNode").parent + parentNode.parentLeaf == 'parentLeafValue' + parentNode.parentLeafList == ['parentLeafListEntry1','parentLeafListEntry2'] + + and: 'leaves for child element is populated under its node identifier' + assert parentNode.'child-object'.childLeaf == 'childLeafValue' + + and: 'leaves for grandchild element is populated under its node identifier' + assert parentNode.'child-object'.'grand-child-object'.grandChildLeaf == 'grandChildLeafValue' + + and: 'data node is associated with anchor name' + assert result.get('anchorName') == 'anchor01' + } } |