categories:
- code: 01
name: SciFi
+ - books:
+ - title: Book 1
+ lang: N/A
+ price: 11
+ editions:
+ - 2009
+ - books:
+ - title: Book 2
+ lang: German
+ price: 39
+ editions:
+ - 2007
+ - 2013
+ - 2021
- code: 02
name: kids
+ - books:
+ - title: Book 3
+ lang: English
+ price: 15
+ editions:
+ - 2010
+ dataSampleForV3:
+ value:
+ test:bookstore:
+ bookstore-name: Chapters
+ categories:
+ - code: 01
+ name: SciFi
+ books:
+ - title: Book 1
+ lang: N/A
+ price: 11
+ editions:
+ - 2009
+ - title: Book 2
+ lang: German
+ price: 39
+ editions:
+ - 2007
+ - 2013
+ - 2021
+ - code: 02
+ name: kids
+ books:
+ - title: Book 3
+ lang: English
+ price: 15
+ editions:
+ - 2010
dataSampleXml:
value:
<stores xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ <bookstore xmlns="org:onap:ccsdk:sample">
+ <bookstore-name>Chapters</bookstore-name>
+ <categories>
+ <code>1</code>
+ <name>SciFi</name>
+ </categories>
+ <categories>
+ <books>
+ <title>Book 1</title>
+ <lang>N/A</lang>
+ <price>11</price>
+ <editions>2009</editions>
+ </books>
+ </categories>
+ <categories>
+ <books>
+ <title>Book 2</title>
+ <lang>German</lang>
+ <price>39</price>
+ <editions>2007</editions>
+ <editions>2013</editions>
+ <editions>2021</editions>
+ </books>
+ </categories>
+ <categories>
+ <code>2</code>
+ <name>kids
+ </name>
+ <books>
+ <title>Book 3</title>
+ <lang>English</lang>
+ <price>15</price>
+ <editions>2010</editions>
+ </books>
+ </categories>
+ </bookstore>
+ </stores>
+ dataSampleXmlForV3:
+ value:
+ <stores xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<bookstore xmlns="org:onap:ccsdk:sample">
- <bookstore-name>Chapters</bookstore-name>
- <categories>
- <code>1</code>
- <name>SciFi</name>
- <code>2</code>
- <name>kids</name>
- </categories>
+ <bookstore-name>Chapters</bookstore-name>
+ <categories>
+ <code>1</code>
+ <name>SciFi</name>
+ <books>
+ <title>Book 1</title>
+ <lang>N/A</lang>
+ <price>11</price>
+ <editions>2009</editions>
+ </books>
+ <books>
+ <title>Book 2</title>
+ <lang>German</lang>
+ <price>39</price>
+ <editions>2007</editions>
+ <editions>2013</editions>
+ <editions>2021</editions>
+ </books>
+ </categories>
+ <categories>
+ <code>2</code>
+ <name>kids</name>
+ <books>
+ <title>Book 3</title>
+ <lang>English</lang>
+ <price>15</price>
+ <editions>2010</editions>
+ </books>
+ </categories>
</bookstore>
- </stores>
+ </stores>
dataSampleAcrossAnchors:
value:
- anchorName: bookstore1
# ============LICENSE_START=======================================================
# Copyright (c) 2022-2025 TechMahindra Ltd.
+# Modifications Copyright (C) 2025 TechMahindra Ltd.
# ================================================================================
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
nodeByDataspaceAndAnchor:
get:
description: Get a node with an option to retrieve all the children for a given anchor and dataspace
+ deprecated: true
tags:
- cps-data
summary: Get a node
--- /dev/null
+# ============LICENSE_START=======================================================
+# Copyright (c) 2025 TechMahindra Ltd.
+# ================================================================================
+# 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=========================================================
+
+nodeByDataspaceAndAnchor:
+ get:
+ description: Get a node with an option to retrieve all the children for a given anchor and dataspace
+ tags:
+ - cps-data
+ summary: Get a node
+ operationId: getNodeByDataspaceAndAnchorV3
+ parameters:
+ - $ref: 'components.yml#/components/parameters/dataspaceNameInPath'
+ - $ref: 'components.yml#/components/parameters/anchorNameInPath'
+ - $ref: 'components.yml#/components/parameters/xpathInQuery'
+ - $ref: 'components.yml#/components/parameters/descendantsInQuery'
+ - $ref: 'components.yml#/components/parameters/contentTypeInHeader'
+ responses:
+ '200':
+ description: OK
+ content:
+ application/json:
+ schema:
+ type: object
+ examples:
+ dataSample:
+ $ref: 'components.yml#/components/examples/dataSampleForV3'
+ application/xml:
+ schema:
+ type: object
+ xml:
+ name: stores
+ examples:
+ dataSample:
+ $ref: 'components.yml#/components/examples/dataSampleXmlForV3'
+ '400':
+ $ref: 'components.yml#/components/responses/BadRequest'
+ '403':
+ $ref: 'components.yml#/components/responses/Forbidden'
+ '500':
+ $ref: 'components.yml#/components/responses/InternalServerError'
+ x-codegen-request-body-name: xpath
\ No newline at end of file
$ref: 'cpsDataV1Deprecated.yml#/nodeByDataspaceAndAnchor'
/v2/dataspaces/{dataspace-name}/anchors/{anchor-name}/node:
- $ref: 'cpsDataV2.yml#/nodeByDataspaceAndAnchor'
+ $ref: 'cpsDataV2Deprecated.yml#/nodeByDataspaceAndAnchor'
+
+ /v3/dataspaces/{dataspace-name}/anchors/{anchor-name}/node:
+ $ref: 'cpsDataV3.yml#/nodeByDataspaceAndAnchor'
/{apiVersion}/dataspaces/{dataspace-name}/anchors/{anchor-name}/nodes:
$ref: 'cpsData.yml#/nodesByDataspaceAndAnchor'
return buildResponseEntity(dataNodesAsMaps, contentType);
}
+ @Override
+ @Timed(value = "cps.data.controller.datanode.get.v3", description = "Time taken to get data node")
+ public ResponseEntity<Object> getNodeByDataspaceAndAnchorV3(final String dataspaceName, final String anchorName,
+ final String xpath,
+ final String fetchDescendantsOptionAsString,
+ final String contentTypeInHeader) {
+ final ContentType contentType = ContentType.fromString(contentTypeInHeader);
+ final FetchDescendantsOption fetchDescendantsOption =
+ FetchDescendantsOption.getFetchDescendantsOption(fetchDescendantsOptionAsString);
+ final Map<String, Object> dataNodesAsMap =
+ cpsFacade.getDataNodesByAnchorV3(dataspaceName, anchorName, xpath, fetchDescendantsOption);
+ return buildResponseEntity(dataNodesAsMap, contentType);
+ }
+
@Override
public ResponseEntity<Object> updateNodeLeaves(final String apiVersion, final String dataspaceName,
final String anchorName, final String nodeData,
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
- private ResponseEntity<Object> buildResponseEntity(final List<Map<String, Object>> dataMaps,
- final ContentType contentType) {
+ private ResponseEntity<Object> buildResponseEntity(final Object dataMaps, final ContentType contentType) {
final String responseData;
if (ContentType.XML.equals(contentType)) {
responseData = XmlFileUtils.convertDataMapsToXml(dataMaps);
def dataNodeBaseEndpointV1
def dataNodeBaseEndpointV2
+ def dataNodeBaseEndpointV3
def dataspaceName = 'my_dataspace'
def anchorName = 'my_anchor'
def noTimestamp = null
def setup() {
dataNodeBaseEndpointV1 = "$basePath/v1/dataspaces/$dataspaceName"
dataNodeBaseEndpointV2 = "$basePath/v2/dataspaces/$dataspaceName"
+ dataNodeBaseEndpointV3 = "$basePath/v3/dataspaces/$dataspaceName"
}
def 'Create a node: #scenario.'() {
'JSON' | MediaType.APPLICATION_JSON || '[{"mocked":"result1"},{"mocked":"result2"}]'
}
+ def 'Get data node with #scenario using V3. output type #scenario.'() {
+ given: 'the service returns data nodes with #scenario'
+ def xpath = 'some xPath'
+ def endpoint = "$dataNodeBaseEndpointV3/anchors/$anchorName/node"
+ when: 'V3 of get request is performed through REST API'
+ def response =
+ mvc.perform(get(endpoint)
+ .contentType(contentType)
+ .param('xpath', xpath)
+ .param('descendants', 'all'))
+ .andReturn().response
+ then: 'the cps service facade is called with the correct parameters and returns some data'
+ 1 * mockCpsFacade.getDataNodesByAnchorV3(dataspaceName, anchorName, xpath, INCLUDE_ALL_DESCENDANTS) >> [books: [[title: 'Book 1'], [title: 'Book 2']]]
+ and: 'a success response is returned'
+ assert response.status == HttpStatus.OK.value()
+ and: 'the response is in the expected format'
+ assert response.contentAsString == expectedResult
+ where: 'the following content types are used'
+ scenario | contentType || expectedResult
+ 'XML' | MediaType.APPLICATION_XML || '<books><title>Book 1</title></books><books><title>Book 2</title></books>'
+ 'JSON' | MediaType.APPLICATION_JSON || '{"books":[{"title":"Book 1"},{"title":"Book 2"}]}'
+ }
+
def 'Update data node leaves: #scenario.'() {
given: 'endpoint to update a node '
def endpoint = "$dataNodeBaseEndpointV1/anchors/$anchorName/nodes"
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2025 Nordix Foundation
+ * Modifications Copyright (C) 2025 TechMahindra Ltd.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
String xpath,
FetchDescendantsOption fetchDescendantsOption);
+ /**
+ * Get data nodes for a given dataspace, anchor and xpath.
+ * This method ensures that list nodes are returned as a single entry with their list items
+ * grouped under the list node name.
+ *
+ *
+ * @param dataspaceName the name of the dataspace
+ * @param anchorName the name of the anchor
+ * @param xpath the xpath
+ * @param fetchDescendantsOption control what level of descendants should be returned
+ * @return a map where each key represents a data node name (e.g., container or list),
+ * and each value is either:
+ * - a leaf values as key-value pairs,
+ * - a nested map (for containers),
+ * - or a list of maps (for lists containing multiple elements)
+ */
+
+ Map<String, Object> getDataNodesByAnchorV3(String dataspaceName,
+ String anchorName,
+ String xpath,
+ FetchDescendantsOption fetchDescendantsOption);
+
/**
* Query the given anchor using a cps path expression.
*
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2025 Nordix Foundation
+ * Modifications Copyright (C) 2025 TechMahindra Ltd.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
return dataMapper.toDataMaps(dataspaceName, anchorName, dataNodes);
}
+ @Override
+ public Map<String, Object> getDataNodesByAnchorV3(final String dataspaceName,
+ final String anchorName,
+ final String xpath,
+ final FetchDescendantsOption fetchDescendantsOption) {
+ final Collection<DataNode> dataNodes = cpsDataService.getDataNodes(dataspaceName, anchorName, xpath,
+ fetchDescendantsOption);
+ return dataMapper.toDataMapForApiV3(dataspaceName, anchorName, dataNodes);
+ }
+
@Override
public List<Map<String, Object>> executeAnchorQuery(final String dataspaceName,
final String anchorName,
* Copyright (C) 2021 Pantheon.tech
* Modifications (C) 2021-2023 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
- * Modifications Copyright (C) 2022-2023 TechMahindra Ltd.
+ * Modifications Copyright (C) 2022-2025 TechMahindra Ltd.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
.putAll(
dataNodes.stream()
.filter(dataNode -> isListElement(dataNode.getXpath()))
- .collect(groupingBy(
- dataNode -> getNodeIdentifier(dataNode.getXpath()),
- mapping(DataMapUtils::toDataMap, toUnmodifiableList())
- ))
+ .collect(groupingBy(DataMapUtils::getNodeIdentifierWithPrefix,
+ mapping(DataMapUtils::toDataMap, toUnmodifiableList())))
).build();
}
}
return dataNodes.stream()
.filter(dataNode -> isContainerNode(dataNode.getXpath()))
- .collect(
- toUnmodifiableMap(
- dataNode -> getNodeIdentifier(dataNode.getXpath()),
- DataMapUtils::toDataMap
- ));
+ .collect(toUnmodifiableMap(DataMapUtils::getNodeIdentifierWithPrefix, DataMapUtils::toDataMap));
}
private static String getNodeIdentifier(String xpath) {
return getNodeIdentifier(xpath);
}
+ private static String getNodeIdentifierWithPrefix(final DataNode dataNode) {
+ return getNodeIdentifierWithPrefix(dataNode.getXpath(), dataNode.getModuleNamePrefix());
+ }
+
private static boolean isContainerNode(final String xpath) {
return !isListElement(xpath);
}
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2025 Nordix Foundation.
+ * Modifications Copyright (C) 2025 TechMahindra Ltd.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import org.onap.cps.api.CpsAnchorService;
import org.onap.cps.api.model.Anchor;
import org.onap.cps.api.model.DataNode;
+import org.onap.cps.impl.DataNodeBuilder;
import org.springframework.stereotype.Service;
@Service
return dataNodesAsMaps;
}
+ /**
+ * Convert a collection of data nodes to a list of data maps.
+ * List nodes are returned as a map entry where the key is the list node name and the value is
+ * a list of maps, each representing an individual list item. Container nodes are returned as
+ * nested maps under their respective parent node names.
+ *
+ * @param dataspaceName the name dataspace name
+ * @param anchorName the name of the anchor
+ * @param dataNodes the data nodes to convert
+ * @return a map reflecting the complete data node structure, where:
+ * - leaf values are returned as key-value pairs,
+ * - containers are returned as nested maps,
+ * - and list nodes are grouped under a single key as a list of map entries.
+ */
+
+ public Map<String, Object> toDataMapForApiV3(final String dataspaceName, final String anchorName,
+ final Collection<DataNode> dataNodes) {
+ final Anchor anchor = cpsAnchorService.getAnchor(dataspaceName, anchorName);
+ dataNodes.forEach(dataNode ->
+ dataNode.setModuleNamePrefix(prefixResolver.getPrefix(anchor, dataNode.getXpath())));
+ final DataNode containerNode = new DataNodeBuilder().withChildDataNodes(dataNodes).build();
+ return DataMapUtils.toDataMap(containerNode);
+ }
+
/**
* Converts list of attributes values to a list of data maps.
* @param attributeName attribute name
* ============LICENSE_START=======================================================
* Copyright (C) 2022 Deutsche Telekom AG
* Modifications Copyright (C) 2023-2024 Nordix Foundation.
- * Modifications Copyright (C) 2024 TechMahindra Ltd.
+ * Modifications Copyright (C) 2024-2025 TechMahindra Ltd.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* @return XML string representation of the data maps
*/
@SuppressFBWarnings(value = "DCN_NULLPOINTER_EXCEPTION")
- public static String convertDataMapsToXml(final List<Map<String, Object>> dataMaps) {
+ public static String convertDataMapsToXml(final Object dataMaps) {
try {
final DocumentBuilder documentBuilder = getDocumentBuilderFactory().newDocumentBuilder();
final Document document = documentBuilder.newDocument();
final DocumentFragment documentFragment = document.createDocumentFragment();
- for (final Map<String, Object> dataMap : dataMaps) {
- createXmlElements(document, documentFragment, dataMap);
+ if (dataMaps instanceof Map) {
+ createXmlElements(document, documentFragment, (Map<String, Object>) dataMaps);
+ } else if (dataMaps instanceof List) {
+ for (final Map<String, Object> dataMap : (List<Map<String, Object>>) dataMaps) {
+ createXmlElements(document, documentFragment, dataMap);
+ }
+ } else {
+ throw new IllegalArgumentException("Unsupported data type for XML conversion");
}
return transformFragmentToString(documentFragment);
} catch (final DOMException | NullPointerException | ParserConfigurationException | TransformerException
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2025 Nordix Foundation
+ * Modifications Copyright (C) 2025 TechMahindra Ltd.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
assert result[1].keySet()[0] == 'prefix2:path2'
}
+ def 'Get multiple data nodes V3.'() {
+ when: 'get data node by dataspace and anchor'
+ def result = objectUnderTest.getDataNodesByAnchorV3('my dataspace', 'my anchor', 'my path', myFetchDescendantsOption)
+ then: 'all nodes (from the data service result) are returned'
+ assert result.size() == 2
+ }
+
def 'Execute anchor query with attribute-axis.'() {
given: 'the cps query service returns two attribute values'
mockCpsQueryService.queryDataLeaf('my dataspace', 'my anchor', '/my/path/@myAttribute', Object) >> ['value1', 'value2']
* ============LICENSE_START=======================================================
* Copyright (C) 2022 Deutsche Telekom AG
* Modifications Copyright (c) 2023-2024 Nordix Foundation
- * Modifications Copyright (C) 2024 TechMahindra Ltd.
+ * Modifications Copyright (C) 2024-2025 TechMahindra Ltd.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
then: 'the result contains the expected XML'
assert result == expectedXmlOutput
where:
- scenario | dataMaps || expectedXmlOutput
- 'single XML branch' | [['branch': ['name': 'Left', 'nest': ['name': 'Small', 'birds': ['Sparrow', 'Owl']]]]] || '<branch><name>Left</name><nest><name>Small</name><birds>Sparrow</birds><birds>Owl</birds></nest></branch>'
- 'nested XML branch' | [['test-tree': [branch: [name: 'Left', nest: [name: 'Small', birds: 'Sparrow']]]]] || '<test-tree><branch><name>Left</name><nest><name>Small</name><birds>Sparrow</birds></nest></branch></test-tree>'
- 'list of branch within a test tree' | [['test-tree': [branch: [[name: 'Left', nest: [name: 'Small', birds: 'Sparrow']], [name: 'Right', nest: [name: 'Big', birds: 'Owl']]]]]] || '<test-tree><branch><name>Left</name><nest><name>Small</name><birds>Sparrow</birds></nest></branch><branch><name>Right</name><nest><name>Big</name><birds>Owl</birds></nest></branch></test-tree>'
- 'list of birds under a nest' | [['nest': ['name': 'Small', 'birds': ['Sparrow']]]] || '<nest><name>Small</name><birds>Sparrow</birds></nest>'
+ scenario | dataMaps || expectedXmlOutput
+ 'single XML branch' | ['branch': ['name': 'Left']] || '<branch><name>Left</name></branch>'
+ 'nested XML branch' | [['test-tree': [branch: [name: 'Left', nest: [name: 'Small', birds: 'Sparrow']]]]] || '<test-tree><branch><name>Left</name><nest><name>Small</name><birds>Sparrow</birds></nest></branch></test-tree>'
+ 'list of branch within a test tree' | [['test-tree': [branch: [[name: 'Left', nest: [name: 'Small', birds: 'Sparrow']], [name: 'Right', nest: [name: 'Big', birds: 'Owl']]]]]] || '<test-tree><branch><name>Left</name><nest><name>Small</name><birds>Sparrow</birds></nest></branch><branch><name>Right</name><nest><name>Big</name><birds>Owl</birds></nest></branch></test-tree>'
+ 'list of birds under a nest' | [['nest': ['name': 'Small', 'birds': ['Sparrow']]]] || '<nest><name>Small</name><birds>Sparrow</birds></nest>'
}
def 'Convert data maps to XML with null or empty maps and lists'() {
'mixed list with null values' | [['branch': ['name': 'Left', 'nest': ['name': 'Small', 'birds': [null, 'Sparrow', null]]]]] || '<branch><name>Left</name><nest><name>Small</name><birds/><birds>Sparrow</birds><birds/></nest></branch>'
}
+ def 'Converting data maps to xml with unsupported input type'() {
+ when: 'a non-Map and non-List object is passed'
+ convertDataMapsToXml("invalid")
+ then: 'an IllegalArgumentException is thrown'
+ def exception = thrown(IllegalArgumentException)
+ assert exception.message == "Unsupported data type for XML conversion"
+ }
+
def 'Converting data maps to xml with no data'() {
given: 'A list of maps where entry is null'
def dataMapWithNull = [null]
version: 3.6.2
servers:
- url: /cps/api
-security:
-- basicAuth: []
tags:
- description: cps Admin
name: cps-admin
x-codegen-request-body-name: xpath
/v2/dataspaces/{dataspace-name}/anchors/{anchor-name}/node:
get:
+ deprecated: true
description: Get a node with an option to retrieve all the children for a given
anchor and dataspace
operationId: getNodeByDataspaceAndAnchorV2
tags:
- cps-data
x-codegen-request-body-name: xpath
+ /v3/dataspaces/{dataspace-name}/anchors/{anchor-name}/node:
+ get:
+ description: Get a node with an option to retrieve all the children for a given
+ anchor and dataspace
+ operationId: getNodeByDataspaceAndAnchorV3
+ parameters:
+ - description: dataspace-name
+ in: path
+ name: dataspace-name
+ required: true
+ schema:
+ example: my-dataspace
+ type: string
+ - description: anchor-name
+ in: path
+ name: anchor-name
+ required: true
+ schema:
+ example: my-anchor
+ type: string
+ - description: "For more details on xpath, please refer https://docs.onap.org/projects/onap-cps/en/latest/xpath.html"
+ examples:
+ container xpath:
+ value: /shops/bookstore
+ list attributes xpath:
+ value: "/shops/bookstore/categories[@code=1]"
+ in: query
+ name: xpath
+ required: false
+ schema:
+ default: /
+ type: string
+ - description: "Number of descendants to query. Allowed values are 'none', 'all',\
+ \ 'direct', 1 (for direct), -1 (for all), 0 (for none) and any positive\
+ \ number."
+ in: query
+ name: descendants
+ required: false
+ schema:
+ default: none
+ example: "3"
+ type: string
+ - description: Content type in header
+ in: header
+ name: Content-Type
+ required: false
+ schema:
+ default: application/json
+ enum:
+ - application/json
+ - application/xml
+ type: string
+ responses:
+ "200":
+ content:
+ application/json:
+ examples:
+ dataSample:
+ $ref: '#/components/examples/dataSampleForV3'
+ value: null
+ schema:
+ type: object
+ application/xml:
+ examples:
+ dataSample:
+ $ref: '#/components/examples/dataSampleXmlForV3'
+ value: null
+ schema:
+ type: object
+ xml:
+ name: stores
+ description: OK
+ "400":
+ content:
+ application/json:
+ example:
+ status: 400
+ message: Bad Request
+ details: The provided request is not valid
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ description: Bad Request
+ "403":
+ content:
+ application/json:
+ example:
+ status: 403
+ message: Request Forbidden
+ details: This request is forbidden
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ description: Forbidden
+ "500":
+ content:
+ application/json:
+ example:
+ status: 500
+ message: Internal Server Error
+ details: Internal Server Error occurred
+ schema:
+ $ref: '#/components/schemas/ErrorMessage'
+ description: Internal Server Error
+ summary: Get a node
+ tags:
+ - cps-data
+ x-codegen-request-body-name: xpath
/{apiVersion}/dataspaces/{dataspace-name}/anchors/{anchor-name}/nodes:
delete:
description: Delete a datanode for a given dataspace and anchor given a node
categories:
- code: 1
name: SciFi
+ - books:
+ - title: Book 1
+ lang: N/A
+ price: 11
+ editions:
+ - 2009
+ - books:
+ - title: Book 2
+ lang: German
+ price: 39
+ editions:
+ - 2007
+ - 2013
+ - 2021
- code: 2
name: kids
+ - books:
+ - title: Book 3
+ lang: English
+ price: 15
+ editions:
+ - 2010
dataSampleXml:
value: <stores xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <bookstore xmlns="org:onap:ccsdk:sample">
<bookstore-name>Chapters</bookstore-name> <categories> <code>1</code> <name>SciFi</name>
- <code>2</code> <name>kids</name> </categories> </bookstore> </stores>
+ </categories> <categories> <books> <title>Book 1</title> <lang>N/A</lang>
+ <price>11</price> <editions>2009</editions> </books> </categories> <categories>
+ <books> <title>Book 2</title> <lang>German</lang> <price>39</price> <editions>2007</editions>
+ <editions>2013</editions> <editions>2021</editions> </books> </categories>
+ <categories> <code>2</code> <name>kids </name> <books> <title>Book 3</title>
+ <lang>English</lang> <price>15</price> <editions>2010</editions> </books>
+ </categories> </bookstore> </stores>
+ dataSampleForV3:
+ value:
+ test:bookstore:
+ bookstore-name: Chapters
+ categories:
+ - code: 1
+ name: SciFi
+ books:
+ - title: Book 1
+ lang: N/A
+ price: 11
+ editions:
+ - 2009
+ - title: Book 2
+ lang: German
+ price: 39
+ editions:
+ - 2007
+ - 2013
+ - 2021
+ - code: 2
+ name: kids
+ books:
+ - title: Book 3
+ lang: English
+ price: 15
+ editions:
+ - 2010
+ dataSampleXmlForV3:
+ value: <stores xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <bookstore xmlns="org:onap:ccsdk:sample">
+ <bookstore-name>Chapters</bookstore-name> <categories> <code>1</code> <name>SciFi</name>
+ <books> <title>Book 1</title> <lang>N/A</lang> <price>11</price> <editions>2009</editions>
+ </books> <books> <title>Book 2</title> <lang>German</lang> <price>39</price>
+ <editions>2007</editions> <editions>2013</editions> <editions>2021</editions>
+ </books> </categories> <categories> <code>2</code> <name>kids</name> <books>
+ <title>Book 3</title> <lang>English</lang> <price>15</price> <editions>2010</editions>
+ </books> </categories> </bookstore> </stores>
deltaReportSample:
value:
- action: create
required:
- json
type: object
- securitySchemes:
- basicAuth:
- scheme: basic
- type: http
version: 3.6.2
servers:
- url: /ncmpInventory
-security:
-- basicAuth: []
paths:
/v1/ch:
post:
moduleName:
example: my-module
type: string
- securitySchemes:
- basicAuth:
- scheme: basic
- type: http
version: 3.6.2
servers:
- url: /ncmp
-security:
-- basicAuth: []
paths:
/v1/ch/{cm-handle}/data/ds/{datastore-name}:
delete:
example: Bad Request
type: string
type: object
- securitySchemes:
- basicAuth:
- scheme: basic
- type: http
with open(metrics_file, 'r') as f:
lines = f.readlines()
- expected_number_of_metrics = 57
+ expected_number_of_metrics = 58
expected_number_of_lines = expected_number_of_metrics + 1 # Header
self.assertEqual(len(lines), expected_number_of_lines, f"metrics.csv does not have {expected_number_of_lines} lines.")