-
Bug
-
Resolution: Done
-
High
-
Aluminium
-
None
Hi,
I tried to read whole leaf-list using plain SSH and chunking mechanism. Example ("extraIpPorts" is described by leaf-list):
#528 <rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="m-291"> <get> <filter xmlns:ns0="urn:ietf:params:xml:ns:netconf:base:1.0" ns0:type="subtree"> <confdConfig xmlns="http://tail-f.com/ns/confd_dyncfg/1.0"> <netconf> <transport> <ssh> <extraIpPorts/> </ssh> </transport> </netconf> </confdConfig> </filter> </get> </rpc> ## #304 <?xml version="1.0" encoding="UTF-8"?> <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="m-291"><data><confdConfig xmlns="http://tail-f.com/ns/confd_dyncfg/1.0"><netconf><transport><ssh><extraIpPorts>:::2022</extraIpPorts></ssh></transport></netconf></confdConfig></data></rpc-reply> ##
Device accepted such request and successfully returned RPC response with one leaf-list entry. I also tried different request which would return whole leaf-lists with multiple entries. Everything seems to work as expected (I tested reading of leaf-list on the ConfD device).
However, I cannot build the similar subtree filter using NETCONF that would point to the whole leaf-list.
My attempts to build subtree filter that would point to "netconf-state/capabilities/capability" leaf-list (ietf-netconf-monitoring module):
#1
final YangInstanceIdentifier targetYiid = YangInstanceIdentifier.create( toId(NetconfState.QNAME), toId(Capabilities.QNAME), toId(QName.create(Capabilities.QNAME, "capability")));
Built GET RPC ('capability' entity is skipped):
<rpc message-id="m-0" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <get> <filter xmlns:ns0="urn:ietf:params:xml:ns:netconf:base:1.0" ns0:type="subtree"> <netconf-state xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring"> <capabilities/> </netconf-state> </filter> </get> </rpc>
#2
final YangInstanceIdentifier targetYiid = YangInstanceIdentifier.create( toId(NetconfState.QNAME), toId(Capabilities.QNAME), new NodeWithValue<>(QName.create(Capabilities.QNAME, "capability"), null));
Built GET RPC ('capability' entity is again skipped):
<rpc message-id="m-0" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <get> <filter xmlns:ns0="urn:ietf:params:xml:ns:netconf:base:1.0" ns0:type="subtree"> <netconf-state xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring"> <capabilities/> </netconf-state> </filter> </get> </rpc>
#3
final YangInstanceIdentifier targetYiid = YangInstanceIdentifier.create( toId(NetconfState.QNAME), toId(Capabilities.QNAME), toId(QName.create(Capabilities.QNAME, "capability")), new NodeWithValue<>(QName.create(Capabilities.QNAME, "capability"), null));
Error:
[main] WARN org.opendaylight.netconf.util.NetconfUtil - Unable to set namespace context, falling back to setPrefix() java.lang.UnsupportedOperationException at java.xml/com.sun.xml.internal.stream.writers.XMLDOMWriterImpl.setNamespaceContext(XMLDOMWriterImpl.java:158) at org.opendaylight.netconf.util.NetconfUtil$NamespaceSetter.forFactory(NetconfUtil.java:83) at org.opendaylight.netconf.util.NetconfUtil.<clinit>(NetconfUtil.java:118) at org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil.<clinit>(NetconfMessageTransformUtil.java:121) at org.opendaylight.netconf.sal.connect.netconf.schema.mapping.NetconfMessageTransformer.<clinit>(NetconfMessageTransformer.java:99) at org.opendaylight.netconf.sal.connect.netconf.schema.mapping.NetconfMessageTransformerTest.getTransformer(NetconfMessageTransformerTest.java:490) at org.opendaylight.netconf.sal.connect.netconf.schema.mapping.NetconfMessageTransformerTest.setUp(NetconfMessageTransformerTest.java:202) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56) at org.junit.internal.runners.statements.RunBefores.invokeMethod(RunBefores.java:33) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63) at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329) at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.ParentRunner.run(ParentRunner.java:413) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53) java.lang.NullPointerException at java.base/java.util.Objects.requireNonNull(Objects.java:221) at org.opendaylight.yangtools.concepts.AbstractCodec.serialize(AbstractCodec.java:34) at org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamWriterUtils.serialize(XMLStreamWriterUtils.java:116) at org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamWriterUtils.encodeValue(XMLStreamWriterUtils.java:82) at org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamWriterUtils.encodeValue(XMLStreamWriterUtils.java:56) at org.opendaylight.yangtools.yang.data.codec.xml.SchemaAwareXMLStreamNormalizedNodeStreamWriter.encodeValue(SchemaAwareXMLStreamNormalizedNodeStreamWriter.java:53) at org.opendaylight.yangtools.yang.data.codec.xml.SchemaAwareXMLStreamNormalizedNodeStreamWriter.encodeValue(SchemaAwareXMLStreamNormalizedNodeStreamWriter.java:38) at org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStreamWriter.writeValue(XMLStreamNormalizedNodeStreamWriter.java:132) at org.opendaylight.yangtools.yang.data.codec.xml.SchemaAwareXMLStreamNormalizedNodeStreamWriter.scalarValue(SchemaAwareXMLStreamNormalizedNodeStreamWriter.java:161) at org.opendaylight.netconf.util.StreamingContext$LeafListEntry.streamToWriter(StreamingContext.java:393) at org.opendaylight.netconf.util.StreamingContext$AbstractComposite.streamToWriter(StreamingContext.java:167) at org.opendaylight.netconf.util.StreamingContext$AbstractComposite.streamToWriter(StreamingContext.java:167) at org.opendaylight.netconf.util.StreamingContext$AbstractComposite.streamToWriter(StreamingContext.java:167) at org.opendaylight.netconf.util.NetconfUtil.writeFilter(NetconfUtil.java:217) at org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil.toFilterStructure(NetconfMessageTransformUtil.java:233) at org.opendaylight.netconf.sal.connect.netconf.schema.mapping.NetconfMessageTransformerTest.getLeafListFieldsTest(NetconfMessageTransformerTest.java:1071) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63) at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329) at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.ParentRunner.run(ParentRunner.java:413) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
Testing was done from "NetconfMessageTransformerTest" unit tests.
My questions:
- From the quick analysis, I think the source of the issue is in the SchemaAwareXMLStreamNormalizedNodeStreamWriter YANG-TOOLs class that just skips the empty leaf-list and doesn't serialize it. Is behaviour of SchemaAwareXMLStreamNormalizedNodeStreamWriter correct?
- Why reading of whole leaf-list using NETCONF is not allowed, if it is it is supported by devices? Is there some RFC sheet that denies such scenario?
- Where to fix this bug (if it is a bug)? Possible solution: creation of custom XML stream writer that also serializes empty leaf-lists and will be used only by NETCONF.
Regards,
Jaroslav