From d5021f65f3d4a73b60d6ae690f1d69a9a839ecb9 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Fri, 13 Aug 2021 22:28:24 +0200 Subject: [PATCH] Fix patch target parsing Our tests were not updated for RFC8040, hence they are written with weird codecs which utterly do not match RFC8072 definition of yang-patch. The problem is that patch edit's target is interpreted in terms of an extension to the URL, i.e. it does NOT follow JSON nor XML parsing rules, nor is it anything in-between -- we must use ParserIdentifier's facilities. Update the parsers and the test suites, ditching a lot of complexity in process of doing so. JIRA: NETCONF-804 Change-Id: If9d9c77e0e2397ffdcb8e8c0f0fef0b9b02bac8b Signed-off-by: Robert Varga (cherry picked from commit 845f511527e22741a1cf1053b04250d16bf7f6a0) --- .../patch/JsonToPatchBodyReader.java | 2 +- .../providers/patch/XmlToPatchBodyReader.java | 106 ++---------------- .../utils/parser/ParserIdentifier.java | 14 +++ .../JsonPatchBodyReaderMountPointTest.java | 77 +++++-------- .../XmlPatchBodyReaderMountPointTest.java | 67 +++++------ .../patch/XmlPatchBodyReaderTest.java | 66 +++++------ .../json/jsonPATCHMergeOperationOnList.json | 6 +- .../json/jsonPATCHSimpleLeafValue.json | 4 +- .../json/jsonPATCHdata.json | 4 +- .../json/jsonPATCHdataCreateAndDelete.json | 6 +- .../instanceidentifier/xml/xmlPATCHdata.xml | 6 +- .../xml/xmlPATCHdataAbsoluteTargetPath.xml | 6 +- .../xml/xmlPATCHdataMergeOperationOnList.xml | 6 +- 13 files changed, 129 insertions(+), 241 deletions(-) diff --git a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/JsonToPatchBodyReader.java b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/JsonToPatchBodyReader.java index 142af29896..9c53d185d0 100644 --- a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/JsonToPatchBodyReader.java +++ b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/JsonToPatchBodyReader.java @@ -234,7 +234,7 @@ public class JsonToPatchBodyReader extends AbstractToPatchBodyReader { edit.setTarget(path.getInstanceIdentifier()); edit.setTargetSchemaNode(path.getSchemaContext()); } else { - edit.setTarget(codec.deserialize(codec.serialize(path.getInstanceIdentifier()).concat(target))); + edit.setTarget(ParserIdentifier.parserPatchTarget(path, target)); edit.setTargetSchemaNode(SchemaContextUtil.findDataSchemaNode(path.getSchemaContext(), codec.getDataContextTree().findChild(edit.getTarget()).orElseThrow().getDataSchemaNode() .getPath().getParent())); diff --git a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/XmlToPatchBodyReader.java b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/XmlToPatchBodyReader.java index 95a78badb8..dbfb889edd 100644 --- a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/XmlToPatchBodyReader.java +++ b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/XmlToPatchBodyReader.java @@ -7,14 +7,14 @@ */ package org.opendaylight.restconf.nb.rfc8040.jersey.providers.patch; +import static com.google.common.base.Verify.verifyNotNull; + import com.google.common.base.Splitter; import com.google.common.collect.ImmutableList; import java.io.IOException; import java.io.InputStream; -import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import java.util.Locale; import javax.ws.rs.Consumes; @@ -24,7 +24,6 @@ import javax.xml.parsers.ParserConfigurationException; import javax.xml.stream.XMLStreamException; import javax.xml.transform.dom.DOMSource; import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.restconf.common.context.InstanceIdentifierContext; import org.opendaylight.restconf.common.errors.RestconfDocumentedException; import org.opendaylight.restconf.common.errors.RestconfError.ErrorTag; @@ -33,13 +32,11 @@ import org.opendaylight.restconf.common.patch.PatchContext; import org.opendaylight.restconf.common.patch.PatchEditOperation; import org.opendaylight.restconf.common.patch.PatchEntity; import org.opendaylight.restconf.nb.rfc8040.Rfc8040; -import org.opendaylight.restconf.nb.rfc8040.codecs.StringModuleInstanceIdentifierCodec; import org.opendaylight.restconf.nb.rfc8040.handlers.DOMMountPointServiceHandler; import org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler; import org.opendaylight.restconf.nb.rfc8040.utils.RestconfConstants; +import org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserIdentifier; import org.opendaylight.yangtools.util.xml.UntrustedXML; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.common.Revision; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; @@ -47,11 +44,10 @@ import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStre import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream; import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter; import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult; +import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; -import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; -import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; import org.slf4j.Logger; @@ -117,28 +113,15 @@ public class XmlToPatchBodyReader extends AbstractToPatchBodyReader { targetII = pathContext.getInstanceIdentifier(); targetNode = pathContext.getSchemaContext(); } else { - // get namespace according to schema node from path context or value - final URI namespace = firstValueElement == null ? schemaNode.getQName().getNamespace() - : URI.create(firstValueElement.getNamespaceURI()); - - // find module according to namespace - final Module module = pathContext.getSchemaContext().findModules(namespace).iterator().next(); - - // initialize codec + set default prefix derived from module name - final StringModuleInstanceIdentifierCodec codec = new StringModuleInstanceIdentifierCodec( - pathContext.getSchemaContext(), module.getName()); + // interpret as simple context + targetII = ParserIdentifier.parserPatchTarget(pathContext, target); - targetII = codec.deserialize(codec.serialize(pathContext.getInstanceIdentifier()) - .concat(prepareNonCondXpath(schemaNode, target.replaceFirst("/", ""), firstValueElement, - namespace, module.getQNameModule().getRevision().orElse(null)))); + // move schema node + final DataSchemaContextTree tree = DataSchemaContextTree.from(pathContext.getSchemaContext()); + schemaNode = verifyNotNull(tree.findChild(targetII).orElseThrow().getDataSchemaNode()); targetNode = SchemaContextUtil.findDataSchemaNode(pathContext.getSchemaContext(), - codec.getDataContextTree().findChild(targetII).orElseThrow().getDataSchemaNode() - .getPath().getParent()); - - // move schema node - schemaNode = (DataSchemaNode) SchemaContextUtil.findDataSchemaNode(pathContext.getSchemaContext(), - codec.getDataContextTree().findChild(targetII).orElseThrow().getDataSchemaNode().getPath()); + schemaNode.getPath().getParent()); } if (targetNode == null) { @@ -209,73 +192,4 @@ public class XmlToPatchBodyReader extends AbstractToPatchBodyReader { return result; } - - /** - * Prepare non-conditional XPath suitable for deserialization with {@link StringModuleInstanceIdentifierCodec}. - * - * @param schemaNode Top schema node - * @param target Edit operation target - * @param value Element with value - * @param namespace Module namespace - * @param revision Module revision - * @return Non-conditional XPath - */ - private static String prepareNonCondXpath(final @NonNull DataSchemaNode schemaNode, final @NonNull String target, - final @NonNull Element value, final @NonNull URI namespace, final @Nullable Revision revision) { - final Iterator args = SLASH_SPLITTER.split(target.substring(target.indexOf(':') + 1)).iterator(); - - final StringBuilder nonCondXpath = new StringBuilder(); - SchemaNode childNode = schemaNode; - - while (args.hasNext()) { - final String s = args.next(); - nonCondXpath.append("/"); - nonCondXpath.append(s); - childNode = ((DataNodeContainer) childNode).getDataChildByName(QName.create(namespace, revision, s)); - - if (childNode instanceof ListSchemaNode && args.hasNext()) { - appendKeys(nonCondXpath, ((ListSchemaNode) childNode).getKeyDefinition().iterator(), args); - } - } - - if (childNode instanceof ListSchemaNode && value != null) { - final Iterator keyValues = readKeyValues(value, - ((ListSchemaNode) childNode).getKeyDefinition().iterator()); - appendKeys(nonCondXpath, ((ListSchemaNode) childNode).getKeyDefinition().iterator(), keyValues); - } - - return nonCondXpath.toString(); - } - - /** - * Read value for every list key. - * - * @param value Value element - * @param keys Iterator of list keys names - * @return Iterator of list keys values - */ - private static Iterator readKeyValues(final @NonNull Element value, final @NonNull Iterator keys) { - final List result = new ArrayList<>(); - - while (keys.hasNext()) { - result.add(value.getElementsByTagName(keys.next().getLocalName()).item(0).getFirstChild().getNodeValue()); - } - - return result.iterator(); - } - - /** - * Append key name - key value pairs for every list key to {@code nonCondXpath}. - * - * @param nonCondXpath Builder for creating non-conditional XPath - * @param keyNames Iterator of list keys names - * @param keyValues Iterator of list keys values - */ - private static void appendKeys(final @NonNull StringBuilder nonCondXpath, final @NonNull Iterator keyNames, - final @NonNull Iterator keyValues) { - while (keyNames.hasNext()) { - nonCondXpath.append('[').append(keyNames.next().getLocalName()).append("='").append(keyValues.next()) - .append("']"); - } - } } diff --git a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/utils/parser/ParserIdentifier.java b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/utils/parser/ParserIdentifier.java index 305b93ff7a..9bfd60b3e6 100644 --- a/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/utils/parser/ParserIdentifier.java +++ b/restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/utils/parser/ParserIdentifier.java @@ -270,6 +270,20 @@ public final class ParserIdentifier { } } + public static YangInstanceIdentifier parserPatchTarget(final InstanceIdentifierContext context, + final String target) { + final var schemaContext = context.getSchemaContext(); + final var urlPath = context.getInstanceIdentifier(); + final String targetUrl; + if (urlPath.isEmpty()) { + targetUrl = target.startsWith("/") ? target.substring(1) : target; + } else { + targetUrl = stringFromYangInstanceIdentifier(urlPath, schemaContext) + target; + } + + return toInstanceIdentifier(targetUrl, schemaContext, Optional.empty()).getInstanceIdentifier(); + } + /** * Validation and parsing of revision. * diff --git a/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/JsonPatchBodyReaderMountPointTest.java b/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/JsonPatchBodyReaderMountPointTest.java index 5149c271df..92ae4103ce 100644 --- a/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/JsonPatchBodyReaderMountPointTest.java +++ b/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/JsonPatchBodyReaderMountPointTest.java @@ -5,12 +5,11 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ - package org.opendaylight.restconf.nb.rfc8040.jersey.providers.patch; import static javax.ws.rs.core.MediaType.APPLICATION_JSON; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import java.io.InputStream; import javax.ws.rs.core.MediaType; @@ -48,11 +47,8 @@ public class JsonPatchBodyReaderMountPointTest extends AbstractBodyReaderTest { final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont/my-list1=leaf1"; mockBodyReader(uri, jsonToPatchBodyReader, false); - final InputStream inputStream = JsonBodyReaderTest.class - .getResourceAsStream("/instanceidentifier/json/jsonPATCHdata.json"); - - final PatchContext returnValue = jsonToPatchBodyReader - .readFrom(null, null, null, mediaType, null, inputStream); + final PatchContext returnValue = jsonToPatchBodyReader.readFrom(null, null, null, mediaType, null, + JsonBodyReaderTest.class.getResourceAsStream("/instanceidentifier/json/jsonPATCHdata.json")); checkPatchContextMountPoint(returnValue); } @@ -64,11 +60,8 @@ public class JsonPatchBodyReaderMountPointTest extends AbstractBodyReaderTest { final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont/my-list1=leaf1"; mockBodyReader(uri, jsonToPatchBodyReader, false); - final InputStream inputStream = JsonBodyReaderTest.class - .getResourceAsStream("/instanceidentifier/json/jsonPATCHdataCreateAndDelete.json"); - - final PatchContext returnValue = jsonToPatchBodyReader - .readFrom(null, null, null, mediaType, null, inputStream); + final PatchContext returnValue = jsonToPatchBodyReader.readFrom(null, null, null, mediaType, null, + JsonBodyReaderTest.class.getResourceAsStream("/instanceidentifier/json/jsonPATCHdataCreateAndDelete.json")); checkPatchContextMountPoint(returnValue); } @@ -81,15 +74,11 @@ public class JsonPatchBodyReaderMountPointTest extends AbstractBodyReaderTest { final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont/my-list1=leaf1"; mockBodyReader(uri, jsonToPatchBodyReader, false); - final InputStream inputStream = JsonBodyReaderTest.class - .getResourceAsStream("/instanceidentifier/json/jsonPATCHdataValueMissing.json"); - - try { - jsonToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream); - fail("Test should return error 400 due to missing value node when attempt to invoke create operation"); - } catch (final RestconfDocumentedException e) { - assertEquals("Error code 400 expected", 400, e.getErrors().get(0).getErrorTag().getStatusCode()); - } + final InputStream inputStream = JsonBodyReaderTest.class.getResourceAsStream( + "/instanceidentifier/json/jsonPATCHdataValueMissing.json"); + final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class, + () -> jsonToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream)); + assertEquals("Error code 400 expected", 400, ex.getErrors().get(0).getErrorTag().getStatusCode()); } /** @@ -101,15 +90,11 @@ public class JsonPatchBodyReaderMountPointTest extends AbstractBodyReaderTest { final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont/my-list1=leaf1"; mockBodyReader(uri, jsonToPatchBodyReader, false); - final InputStream inputStream = JsonBodyReaderTest.class - .getResourceAsStream("/instanceidentifier/json/jsonPATCHdataValueNotSupported.json"); - - try { - jsonToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream); - fail("Test should return error 400 due to present value node when attempt to invoke delete operation"); - } catch (final RestconfDocumentedException e) { - assertEquals("Error code 400 expected", 400, e.getErrors().get(0).getErrorTag().getStatusCode()); - } + final InputStream inputStream = JsonBodyReaderTest.class.getResourceAsStream( + "/instanceidentifier/json/jsonPATCHdataValueNotSupported.json"); + final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class, + () -> jsonToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream)); + assertEquals("Error code 400 expected", 400, ex.getErrors().get(0).getErrorTag().getStatusCode()); } /** @@ -120,11 +105,9 @@ public class JsonPatchBodyReaderMountPointTest extends AbstractBodyReaderTest { final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont"; mockBodyReader(uri, jsonToPatchBodyReader, false); - final InputStream inputStream = JsonBodyReaderTest.class - .getResourceAsStream("/instanceidentifier/json/jsonPATCHdataCompleteTargetInURI.json"); - - final PatchContext returnValue = jsonToPatchBodyReader - .readFrom(null, null, null, mediaType, null, inputStream); + final PatchContext returnValue = jsonToPatchBodyReader.readFrom(null, null, null, mediaType, null, + JsonBodyReaderTest.class.getResourceAsStream( + "/instanceidentifier/json/jsonPATCHdataCompleteTargetInURI.json")); checkPatchContextMountPoint(returnValue); } @@ -136,11 +119,9 @@ public class JsonPatchBodyReaderMountPointTest extends AbstractBodyReaderTest { final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont/my-list1=leaf1"; mockBodyReader(uri, jsonToPatchBodyReader, false); - final InputStream inputStream = JsonBodyReaderTest.class - .getResourceAsStream("/instanceidentifier/json/jsonPATCHMergeOperationOnList.json"); - - final PatchContext returnValue = jsonToPatchBodyReader - .readFrom(null, null, null, mediaType, null, inputStream); + final PatchContext returnValue = jsonToPatchBodyReader.readFrom(null, null, null, mediaType, null, + JsonBodyReaderTest.class.getResourceAsStream( + "/instanceidentifier/json/jsonPATCHMergeOperationOnList.json")); checkPatchContextMountPoint(returnValue); } @@ -152,11 +133,9 @@ public class JsonPatchBodyReaderMountPointTest extends AbstractBodyReaderTest { final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont"; mockBodyReader(uri, jsonToPatchBodyReader, false); - final InputStream inputStream = JsonBodyReaderTest.class - .getResourceAsStream("/instanceidentifier/json/jsonPATCHMergeOperationOnContainer.json"); - - final PatchContext returnValue = jsonToPatchBodyReader - .readFrom(null, null, null, mediaType, null, inputStream); + final PatchContext returnValue = jsonToPatchBodyReader.readFrom(null, null, null, mediaType, null, + JsonBodyReaderTest.class.getResourceAsStream( + "/instanceidentifier/json/jsonPATCHMergeOperationOnContainer.json")); checkPatchContextMountPoint(returnValue); } @@ -168,12 +147,8 @@ public class JsonPatchBodyReaderMountPointTest extends AbstractBodyReaderTest { final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont/my-list1=leaf1"; mockBodyReader(uri, jsonToPatchBodyReader, false); - final InputStream inputStream = - JsonBodyReaderTest.class - .getResourceAsStream("/instanceidentifier/json/jsonPATCHSimpleLeafValue.json"); - - final PatchContext returnValue = jsonToPatchBodyReader - .readFrom(null, null, null, mediaType, null, inputStream); + final PatchContext returnValue = jsonToPatchBodyReader.readFrom(null, null, null, mediaType, null, + JsonBodyReaderTest.class.getResourceAsStream("/instanceidentifier/json/jsonPATCHSimpleLeafValue.json")); checkPatchContext(returnValue); } } diff --git a/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/XmlPatchBodyReaderMountPointTest.java b/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/XmlPatchBodyReaderMountPointTest.java index 97b2da238d..da1b92137a 100644 --- a/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/XmlPatchBodyReaderMountPointTest.java +++ b/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/XmlPatchBodyReaderMountPointTest.java @@ -9,7 +9,7 @@ package org.opendaylight.restconf.nb.rfc8040.jersey.providers.patch; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import java.io.InputStream; import javax.ws.rs.core.MediaType; @@ -46,10 +46,9 @@ public class XmlPatchBodyReaderMountPointTest extends AbstractBodyReaderTest { public void moduleDataTest() throws Exception { final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont/my-list1=leaf1"; mockBodyReader(uri, xmlToPatchBodyReader, false); - final InputStream inputStream = XmlBodyReaderTest.class - .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdata.xml"); - final PatchContext returnValue = xmlToPatchBodyReader - .readFrom(null, null, null, mediaType, null, inputStream); + + final PatchContext returnValue = xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, + XmlBodyReaderTest.class.getResourceAsStream("/instanceidentifier/xml/xmlPATCHdata.xml")); checkPatchContextMountPoint(returnValue); } @@ -60,14 +59,12 @@ public class XmlPatchBodyReaderMountPointTest extends AbstractBodyReaderTest { public void moduleDataValueMissingNegativeTest() throws Exception { final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont/my-list1=leaf1"; mockBodyReader(uri, xmlToPatchBodyReader, false); - final InputStream inputStream = XmlBodyReaderTest.class - .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataValueMissing.xml"); - try { - xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream); - fail("Test should return error 400 due to missing value node when attempt to invoke create operation"); - } catch (final RestconfDocumentedException e) { - assertEquals("Error code 400 expected", 400, e.getErrors().get(0).getErrorTag().getStatusCode()); - } + final InputStream inputStream = XmlBodyReaderTest.class.getResourceAsStream( + "/instanceidentifier/xml/xmlPATCHdataValueMissing.xml"); + + final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class, + () -> xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream)); + assertEquals("Error code 400 expected", 400, ex.getErrors().get(0).getErrorTag().getStatusCode()); } /** @@ -78,14 +75,12 @@ public class XmlPatchBodyReaderMountPointTest extends AbstractBodyReaderTest { public void moduleDataNotValueNotSupportedNegativeTest() throws Exception { final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont/my-list1=leaf1"; mockBodyReader(uri, xmlToPatchBodyReader, false); - final InputStream inputStream = XmlBodyReaderTest.class - .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataValueNotSupported.xml"); - try { - xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream); - fail("Test should return error 400 due to present value node when attempt to invoke delete operation"); - } catch (final RestconfDocumentedException e) { - assertEquals("Error code 400 expected", 400, e.getErrors().get(0).getErrorTag().getStatusCode()); - } + final InputStream inputStream = XmlBodyReaderTest.class.getResourceAsStream( + "/instanceidentifier/xml/xmlPATCHdataValueNotSupported.xml"); + + final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class, + () -> xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream)); + assertEquals("Error code 400 expected", 400, ex.getErrors().get(0).getErrorTag().getStatusCode()); } @@ -96,10 +91,9 @@ public class XmlPatchBodyReaderMountPointTest extends AbstractBodyReaderTest { public void moduleDataAbsoluteTargetPathTest() throws Exception { final String uri = MOUNT_POINT; mockBodyReader(uri, xmlToPatchBodyReader, false); - final InputStream inputStream = XmlBodyReaderTest.class - .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataAbsoluteTargetPath.xml"); - final PatchContext returnValue = xmlToPatchBodyReader - .readFrom(null, null, null, mediaType, null, inputStream); + + final PatchContext returnValue = xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, + XmlBodyReaderTest.class.getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataAbsoluteTargetPath.xml")); checkPatchContextMountPoint(returnValue); } @@ -110,10 +104,9 @@ public class XmlPatchBodyReaderMountPointTest extends AbstractBodyReaderTest { public void modulePatchCompleteTargetInURITest() throws Exception { final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont"; mockBodyReader(uri, xmlToPatchBodyReader, false); - final InputStream inputStream = XmlBodyReaderTest.class - .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataCompleteTargetInURI.xml"); - final PatchContext returnValue = xmlToPatchBodyReader - .readFrom(null, null, null, mediaType, null, inputStream); + + final PatchContext returnValue = xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, + XmlBodyReaderTest.class.getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataCompleteTargetInURI.xml")); checkPatchContextMountPoint(returnValue); } @@ -124,10 +117,10 @@ public class XmlPatchBodyReaderMountPointTest extends AbstractBodyReaderTest { public void moduleDataMergeOperationOnListTest() throws Exception { final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont/my-list1=leaf1"; mockBodyReader(uri, xmlToPatchBodyReader, false); - final InputStream inputStream = XmlBodyReaderTest.class - .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataMergeOperationOnList.xml"); - final PatchContext returnValue = xmlToPatchBodyReader - .readFrom(null, null, null, mediaType, null, inputStream); + + final PatchContext returnValue = xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, + XmlBodyReaderTest.class.getResourceAsStream( + "/instanceidentifier/xml/xmlPATCHdataMergeOperationOnList.xml")); checkPatchContextMountPoint(returnValue); } @@ -138,10 +131,10 @@ public class XmlPatchBodyReaderMountPointTest extends AbstractBodyReaderTest { public void moduleDataMergeOperationOnContainerTest() throws Exception { final String uri = MOUNT_POINT + "instance-identifier-patch-module:patch-cont"; mockBodyReader(uri, xmlToPatchBodyReader, false); - final InputStream inputStream = XmlBodyReaderTest.class - .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataMergeOperationOnContainer.xml"); - final PatchContext returnValue = xmlToPatchBodyReader - .readFrom(null, null, null, mediaType, null, inputStream); + + final PatchContext returnValue = xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, + XmlBodyReaderTest.class.getResourceAsStream( + "/instanceidentifier/xml/xmlPATCHdataMergeOperationOnContainer.xml")); checkPatchContextMountPoint(returnValue); } } diff --git a/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/XmlPatchBodyReaderTest.java b/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/XmlPatchBodyReaderTest.java index d8d7bb17c2..f88723391f 100644 --- a/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/XmlPatchBodyReaderTest.java +++ b/restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/XmlPatchBodyReaderTest.java @@ -9,7 +9,7 @@ package org.opendaylight.restconf.nb.rfc8040.jersey.providers.patch; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertThrows; import java.io.InputStream; import javax.ws.rs.core.MediaType; @@ -45,10 +45,9 @@ public class XmlPatchBodyReaderTest extends AbstractBodyReaderTest { public void moduleDataTest() throws Exception { final String uri = "instance-identifier-patch-module:patch-cont/my-list1=leaf1"; mockBodyReader(uri, xmlToPatchBodyReader, false); - final InputStream inputStream = XmlBodyReaderTest.class - .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdata.xml"); - final PatchContext returnValue = xmlToPatchBodyReader - .readFrom(null, null, null, mediaType, null, inputStream); + + final PatchContext returnValue = xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, + XmlBodyReaderTest.class.getResourceAsStream("/instanceidentifier/xml/xmlPATCHdata.xml")); checkPatchContext(returnValue); } @@ -59,14 +58,12 @@ public class XmlPatchBodyReaderTest extends AbstractBodyReaderTest { public void moduleDataValueMissingNegativeTest() throws Exception { final String uri = "instance-identifier-patch-module:patch-cont/my-list1=leaf1"; mockBodyReader(uri, xmlToPatchBodyReader, false); - final InputStream inputStream = XmlBodyReaderTest.class - .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataValueMissing.xml"); - try { - xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream); - fail("Test should return error 400 due to missing value node when attempt to invoke create operation"); - } catch (final RestconfDocumentedException e) { - assertEquals("Error code 400 expected", 400, e.getErrors().get(0).getErrorTag().getStatusCode()); - } + final InputStream inputStream = XmlBodyReaderTest.class.getResourceAsStream( + "/instanceidentifier/xml/xmlPATCHdataValueMissing.xml"); + + final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class, + () -> xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream)); + assertEquals("Error code 400 expected", 400, ex.getErrors().get(0).getErrorTag().getStatusCode()); } /** @@ -77,14 +74,12 @@ public class XmlPatchBodyReaderTest extends AbstractBodyReaderTest { public void moduleDataNotValueNotSupportedNegativeTest() throws Exception { final String uri = "instance-identifier-patch-module:patch-cont/my-list1=leaf1"; mockBodyReader(uri, xmlToPatchBodyReader, false); - final InputStream inputStream = XmlBodyReaderTest.class - .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataValueNotSupported.xml"); - try { - xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream); - fail("Test should return error 400 due to present value node when attempt to invoke delete operation"); - } catch (final RestconfDocumentedException e) { - assertEquals("Error code 400 expected", 400, e.getErrors().get(0).getErrorTag().getStatusCode()); - } + final InputStream inputStream = XmlBodyReaderTest.class.getResourceAsStream( + "/instanceidentifier/xml/xmlPATCHdataValueNotSupported.xml"); + + final RestconfDocumentedException ex = assertThrows(RestconfDocumentedException.class, + () -> xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, inputStream)); + assertEquals("Error code 400 expected", 400, ex.getErrors().get(0).getErrorTag().getStatusCode()); } @@ -95,10 +90,9 @@ public class XmlPatchBodyReaderTest extends AbstractBodyReaderTest { public void moduleDataAbsoluteTargetPathTest() throws Exception { final String uri = ""; mockBodyReader(uri, xmlToPatchBodyReader, false); - final InputStream inputStream = XmlBodyReaderTest.class - .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataAbsoluteTargetPath.xml"); - final PatchContext returnValue = xmlToPatchBodyReader - .readFrom(null, null, null, mediaType, null, inputStream); + + final PatchContext returnValue = xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, + XmlBodyReaderTest.class.getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataAbsoluteTargetPath.xml")); checkPatchContext(returnValue); } @@ -109,10 +103,9 @@ public class XmlPatchBodyReaderTest extends AbstractBodyReaderTest { public void modulePatchCompleteTargetInURITest() throws Exception { final String uri = "instance-identifier-patch-module:patch-cont"; mockBodyReader(uri, xmlToPatchBodyReader, false); - final InputStream inputStream = XmlBodyReaderTest.class - .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataCompleteTargetInURI.xml"); - final PatchContext returnValue = xmlToPatchBodyReader - .readFrom(null, null, null, mediaType, null, inputStream); + + final PatchContext returnValue = xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, + XmlBodyReaderTest.class.getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataCompleteTargetInURI.xml")); checkPatchContext(returnValue); } @@ -123,10 +116,10 @@ public class XmlPatchBodyReaderTest extends AbstractBodyReaderTest { public void moduleDataMergeOperationOnListTest() throws Exception { final String uri = "instance-identifier-patch-module:patch-cont/my-list1=leaf1"; mockBodyReader(uri, xmlToPatchBodyReader, false); - final InputStream inputStream = XmlBodyReaderTest.class - .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataMergeOperationOnList.xml"); - final PatchContext returnValue = xmlToPatchBodyReader - .readFrom(null, null, null, mediaType, null, inputStream); + + final PatchContext returnValue = xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, + XmlBodyReaderTest.class.getResourceAsStream( + "/instanceidentifier/xml/xmlPATCHdataMergeOperationOnList.xml")); checkPatchContext(returnValue); } @@ -137,10 +130,9 @@ public class XmlPatchBodyReaderTest extends AbstractBodyReaderTest { public void moduleDataMergeOperationOnContainerTest() throws Exception { final String uri = "instance-identifier-patch-module:patch-cont"; mockBodyReader(uri, xmlToPatchBodyReader, false); - final InputStream inputStream = XmlBodyReaderTest.class - .getResourceAsStream("/instanceidentifier/xml/xmlPATCHdataMergeOperationOnContainer.xml"); - final PatchContext returnValue = xmlToPatchBodyReader - .readFrom(null, null, null, mediaType, null, inputStream); + final PatchContext returnValue = xmlToPatchBodyReader.readFrom(null, null, null, mediaType, null, + XmlBodyReaderTest.class.getResourceAsStream( + "/instanceidentifier/xml/xmlPATCHdataMergeOperationOnContainer.xml")); checkPatchContext(returnValue); } } diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/json/jsonPATCHMergeOperationOnList.json b/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/json/jsonPATCHMergeOperationOnList.json index 3b809e0061..cbb67a9769 100644 --- a/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/json/jsonPATCHMergeOperationOnList.json +++ b/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/json/jsonPATCHMergeOperationOnList.json @@ -6,7 +6,7 @@ { "edit-id": "edit1", "operation": "replace", - "target": "/instance-identifier-patch-module:my-list2[instance-identifier-patch-module:name='my-leaf20']", + "target": "/my-list2=my-leaf20", "value": { "my-list2": { "name": "my-leaf20", @@ -18,7 +18,7 @@ { "edit-id": "edit2", "operation": "merge", - "target": "/instance-identifier-patch-module:my-list2[instance-identifier-patch-module:name='my-leaf21']", + "target": "/my-list2=my-leaf21", "value": { "my-list2": { "name": "my-leaf21", @@ -29,4 +29,4 @@ } ] } -} \ No newline at end of file +} diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/json/jsonPATCHSimpleLeafValue.json b/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/json/jsonPATCHSimpleLeafValue.json index 4a109efb91..d63d43b8fb 100644 --- a/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/json/jsonPATCHSimpleLeafValue.json +++ b/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/json/jsonPATCHSimpleLeafValue.json @@ -7,11 +7,11 @@ { "edit-id": "edit1", "operation": "replace", - "target": "/instance-identifier-patch-module:my-list2[instance-identifier-patch-module:name='my-leaf20']/instance-identifier-patch-module:name", + "target": "/my-list2=my-leaf20/name", "value": { "name": "my-leaf20" } } ] } -} \ No newline at end of file +} diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/json/jsonPATCHdata.json b/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/json/jsonPATCHdata.json index e027a76672..24988264ac 100644 --- a/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/json/jsonPATCHdata.json +++ b/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/json/jsonPATCHdata.json @@ -7,7 +7,7 @@ { "edit-id": "edit1", "operation": "replace", - "target": "/instance-identifier-patch-module:my-list2[instance-identifier-patch-module:name='my-leaf20']", + "target": "/my-list2=my-leaf20", "value": { "my-list2": { "name": "my-leaf20", @@ -20,7 +20,7 @@ { "edit-id": "edit2", "operation": "replace", - "target": "/instance-identifier-patch-module:my-list2[instance-identifier-patch-module:name='my-leaf20']", + "target": "/my-list2=my-leaf20", "value": { "my-list2": { "name": "my-leaf20", diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/json/jsonPATCHdataCreateAndDelete.json b/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/json/jsonPATCHdataCreateAndDelete.json index 4455038134..8d705a8fdd 100644 --- a/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/json/jsonPATCHdataCreateAndDelete.json +++ b/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/json/jsonPATCHdataCreateAndDelete.json @@ -18,14 +18,14 @@ } ] }, - "target": "/instance-identifier-patch-module:my-list2[instance-identifier-patch-module:name='my-leaf20']", + "target": "/my-list2=my-leaf20", "operation": "create" }, { "edit-id": "edit2", "operation": "delete", - "target": "/instance-identifier-patch-module:my-list2[instance-identifier-patch-module:name='my-leaf20']" + "target": "/my-list2=my-leaf20" } ] } -} \ No newline at end of file +} diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/xml/xmlPATCHdata.xml b/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/xml/xmlPATCHdata.xml index d7d3a6bea6..3542c9133a 100644 --- a/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/xml/xmlPATCHdata.xml +++ b/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/xml/xmlPATCHdata.xml @@ -4,7 +4,7 @@ edit1 create - /my-list2 + /my-list2=my-leaf20 my-leaf20 @@ -16,7 +16,7 @@ edit2 create - /my-list2 + /my-list2=my-leaf21 my-leaf21 @@ -25,4 +25,4 @@ - \ No newline at end of file + diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/xml/xmlPATCHdataAbsoluteTargetPath.xml b/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/xml/xmlPATCHdataAbsoluteTargetPath.xml index 6e84c47a49..d792356a7d 100644 --- a/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/xml/xmlPATCHdataAbsoluteTargetPath.xml +++ b/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/xml/xmlPATCHdataAbsoluteTargetPath.xml @@ -11,7 +11,7 @@ edit1 create - /instance-identifier-patch-module:patch-cont/my-list1/leaf1/my-list2 + /instance-identifier-patch-module:patch-cont/my-list1=leaf1/my-list2=my-leaf20 my-leaf20 @@ -23,7 +23,7 @@ edit2 create - /instance-identifier-patch-module:patch-cont/my-list1/leaf1/my-list2 + /instance-identifier-patch-module:patch-cont/my-list1=leaf1/my-list2=my-leaf21 my-leaf21 @@ -32,4 +32,4 @@ - \ No newline at end of file + diff --git a/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/xml/xmlPATCHdataMergeOperationOnList.xml b/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/xml/xmlPATCHdataMergeOperationOnList.xml index ad130413a4..bf852877c4 100644 --- a/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/xml/xmlPATCHdataMergeOperationOnList.xml +++ b/restconf/restconf-nb-rfc8040/src/test/resources/instanceidentifier/xml/xmlPATCHdataMergeOperationOnList.xml @@ -11,7 +11,7 @@ edit1 replace - /my-list2 + /my-list2=my-leaf20 my-leaf20 @@ -23,7 +23,7 @@ edit2 merge - /my-list2 + /my-list2=my-leaf21 my-leaf21 @@ -32,4 +32,4 @@ - \ No newline at end of file + -- 2.36.6