From 6379e64a96f5d510b3f298ef207a2ea3c3fc0b63 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Thu, 4 Nov 2021 14:43:31 +0100 Subject: [PATCH] Implement NodeContainerProxy.getPath() getPath() is being used for diagnostics in XML parser, let's implement it in the obviously-correct way to get some more information. Also modermize NodeContainerProxyTest and move it netconf-util, so it is co-located with the class it is testing. JIRA: NETCONF-828 Change-Id: Idfac9d779366d3465db29dcadc27af51dc16b956 Signed-off-by: Robert Varga --- .../netconf/util/NetconfUtil.java | 10 +- .../netconf/util/NodeContainerProxy.java | 49 +++--- .../netconf/util/NodeContainerProxyTest.java | 143 ++++++++++++++++++ .../util/NetconfMessageTransformUtil.java | 9 +- .../netconf/util/NodeContainerProxyTest.java | 139 ----------------- 5 files changed, 178 insertions(+), 172 deletions(-) create mode 100644 netconf/netconf-util/src/test/java/org/opendaylight/netconf/util/NodeContainerProxyTest.java delete mode 100644 netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/util/NodeContainerProxyTest.java diff --git a/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/NetconfUtil.java b/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/NetconfUtil.java index 24d73643ea..17341ffa7f 100644 --- a/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/NetconfUtil.java +++ b/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/NetconfUtil.java @@ -44,7 +44,6 @@ import org.opendaylight.yangtools.yang.data.codec.xml.XmlCodecFactory; 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.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaPath; @@ -356,13 +355,12 @@ public final class NetconfUtil { public static NormalizedNodeResult transformDOMSourceToNormalizedNode(final MountPointContext mountContext, final DOMSource value) throws XMLStreamException, URISyntaxException, IOException, SAXException { final NormalizedNodeResult resultHolder = new NormalizedNodeResult(); - final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder); - final XmlCodecFactory codecs = XmlCodecFactory.create(mountContext); // FIXME: we probably need to propagate MountPointContext here and not just the child nodes - final ContainerSchemaNode dataRead = new NodeContainerProxy(NETCONF_DATA_QNAME, - mountContext.getEffectiveModelContext().getChildNodes()); - try (XmlParserStream xmlParserStream = XmlParserStream.create(writer, codecs, dataRead)) { + try (XmlParserStream xmlParserStream = XmlParserStream.create( + ImmutableNormalizedNodeStreamWriter.from(resultHolder), + XmlCodecFactory.create(mountContext), + NodeContainerProxy.ofModelContext(NETCONF_DATA_QNAME, mountContext.getEffectiveModelContext()))) { xmlParserStream.traverse(value); } return resultHolder; diff --git a/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/NodeContainerProxy.java b/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/NodeContainerProxy.java index 760409824a..b327e907eb 100644 --- a/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/NodeContainerProxy.java +++ b/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/NodeContainerProxy.java @@ -9,16 +9,19 @@ package org.opendaylight.netconf.util; import static java.util.Objects.requireNonNull; +import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Maps; import java.util.Collection; -import java.util.Collections; import java.util.Map; import java.util.Optional; +import java.util.Set; +import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.ActionDefinition; import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; import org.opendaylight.yangtools.yang.model.api.MustDefinition; import org.opendaylight.yangtools.yang.model.api.NotificationDefinition; @@ -33,25 +36,27 @@ import org.opendaylight.yangtools.yang.xpath.api.YangXPathExpression.QualifiedBo * Simple proxy for container like schema nodes, where user provides a collection of children schema nodes. */ public final class NodeContainerProxy implements ContainerSchemaNode { - - private final Map childNodes; - private final QName qualifiedName; private final Collection availableAugmentations; - - public NodeContainerProxy(final QName qualifiedName, final Map childNodes, - final Collection availableAugmentations) { + private final @NonNull Map childNodes; + private final @NonNull SchemaPath path; + private final @NonNull QName qname; + + @VisibleForTesting + NodeContainerProxy(final QName qname, final SchemaPath path, final Map childNodes, + final Collection availableAugmentations) { + this.qname = requireNonNull(qname); + this.path = requireNonNull(path); + this.childNodes = requireNonNull(childNodes); this.availableAugmentations = availableAugmentations; - this.childNodes = requireNonNull(childNodes, "childNodes"); - this.qualifiedName = qualifiedName; } - public NodeContainerProxy(final QName qualifiedName, final Collection childNodes) { - this(qualifiedName, asMap(childNodes), Collections.emptySet()); + public static @NonNull NodeContainerProxy ofModelContext(final QName qname, final EffectiveModelContext context) { + return new NodeContainerProxy(qname, SchemaPath.ROOT, asMap(context.getChildNodes()), Set.of()); } - public NodeContainerProxy(final QName qualifiedName, final Collection childNodes, - final Collection availableAugmentations) { - this(qualifiedName, asMap(childNodes), availableAugmentations); + public static @NonNull NodeContainerProxy ofNotification(final NotificationDefinition notification) { + return new NodeContainerProxy(notification.getQName(), notification.getPath(), + asMap(notification.getChildNodes()), notification.getAvailableAugmentations()); } private static Map asMap(final Collection childNodes) { @@ -60,7 +65,7 @@ public final class NodeContainerProxy implements ContainerSchemaNode { @Override public Collection> getTypeDefinitions() { - return Collections.emptySet(); + return Set.of(); } @Override @@ -70,7 +75,7 @@ public final class NodeContainerProxy implements ContainerSchemaNode { @Override public Collection getGroupings() { - return Collections.emptySet(); + return Set.of(); } @Override @@ -80,7 +85,7 @@ public final class NodeContainerProxy implements ContainerSchemaNode { @Override public Collection getUses() { - return Collections.emptySet(); + return Set.of(); } @Override @@ -112,13 +117,13 @@ public final class NodeContainerProxy implements ContainerSchemaNode { @Override public QName getQName() { - return qualifiedName; + return qname; } @Override @Deprecated public SchemaPath getPath() { - throw new UnsupportedOperationException(); + return path; } @Override @@ -138,12 +143,12 @@ public final class NodeContainerProxy implements ContainerSchemaNode { @Override public Collection getNotifications() { - return Collections.emptySet(); + return Set.of(); } @Override public Collection getActions() { - return Collections.emptySet(); + return Set.of(); } @Override @@ -153,7 +158,7 @@ public final class NodeContainerProxy implements ContainerSchemaNode { @Override public Collection getMustConstraints() { - return Collections.emptySet(); + return Set.of(); } @Override diff --git a/netconf/netconf-util/src/test/java/org/opendaylight/netconf/util/NodeContainerProxyTest.java b/netconf/netconf-util/src/test/java/org/opendaylight/netconf/util/NodeContainerProxyTest.java new file mode 100644 index 0000000000..d0a352828b --- /dev/null +++ b/netconf/netconf-util/src/test/java/org/opendaylight/netconf/util/NodeContainerProxyTest.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * 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.netconf.util; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThrows; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; + +@RunWith(MockitoJUnitRunner.StrictStubs.class) +public class NodeContainerProxyTest { + private static final QName QNAME = QName.create("ns", "2016-10-19", "name"); + private static final QName NODE_1_QNAME = QName.create(QNAME, "node-1"); + private static final QName NODE_2_QNAME = QName.create(QNAME, "node-2"); + + @Mock + private AugmentationSchemaNode augSchema1; + @Mock + private AugmentationSchemaNode augSchema2; + @Mock + private DataSchemaNode schemaNode1; + @Mock + private DataSchemaNode schemaNode2; + private NodeContainerProxy proxy; + + @Before + public void setUp() { + proxy = new NodeContainerProxy(QNAME, SchemaPath.SAME, + Map.of(NODE_1_QNAME, schemaNode1, NODE_2_QNAME, schemaNode2), Set.of(augSchema1, augSchema2)); + } + + @Test + public void testGetQName() { + assertSame(QNAME, proxy.getQName()); + } + + @Test + @Deprecated + public void testGetPath() { + assertSame(SchemaPath.SAME, proxy.getPath()); + } + + @Test + public void testGetChildNodes() { + final var children = proxy.getChildNodes(); + assertEquals(2, children.size()); + assertThat(children, containsInAnyOrder(schemaNode1, schemaNode2)); + } + + @Test + public void testGetAvailableAugmentations() { + final var augmentations = proxy.getAvailableAugmentations(); + assertEquals(2, augmentations.size()); + assertThat(augmentations, containsInAnyOrder(augSchema1, augSchema2)); + } + + @Test + public void testFindDataChildByName() { + assertEquals(Optional.of(schemaNode1), proxy.findDataChildByName(NODE_1_QNAME)); + } + + @Test + public void testGetTypeDefinitions() { + assertEmpty(proxy.getTypeDefinitions()); + } + + @Test + public void testGetGroupings() { + assertEmpty(proxy.getGroupings()); + } + + @Test + public void testGetUses() { + assertEmpty(proxy.getUses()); + } + + @Test + public void testGetUnknownSchemaNodes() { + assertEmpty(proxy.getUnknownSchemaNodes()); + } + + @Test + public void testIsPresenceContainer() { + assertThrows(UnsupportedOperationException.class, () -> proxy.isPresenceContainer()); + } + + @Test + @Deprecated + public void testIsAugmenting() { + assertThrows(UnsupportedOperationException.class, () -> proxy.isAugmenting()); + } + + @Test + @Deprecated + public void testIsAddedByUses() { + assertThrows(UnsupportedOperationException.class, () -> proxy.isAddedByUses()); + } + + @Test + public void testIsConfiguration() { + assertThrows(UnsupportedOperationException.class, () -> proxy.isConfiguration()); + } + + @Test + public void testGetDescription() { + assertThrows(UnsupportedOperationException.class, () -> proxy.getDescription()); + } + + @Test + public void testGetReference() { + assertThrows(UnsupportedOperationException.class, () -> proxy.getReference()); + } + + @Test + public void testGetStatus() { + assertThrows(UnsupportedOperationException.class, () -> proxy.getStatus()); + } + + static void assertEmpty(final Collection coll) { + assertEquals(List.of(), List.copyOf(coll)); + } +} diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfMessageTransformUtil.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfMessageTransformUtil.java index 7dcf80e4ad..0654745394 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfMessageTransformUtil.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfMessageTransformUtil.java @@ -77,7 +77,6 @@ import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; import org.opendaylight.yangtools.yang.model.api.NotificationDefinition; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute; import org.slf4j.Logger; @@ -372,12 +371,12 @@ public final class NetconfMessageTransformUtil { || NETCONF_GET_QNAME.getLocalName().equals(rpc.getLocalName())); } - public static @NonNull ContainerSchemaNode createSchemaForDataRead(final SchemaContext schemaContext) { - return new NodeContainerProxy(NETCONF_DATA_QNAME, schemaContext.getChildNodes()); + public static @NonNull ContainerSchemaNode createSchemaForDataRead(final EffectiveModelContext schemaContext) { + return NodeContainerProxy.ofModelContext(NETCONF_DATA_QNAME, schemaContext); } - public static @NonNull ContainerSchemaNode createSchemaForNotification(final NotificationDefinition next) { - return new NodeContainerProxy(next.getQName(), next.getChildNodes(), next.getAvailableAugmentations()); + public static @NonNull ContainerSchemaNode createSchemaForNotification(final NotificationDefinition notification) { + return NodeContainerProxy.ofNotification(notification); } @Deprecated diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/util/NodeContainerProxyTest.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/util/NodeContainerProxyTest.java deleted file mode 100644 index 59cce4a742..0000000000 --- a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/util/NodeContainerProxyTest.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * 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.netconf.sal.connect.netconf.util; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; -import org.opendaylight.netconf.util.NodeContainerProxy; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; -import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; - -@RunWith(MockitoJUnitRunner.StrictStubs.class) -public class NodeContainerProxyTest { - - private static final QName QNAME = QName.create("ns", "2016-10-19", "name"); - private static final QName NODE_1_QNAME = QName.create(QNAME, "node-1"); - private static final QName NODE_2_QNAME = QName.create(QNAME, "node-2"); - @Mock - private AugmentationSchemaNode augSchema1; - @Mock - private AugmentationSchemaNode augSchema2; - @Mock - private DataSchemaNode schemaNode1; - @Mock - private DataSchemaNode schemaNode2; - private NodeContainerProxy proxy; - - @Before - public void setUp() throws Exception { - final Map childNodes = new HashMap<>(); - childNodes.put(NODE_1_QNAME, schemaNode1); - childNodes.put(NODE_2_QNAME, schemaNode2); - final Set augmentations = new HashSet<>(); - augmentations.add(augSchema1); - augmentations.add(augSchema2); - proxy = new NodeContainerProxy(QNAME, childNodes, augmentations); - } - - @Test - public void testGetQName() throws Exception { - assertEquals(QNAME, proxy.getQName()); - } - - @Test - public void testGetChildNodes() throws Exception { - assertEquals(2, proxy.getChildNodes().size()); - } - - @Test - public void testGetAvailableAugmentations() throws Exception { - final Collection augmentations = proxy.getAvailableAugmentations(); - assertEquals(2, augmentations.size()); - assertTrue(augmentations.contains(augSchema1)); - assertTrue(augmentations.contains(augSchema2)); - } - - @Test - public void testFindDataChildByName() { - assertEquals(Optional.of(schemaNode1), proxy.findDataChildByName(NODE_1_QNAME)); - } - - @Test - public void testGetTypeDefinitions() throws Exception { - assertTrue(proxy.getTypeDefinitions().isEmpty()); - } - - @Test - public void testGetGroupings() throws Exception { - assertTrue(proxy.getGroupings().isEmpty()); - } - - @Test - public void testGetUses() throws Exception { - assertTrue(proxy.getUses().isEmpty()); - } - - @Test - public void testGetUnknownSchemaNodes() throws Exception { - assertTrue(proxy.getUnknownSchemaNodes().isEmpty()); - } - - @Test(expected = UnsupportedOperationException.class) - public void testIsPresenceContainer() throws Exception { - proxy.isPresenceContainer(); - } - - @Test(expected = UnsupportedOperationException.class) - public void testIsAugmenting() throws Exception { - proxy.isAugmenting(); - } - - @Test(expected = UnsupportedOperationException.class) - public void testIsAddedByUses() throws Exception { - proxy.isAddedByUses(); - } - - @Test(expected = UnsupportedOperationException.class) - public void testIsConfiguration() throws Exception { - proxy.isConfiguration(); - } - - @Test(expected = UnsupportedOperationException.class) - public void testGetPath() throws Exception { - proxy.getPath(); - } - - @Test(expected = UnsupportedOperationException.class) - public void testGetDescription() throws Exception { - proxy.getDescription(); - } - - @Test(expected = UnsupportedOperationException.class) - public void testGetReference() throws Exception { - proxy.getReference(); - } - - @Test(expected = UnsupportedOperationException.class) - public void testGetStatus() throws Exception { - proxy.getStatus(); - } - -} -- 2.36.6