From: Rudrangi Anupriya Date: Fri, 1 Nov 2024 18:46:58 +0000 (+0530) Subject: XML content support on get a node X-Git-Tag: 3.5.5~38^2 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=14d6a9b990005965307bbab66b0ffe15327a8758;p=cps.git XML content support on get a node Here to bring Support for XML Response Entity In GET A NODE - Made changes in components.yml to support contentType as application/xml - Add ContentTypeInheadr in cpsDataV2.yml to support application/xml - Add contentTypeInHeader parameter to accept xml in DataRestController.java - Implemented Logic to convert DataMaps To XML Data - written testcase for above changes made Issue-ID: CPS-2280 Change-Id: Ibe7ffb66ccbb03703626132c6d5c2eade0e7ab4b Signed-off-by: Rudrangi Anupriya --- diff --git a/cps-rest/docs/openapi/components.yml b/cps-rest/docs/openapi/components.yml index 40f0e170ff..728295fd31 100644 --- a/cps-rest/docs/openapi/components.yml +++ b/cps-rest/docs/openapi/components.yml @@ -293,7 +293,9 @@ components: description: Content type in header schema: type: string - example: 'application/json' + enum: + - application/json + - application/xml required: true descendantsInQuery: name: descendants diff --git a/cps-rest/docs/openapi/cpsDataV2.yml b/cps-rest/docs/openapi/cpsDataV2.yml index d5a8ef3891..999c5b2c19 100644 --- a/cps-rest/docs/openapi/cpsDataV2.yml +++ b/cps-rest/docs/openapi/cpsDataV2.yml @@ -28,6 +28,7 @@ nodeByDataspaceAndAnchor: - $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 @@ -38,6 +39,14 @@ nodeByDataspaceAndAnchor: examples: dataSample: $ref: 'components.yml#/components/examples/dataSample' + application/xml: + schema: + type: object + xml: + name: stores + examples: + dataSample: + $ref: 'components.yml#/components/examples/dataSampleXml' '400': $ref: 'components.yml#/components/responses/BadRequest' '403': diff --git a/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java b/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java index 7390afcf98..6d22581845 100755 --- a/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java +++ b/cps-rest/src/main/java/org/onap/cps/rest/controller/DataRestController.java @@ -48,8 +48,8 @@ import org.onap.cps.utils.ContentType; import org.onap.cps.utils.DataMapUtils; import org.onap.cps.utils.JsonObjectMapper; import org.onap.cps.utils.PrefixResolver; +import org.onap.cps.utils.XmlFileUtils; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -75,7 +75,7 @@ public class DataRestController implements CpsDataApi { final String contentTypeInHeader, final String nodeData, final String parentNodeXpath, final Boolean dryRunEnabled, final String observedTimestamp) { - final ContentType contentType = getContentTypeFromHeader(contentTypeInHeader); + final ContentType contentType = ContentType.fromString(contentTypeInHeader); if (Boolean.TRUE.equals(dryRunEnabled)) { cpsDataService.validateData(dataspaceName, anchorName, parentNodeXpath, nodeData, contentType); return ResponseEntity.ok().build(); @@ -105,7 +105,7 @@ public class DataRestController implements CpsDataApi { final String anchorName, final String parentNodeXpath, final String contentTypeInHeader, final String nodeData, final String observedTimestamp) { - final ContentType contentType = getContentTypeFromHeader(contentTypeInHeader); + final ContentType contentType = ContentType.fromString(contentTypeInHeader); cpsDataService.saveListElements(dataspaceName, anchorName, parentNodeXpath, nodeData, toOffsetDateTime(observedTimestamp), contentType); return new ResponseEntity<>(HttpStatus.CREATED); @@ -129,8 +129,9 @@ public class DataRestController implements CpsDataApi { @Timed(value = "cps.data.controller.datanode.get.v2", description = "Time taken to get data node") public ResponseEntity getNodeByDataspaceAndAnchorV2(final String dataspaceName, final String anchorName, - final String xpath, + final String contentTypeInHeader, final String xpath, final String fetchDescendantsOptionAsString) { + final ContentType contentType = ContentType.fromString(contentTypeInHeader); final FetchDescendantsOption fetchDescendantsOption = FetchDescendantsOption.getFetchDescendantsOption(fetchDescendantsOptionAsString); final Collection dataNodes = cpsDataService.getDataNodes(dataspaceName, anchorName, xpath, @@ -142,7 +143,7 @@ public class DataRestController implements CpsDataApi { final Map dataMap = DataMapUtils.toDataMapWithIdentifier(dataNode, prefix); dataMaps.add(dataMap); } - return new ResponseEntity<>(jsonObjectMapper.asJsonString(dataMaps), HttpStatus.OK); + return buildResponseEntity(dataMaps, contentType); } @Override @@ -150,7 +151,7 @@ public class DataRestController implements CpsDataApi { final String anchorName, final String contentTypeInHeader, final String nodeData, final String parentNodeXpath, final String observedTimestamp) { - final ContentType contentType = getContentTypeFromHeader(contentTypeInHeader); + final ContentType contentType = ContentType.fromString(contentTypeInHeader); cpsDataService.updateNodeLeaves(dataspaceName, anchorName, parentNodeXpath, nodeData, toOffsetDateTime(observedTimestamp), contentType); return new ResponseEntity<>(HttpStatus.OK); @@ -161,7 +162,7 @@ public class DataRestController implements CpsDataApi { final String anchorName, final String contentTypeInHeader, final String nodeData, final String parentNodeXpath, final String observedTimestamp) { - final ContentType contentType = getContentTypeFromHeader(contentTypeInHeader); + final ContentType contentType = ContentType.fromString(contentTypeInHeader); cpsDataService.updateDataNodeAndDescendants(dataspaceName, anchorName, parentNodeXpath, nodeData, toOffsetDateTime(observedTimestamp), contentType); return new ResponseEntity<>(HttpStatus.OK); @@ -219,12 +220,19 @@ public class DataRestController implements CpsDataApi { final List deltaBetweenAnchors = cpsDataService.getDeltaByDataspaceAndAnchors(dataspaceName, sourceAnchorName, - targetAnchorName, xpath, fetchDescendantsOption); + targetAnchorName, xpath, fetchDescendantsOption); return new ResponseEntity<>(jsonObjectMapper.asJsonString(deltaBetweenAnchors), HttpStatus.OK); } - private static ContentType getContentTypeFromHeader(final String contentTypeInHeader) { - return contentTypeInHeader.contains(MediaType.APPLICATION_XML_VALUE) ? ContentType.XML : ContentType.JSON; + ResponseEntity buildResponseEntity(final List> dataMaps, + final ContentType contentType) { + final String responseData; + if (contentType == ContentType.XML) { + responseData = XmlFileUtils.convertDataMapsToXml(dataMaps); + } else { + responseData = jsonObjectMapper.asJsonString(dataMaps); + } + return new ResponseEntity<>(responseData, HttpStatus.OK); } private static boolean isRootXpath(final String xpath) { diff --git a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy index 705c2fee91..27738b07c6 100755 --- a/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy +++ b/cps-rest/src/test/groovy/org/onap/cps/rest/controller/DataRestControllerSpec.groovy @@ -314,7 +314,9 @@ class DataRestControllerSpec extends Specification { mockCpsDataService.getDataNodes(dataspaceName, anchorName, xpath, OMIT_DESCENDANTS) >> [dataNodeWithLeavesNoChildren, dataNodeWithLeavesNoChildren2] when: 'V2 of get request is performed through REST API' def response = - mvc.perform(get(endpoint).param('xpath', xpath)) + mvc.perform(get(endpoint) + .contentType(MediaType.APPLICATION_JSON) + .param('xpath', xpath)) .andReturn().response then: 'a success response is returned' response.status == HttpStatus.OK.value() @@ -326,6 +328,21 @@ class DataRestControllerSpec extends Specification { assert numberOfDataTrees == 2 } + def 'Get all the data trees as XML with root node xPath using V2'() { + given: 'the service returns all data node leaves' + def xpath = '/' + def endpoint = "$dataNodeBaseEndpointV2/anchors/$anchorName/node" + mockCpsDataService.getDataNodes(dataspaceName, anchorName, xpath, OMIT_DESCENDANTS) >> [dataNodeWithLeavesNoChildren] + when: 'V2 of get request is performed through REST API with XML content type' + def response = + mvc.perform(get(endpoint).contentType(MediaType.APPLICATION_XML).param('xpath', xpath)) + .andReturn().response + then: 'a success response is returned' + response.status == HttpStatus.OK.value() + and: 'the response contains the datanode in XML format' + response.getContentAsString() == 'valueleaveListElement1leaveListElement2' + } + def 'Get data node with #scenario using V2.'() { given: 'the service returns data nodes with #scenario' def xpath = 'some xPath' @@ -335,6 +352,7 @@ class DataRestControllerSpec extends Specification { def response = mvc.perform( get(endpoint) + .contentType(MediaType.APPLICATION_JSON) .param('xpath', xpath) .param('descendants', includeDescendantsOption)) .andReturn().response @@ -361,6 +379,7 @@ class DataRestControllerSpec extends Specification { def response = mvc.perform( get(endpoint) + .contentType(MediaType.APPLICATION_JSON) .param('xpath', xpath) .param('descendants', '2')) .andReturn().response diff --git a/cps-service/pom.xml b/cps-service/pom.xml index c7a3666a07..fdd6272660 100644 --- a/cps-service/pom.xml +++ b/cps-service/pom.xml @@ -5,6 +5,7 @@ Modifications Copyright (C) 2021 Bell Canada. Modifications Copyright (C) 2021 Pantheon.tech Modifications Copyright (C) 2022 Deutsche Telekom AG + Modifications Copyright (C) 2024 TechMahindra Ltd. ================================================================================ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -192,5 +193,9 @@ spring-kafka-test test + + org.springframework + spring-web + diff --git a/cps-service/src/main/java/org/onap/cps/utils/ContentType.java b/cps-service/src/main/java/org/onap/cps/utils/ContentType.java index f888504843..eb8e592d9b 100644 --- a/cps-service/src/main/java/org/onap/cps/utils/ContentType.java +++ b/cps-service/src/main/java/org/onap/cps/utils/ContentType.java @@ -1,6 +1,7 @@ /* * ============LICENSE_START======================================================= * Copyright (C) 2022 Deutsche Telekom AG + * Modifications Copyright (C) 2024 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +21,14 @@ package org.onap.cps.utils; +import org.springframework.http.MediaType; + public enum ContentType { JSON, - XML + XML; + + public static ContentType fromString(final String contentTypeAsString) { + return contentTypeAsString.contains(MediaType.APPLICATION_XML_VALUE) ? XML : JSON; + } + } diff --git a/cps-service/src/main/java/org/onap/cps/utils/XmlFileUtils.java b/cps-service/src/main/java/org/onap/cps/utils/XmlFileUtils.java index 7a6d0bb3d5..94b97bd88f 100644 --- a/cps-service/src/main/java/org/onap/cps/utils/XmlFileUtils.java +++ b/cps-service/src/main/java/org/onap/cps/utils/XmlFileUtils.java @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2022 Deutsche Telekom AG * Modifications Copyright (C) 2023-2024 Nordix Foundation. + * Modifications Copyright (C) 2024 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,11 +22,13 @@ package org.onap.cps.utils; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.StringWriter; import java.nio.charset.StandardCharsets; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -33,6 +36,7 @@ import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; @@ -40,10 +44,14 @@ import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import lombok.AccessLevel; import lombok.NoArgsConstructor; +import org.onap.cps.spi.exceptions.DataValidationException; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.w3c.dom.DOMException; import org.w3c.dom.Document; +import org.w3c.dom.DocumentFragment; import org.w3c.dom.Element; +import org.w3c.dom.Node; import org.xml.sax.SAXException; @NoArgsConstructor(access = AccessLevel.PRIVATE) @@ -156,6 +164,85 @@ public class XmlFileUtils { return document; } + /** + * Convert a list of data maps to XML format. + * + * @param dataMaps List of data maps to convert + * @return XML string representation of the data maps + */ + @SuppressFBWarnings(value = "DCN_NULLPOINTER_EXCEPTION") + public static String convertDataMapsToXml(final List> dataMaps) { + try { + final DocumentBuilder documentBuilder = getDocumentBuilderFactory().newDocumentBuilder(); + final Document document = documentBuilder.newDocument(); + final DocumentFragment documentFragment = document.createDocumentFragment(); + for (final Map dataMap : dataMaps) { + createXmlElements(document, documentFragment, dataMap); + } + return transformFragmentToString(documentFragment); + } catch (final DOMException | NullPointerException | ParserConfigurationException | TransformerException + exception) { + throw new DataValidationException( + "Data Validation Failed", "Failed to parse xml data: " + exception.getMessage(), exception); + } + } + + private static void createXmlElements(final Document document, final Node parentNode, + final Map dataMap) { + for (final Map.Entry mapEntry : dataMap.entrySet()) { + if (mapEntry.getValue() instanceof List) { + appendList(document, parentNode, mapEntry); + } else if (mapEntry.getValue() instanceof Map) { + appendMap(document, parentNode, mapEntry); + } else { + appendObject(document, parentNode, mapEntry); + } + } + } + + private static void appendList(final Document document, final Node parentNode, + final Map.Entry mapEntry) { + final List list = (List) mapEntry.getValue(); + if (list.isEmpty()) { + final Element listElement = document.createElement(mapEntry.getKey()); + parentNode.appendChild(listElement); + } else { + for (final Object element : list) { + final Element listElement = document.createElement(mapEntry.getKey()); + if (element instanceof Map) { + createXmlElements(document, listElement, (Map) element); + } else { + listElement.appendChild(document.createTextNode(element.toString())); + } + parentNode.appendChild(listElement); + } + } + } + + private static void appendMap(final Document document, final Node parentNode, + final Map.Entry mapEntry) { + final Element childElement = document.createElement(mapEntry.getKey()); + createXmlElements(document, childElement, (Map) mapEntry.getValue()); + parentNode.appendChild(childElement); + } + + private static void appendObject(final Document document, final Node parentNode, + final Map.Entry mapEntry) { + final Element element = document.createElement(mapEntry.getKey()); + element.appendChild(document.createTextNode(mapEntry.getValue().toString())); + parentNode.appendChild(element); + } + + private static String transformFragmentToString(final DocumentFragment documentFragment) + throws TransformerException { + final Transformer transformer = getTransformerFactory().newTransformer(); + transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + final StringWriter writer = new StringWriter(); + final StreamResult result = new StreamResult(writer); + transformer.transform(new DOMSource(documentFragment), result); + return writer.toString(); + } + private static DocumentBuilderFactory getDocumentBuilderFactory() { if (isNewDocumentBuilderFactoryInstance) { diff --git a/cps-service/src/test/groovy/org/onap/cps/utils/ContentTypeSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/utils/ContentTypeSpec.groovy new file mode 100644 index 0000000000..cada33ef06 --- /dev/null +++ b/cps-service/src/test/groovy/org/onap/cps/utils/ContentTypeSpec.groovy @@ -0,0 +1,37 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2024 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========================================================= + */ + +package org.onap.cps.utils; + +import spock.lang.Specification; +import org.springframework.http.MediaType + + +class ContentTypeSpec extends Specification { + + def 'Should return correct ContentType based on given input.'() { + given: 'contentType fromString method converts the input string as expectedContentType' + ContentType.fromString(contentTypeString) == expectedContentType + where: + contentTypeString || expectedContentType + MediaType.APPLICATION_XML_VALUE || ContentType.XML + MediaType.APPLICATION_JSON_VALUE || ContentType.JSON + } + +} diff --git a/cps-service/src/test/groovy/org/onap/cps/utils/XmlFileUtilsSpec.groovy b/cps-service/src/test/groovy/org/onap/cps/utils/XmlFileUtilsSpec.groovy index dc6027de25..3b21145293 100644 --- a/cps-service/src/test/groovy/org/onap/cps/utils/XmlFileUtilsSpec.groovy +++ b/cps-service/src/test/groovy/org/onap/cps/utils/XmlFileUtilsSpec.groovy @@ -2,6 +2,7 @@ * ============LICENSE_START======================================================= * Copyright (C) 2022 Deutsche Telekom AG * Modifications Copyright (c) 2023-2024 Nordix Foundation + * Modifications Copyright (C) 2024 TechMahindra Ltd. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,10 +22,14 @@ package org.onap.cps.utils import org.onap.cps.TestUtils +import org.onap.cps.spi.exceptions.DataValidationException import org.onap.cps.yang.YangTextSchemaSourceSetBuilder +import org.w3c.dom.DOMException import org.xml.sax.SAXParseException import spock.lang.Specification +import static org.onap.cps.utils.XmlFileUtils.convertDataMapsToXml + class XmlFileUtilsSpec extends Specification { def 'Parse a valid xml content #scenario'(){ @@ -68,4 +73,56 @@ class XmlFileUtilsSpec extends Specification { 'without root data node' | 'SmallSparrow' | '/test-tree/branch[@name=\'Branch\']' || 'BranchSmallSparrow' } + def 'Convert data maps to XML #scenario'() { + when: 'data maps are converted to XML' + def result = convertDataMapsToXml(dataMaps) + 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']]]]] || 'LeftSmallSparrowOwl' + 'nested XML branch' | [['test-tree': [branch: [name: 'Left', nest: [name: 'Small', birds: 'Sparrow']]]]] || 'LeftSmallSparrow' + 'list of branch within a test tree' | [['test-tree': [branch: [[name: 'Left', nest: [name: 'Small', birds: 'Sparrow']], [name: 'Right', nest: [name: 'Big', birds: 'Owl']]]]]] || 'LeftSmallSparrowRightBigOwl' + 'list of birds under a nest' | [['nest': ['name': 'Small', 'birds': ['Sparrow']]]] || 'SmallSparrow' + 'XML Content map with null key/value' | [['test-tree': [branch: [name: 'Left', nest: []]]]] || 'Left' + 'XML Content list is empty' | [['nest': ['name': 'Small', 'birds': []]]] || 'Small' + 'XML with mixed content in list' | [['branch': ['name': 'Left', 'nest': ['name': 'Small', 'birds': ['', 'Sparrow']]]]] || 'LeftSmallSparrow' + } + + def 'Convert data maps to XML with null or empty maps and lists'() { + when: 'data maps with empty content are converted to XML' + def result = convertDataMapsToXml(dataMaps) + then: 'the result contains the expected XML or handles nulls correctly' + assert result == expectedXmlOutput + where: + scenario | dataMaps || expectedXmlOutput + 'null entry in map' | [['branch': []]] || '' + 'list with null object' | [['branch': [name: 'Left', nest: [name: 'Small', birds: []]]]] || 'LeftSmall' + 'list containing null list' | [['test-tree': [branch: '']]] || '' + 'nested map with null values' | [['test-tree': [branch: [name: 'Left', nest: '']]]] || 'Left' + } + + def 'Converting data maps to xml with no data'() { + given: 'A list of maps where entry is null' + def dataMapWithNull = [null] + when: 'convert the dataMaps to XML' + convertDataMapsToXml(dataMapWithNull) + then: 'a validation exception is thrown' + def exception = thrown(DataValidationException) + and:'the cause is a null pointer exception' + assert exception.cause instanceof NullPointerException + } + + def 'Converting data maps to xml with document syntax error'() { + given: 'A list of maps with an invalid entry' + def dataMap = [['invalid': 'value']] + when: 'convert the dataMaps to XML' + convertDataMapsToXml(dataMap) + then: 'a validation exception is thrown' + def exception = thrown(DataValidationException) + and:'the cause is a document object model exception' + assert exception.cause instanceof DOMException + + } + } diff --git a/docs/api/swagger/cps/openapi.yaml b/docs/api/swagger/cps/openapi.yaml index 3069b18d1e..3f889c1e6c 100644 --- a/docs/api/swagger/cps/openapi.yaml +++ b/docs/api/swagger/cps/openapi.yaml @@ -1162,6 +1162,15 @@ paths: default: none example: "3" type: string + - description: Content type in header + in: header + name: Content-Type + required: true + schema: + enum: + - application/json + - application/xml + type: string responses: "200": content: @@ -1172,6 +1181,15 @@ paths: value: null schema: type: object + application/xml: + examples: + dataSample: + $ref: '#/components/examples/dataSampleXml' + value: null + schema: + type: object + xml: + name: stores description: OK "400": content: @@ -1347,7 +1365,9 @@ paths: name: Content-Type required: true schema: - example: application/json + enum: + - application/json + - application/xml type: string requestBody: content: @@ -1472,7 +1492,9 @@ paths: name: Content-Type required: true schema: - example: application/json + enum: + - application/json + - application/xml type: string requestBody: content: @@ -1597,7 +1619,9 @@ paths: name: Content-Type required: true schema: - example: application/json + enum: + - application/json + - application/xml type: string requestBody: content: @@ -1788,7 +1812,9 @@ paths: name: Content-Type required: true schema: - example: application/json + enum: + - application/json + - application/xml type: string requestBody: content: @@ -2543,6 +2569,16 @@ components: default: none example: "3" type: string + contentTypeInHeader: + description: Content type in header + in: header + name: Content-Type + required: true + schema: + enum: + - application/json + - application/xml + type: string observedTimestampInQuery: description: observed-timestamp in: query @@ -2551,14 +2587,6 @@ components: schema: example: 2021-03-21T00:10:34.030-0100 type: string - contentTypeInHeader: - description: Content type in header - in: header - name: Content-Type - required: true - schema: - example: application/json - type: string dryRunInQuery: description: "Boolean flag to validate data, without persisting it. Default\ \ value is set to false." diff --git a/docs/api/swagger/ncmp/openapi-inventory.yaml b/docs/api/swagger/ncmp/openapi-inventory.yaml index a2c7af6fda..8552ad53e3 100644 --- a/docs/api/swagger/ncmp/openapi-inventory.yaml +++ b/docs/api/swagger/ncmp/openapi-inventory.yaml @@ -131,9 +131,19 @@ paths: - network-cm-proxy-inventory /v1/ch/searches: post: - description: "Query and get CMHandleIds for additional properties, public properties\ - \ and registered DMI plugin (DMI plugin, DMI data plugin, DMI model plugin)." + description: "Query and get CMHandle references for additional properties, public\ + \ properties and registered DMI plugin (DMI plugin, DMI data plugin, DMI model\ + \ plugin)." operationId: searchCmHandleIds + parameters: + - description: Boolean parameter to determine if returned value(s) will be cmHandle + Ids or Alternate Ids for a given query + in: query + name: outputAlternateId + required: false + schema: + default: false + type: boolean requestBody: content: application/json: @@ -182,6 +192,15 @@ components: schema: example: my-dmi-plugin type: string + outputAlternateIdOptionInQuery: + description: Boolean parameter to determine if returned value(s) will be cmHandle + Ids or Alternate Ids for a given query + in: query + name: outputAlternateId + required: false + schema: + default: false + type: boolean responses: NoContent: content: {} diff --git a/docs/api/swagger/ncmp/openapi.yaml b/docs/api/swagger/ncmp/openapi.yaml index f93395a6db..aa732c8566 100644 --- a/docs/api/swagger/ncmp/openapi.yaml +++ b/docs/api/swagger/ncmp/openapi.yaml @@ -1129,7 +1129,7 @@ paths: - network-cm-proxy /v1/ch/id-searches: post: - description: Execute cm handle query search and return a list of cm handle ids. + description: Execute cm handle query search and return a list of cm handle references. Any number of conditions can be applied. To be included in the result a cm-handle must fulfill ALL the conditions. An empty collection will be returned in the case that the cm handle does not match a condition. For more on cm handle @@ -1140,6 +1140,15 @@ paths: Path Read the Docs. The cm handle ancestor is automatically returned for this query. operationId: searchCmHandleIds + parameters: + - description: Boolean parameter to determine if returned value(s) will be cmHandle + Ids or Alternate Ids for a given query + in: query + name: outputAlternateId + required: false + schema: + default: false + type: boolean requestBody: content: application/json: @@ -1608,6 +1617,15 @@ components: schema: example: 2024-01-22 type: string + outputAlternateIdOptionInQuery: + description: Boolean parameter to determine if returned value(s) will be cmHandle + Ids or Alternate Ids for a given query + in: query + name: outputAlternateId + required: false + schema: + default: false + type: boolean dataSyncEnabled: description: Is used to enable or disable the data synchronization flag in: query