Uploaded image for project: 'netconf'
  1. netconf
  2. NETCONF-744

Read whole leaf-list using get/get-config RPC

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: High High
    • Aluminium SR4, 1.13.2
    • Aluminium
    • netconf
    • 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:

      1. 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?
      2. 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?
      3. 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

       

            jaro0149odl Jaroslav Tóth
            jaro0149odl Jaroslav Tóth
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: