summaryrefslogtreecommitdiffstats
path: root/cps-service
diff options
context:
space:
mode:
authorrajesh.kumar <rk00747546@techmahindra.com>2022-12-14 14:27:29 +0000
committerLuke Gleeson <luke.gleeson@est.tech>2023-03-21 09:45:16 +0000
commita317890387fdbc689f8dcd8648b5bfe3b43abd1e (patch)
tree652b78e62895aa186eb26788eb475634ce2ddce9 /cps-service
parent0b00f81b98e5fa9632b1145e49f62d0b2712f4e4 (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')
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/CpsQueryService.java12
-rw-r--r--cps-service/src/main/java/org/onap/cps/api/impl/CpsQueryServiceImpl.java8
-rw-r--r--cps-service/src/main/java/org/onap/cps/spi/CpsDataPersistenceService.java13
-rw-r--r--cps-service/src/main/java/org/onap/cps/spi/model/DataNodeBuilder.java15
-rw-r--r--cps-service/src/main/java/org/onap/cps/utils/DataMapUtils.java15
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/api/impl/CpsQueryServiceImplSpec.groovy14
-rw-r--r--cps-service/src/test/groovy/org/onap/cps/utils/DataMapUtilsSpec.groovy32
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'
+ }
}