有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

使用Opendaylight通过NETCONF检索列表时出现java错误“XML输入中的重复命名空间”

我使用Opendaylight(0.10.1版)作为NETCONF客户端向Netopeer2服务器发送请求
My YANG模型是一个第三方模型,由多个模块组成,这些模块除其他属性外,还包含多个列表元素
这将转换为一个XML请求和响应对,如下所示(简化):

请求:

<rpc message-id="m-3" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
    <get-config>
        <source>
            <running/>
        </source>
        <filter xmlns:ns0="urn:ietf:params:xml:ns:netconf:base:1.0" ns0:type="subtree">
            <TopElement xmlns="top-element">
                <id>1</id>
            </TopElement>
        </filter>
    </get-config>
</rpc>

答复:

<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="m-3">
    <data>
        <TopElement xmlns="top-element">
            <id>1</id>
            <ParentElement xmlns="parent-element">
                <id>1</id>
                <ChildElement1 xmlns="child-element1">
                    <id>1</id>
                    <attributes>
                        ...
                    </attributes>
                </ChildElement1>
                <ChildElement1 xmlns="child-element1">
                    <id>2</id>
                    <attributes>
                        ...
                    </attributes>
                </ChildElement1>
                <ChildElement2 xmlns="child-element2">
                    <id>1</id>
                    <attributes>
                        ...
                    </attributes>
                </ChildElement2>
                <ChildElement1 xmlns="child-element1">
                    <id>3</id>
                    <attributes>
                        ...
                    </attributes>
                </ChildElement1>
            </ParentElement>
        </TopElement>
    </data>
</rpc-reply>

但是,这样的请求会导致“主机关闭”错误,我已经尝试使用Karaf日志文件进行调查。我跟踪到了akka.pattern.AskTimeoutException超时,这似乎是由XML响应的解析错误引起的:

2020-04-08T09:09:11,733 | ERROR | nioEventLoopGroupCloseable-3-1 | AbstractFuture                   | 42 - com.google.guava - 25.1.0.jre |  -  | RuntimeException while executing runnable CallbackListener{org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceRpc$1@165744d4} with executor MoreExecutors.directExecutor()
java.lang.IllegalArgumentException: Failed to parse data response [data: null]
    at org.opendaylight.netconf.sal.connect.netconf.schema.mapping.NetconfMessageTransformer.toRpcResult(NetconfMessageTransformer.java:285) ~[386:org.opendaylight.netconf.sal-netconf-connector:1.9.1]
    at org.opendaylight.netconf.sal.connect.netconf.schema.mapping.NetconfMessageTransformer.toRpcResult(NetconfMessageTransformer.java:75) ~[386:org.opendaylight.netconf.sal-netconf-connector:1.9.1]
    at org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceRpc$1.onSuccess(NetconfDeviceRpc.java:60) ~[386:org.opendaylight.netconf.sal-netconf-connector:1.9.1]
    at org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceRpc$1.onSuccess(NetconfDeviceRpc.java:57) ~[386:org.opendaylight.netconf.sal-netconf-connector:1.9.1]
    at com.google.common.util.concurrent.Futures$CallbackListener.run(Futures.java:1355) ~[42:com.google.guava:25.1.0.jre]
    at com.google.common.util.concurrent.MoreExecutors$DirectExecutor.execute(MoreExecutors.java:398) ~[42:com.google.guava:25.1.0.jre]
    at com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1024) [42:com.google.guava:25.1.0.jre]
    at com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:866) [42:com.google.guava:25.1.0.jre]
    at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:689) [42:com.google.guava:25.1.0.jre]
    at org.opendaylight.netconf.sal.connect.netconf.listener.UncancellableFuture.set(UncancellableFuture.java:45) [386:org.opendaylight.netconf.sal-netconf-connector:1.9.1]
    at org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCommunicator.processMessage(NetconfDeviceCommunicator.java:338) [386:org.opendaylight.netconf.sal-netconf-connector:1.9.1]
    at org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCommunicator.onMessage(NetconfDeviceCommunicator.java:270) [386:org.opendaylight.netconf.sal-netconf-connector:1.9.1]
    at org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCommunicator.onMessage(NetconfDeviceCommunicator.java:49) [386:org.opendaylight.netconf.sal-netconf-connector:1.9.1]
    at org.opendaylight.netconf.nettyutil.AbstractNetconfSession.handleMessage(AbstractNetconfSession.java:64) [379:org.opendaylight.netconf.netty-util:1.6.1]
    at org.opendaylight.netconf.nettyutil.AbstractNetconfSession.channelRead0(AbstractNetconfSession.java:187) [379:org.opendaylight.netconf.netty-util:1.6.1]
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [71:io.netty.transport:4.1.34.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359) [71:io.netty.transport:4.1.34.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345) [71:io.netty.transport:4.1.34.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:337) [71:io.netty.transport:4.1.34.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:323) [66:io.netty.codec:4.1.34.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:297) [66:io.netty.codec:4.1.34.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359) [71:io.netty.transport:4.1.34.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345) [71:io.netty.transport:4.1.34.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:337) [71:io.netty.transport:4.1.34.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:323) [66:io.netty.codec:4.1.34.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:297) [66:io.netty.codec:4.1.34.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359) [71:io.netty.transport:4.1.34.Final]
    at io.netty.channel.AbstractChannelHandlerContext.access$600(AbstractChannelHandlerContext.java:38) [71:io.netty.transport:4.1.34.Final]
    at io.netty.channel.AbstractChannelHandlerContext$7.run(AbstractChannelHandlerContext.java:350) [71:io.netty.transport:4.1.34.Final]
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) [68:io.netty.common:4.1.34.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404) [68:io.netty.common:4.1.34.Final]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:495) [71:io.netty.transport:4.1.34.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:905) [68:io.netty.common:4.1.34.Final]
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [68:io.netty.common:4.1.34.Final]
    at java.lang.Thread.run(Thread.java:748) [?:?]
Caused by: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[-1,-1]
Message: Duplicate namespace "child-element1" element "ChildElement1" in XML input
    at org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream.read(XmlParserStream.java:383) ~[410:org.opendaylight.yangtools.yang-data-codec-xml:2.1.10]
    at org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream.read(XmlParserStream.java:321) ~[410:org.opendaylight.yangtools.yang-data-codec-xml:2.1.10]
    at org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream.read(XmlParserStream.java:403) ~[410:org.opendaylight.yangtools.yang-data-codec-xml:2.1.10]
    at org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream.read(XmlParserStream.java:321) ~[410:org.opendaylight.yangtools.yang-data-codec-xml:2.1.10]
    at org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream.read(XmlParserStream.java:403) ~[410:org.opendaylight.yangtools.yang-data-codec-xml:2.1.10]
    at org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream.parse(XmlParserStream.java:214) ~[410:org.opendaylight.yangtools.yang-data-codec-xml:2.1.10]
    at org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream.traverse(XmlParserStream.java:244) ~[410:org.opendaylight.yangtools.yang-data-codec-xml:2.1.10]
    at org.opendaylight.netconf.sal.connect.netconf.schema.mapping.NetconfMessageTransformer.toRpcResult(NetconfMessageTransformer.java:281) ~[386:org.opendaylight.netconf.sal-netconf-connector:1.9.1]
    ... 34 more

真的是因为名单吗?XML符合RFC 7950

7.8.5. XML Encoding Rules

A list is encoded as a series of XML elements, one for each entry in the list. Each element's local name is the list's identifier, and its namespace is the module's XML namespace (see Section 7.1.3). There is no XML element surrounding the list as a whole.

如有任何建议,将不胜感激。谢谢


共 (3) 个答案

  1. # 1 楼答案

    我不确定我是否知道这里的答案,但问题是否就那么简单 列表项的名称是否相同?例如:

    <ChildElement1 xmlns="child-element1">
    

    我知道身份证是独一无二的,但这对我来说很突出

  2. # 2 楼答案

    我可能偶然发现了什么
    我用不同的NETCONF服务器(ConfD)和相同的型号尝试了同样的方法,它似乎工作得很好
    我注意到的一个区别是,当对TopElement或ParentElement执行get-request操作时,ConfD返回按顺序排列的子列表,即首先返回所有ChildElement1元素,然后返回所有ChildElement2元素,即使它们是按随机顺序创建的。另一方面,Sysrepo-netopeer2以与创建元素相同的顺序返回XML树,因此ChildElement1元素和ChildElement2元素是混合的(参见我的示例)
    我不确定它们是否都是好的方法,或者是否有正确的方法和错误的方法

    编辑:在我最初的帖子中,我引用了RFC7950,但不知何故遗漏了相关部分:

    The XML elements representing list entries MUST appear in the order specified by the user if the list is "ordered-by user"; otherwise, the order is implementation dependent. The XML elements representing list entries MAY be interleaved with elements for siblings of the list, unless the list defines RPC or action input or output parameters.

    所以,假设我的假设是正确的,在这种情况下,ODL实际上限制太多了

  3. # 3 楼答案

    我猜这里的问题是服务器的响应在/TopElement/ParentElement处包含列表条目(按以下顺序):

    • ChildElement1[id=1]
    • ChildElement1[id=2]
    • ChildElement2[id=1]
    • ChildElement1[id=3]

    所以我假设ChildElement1和ChildElement2都是列表。 这里的问题是,CyelDelt1的3个条目不是顺序的,在中间有一个CHILDELMENT2的条目。

    我在NETCONF规范中没有看到任何东西说这是一个问题,但显然OpenDaylight有一个问题。 我假设OpenDayL光考虑对CyelDelMe2条目的处理,意味着CeldLeMe1列表已经被删除,因此在找到另一个条目之后,它将其视为一个单独的列表,并在XML输入EME>中生成异常重复命名空间“CHILDEELMET1”元素“CHILDELMENT1”。p>

    如果您想避免这个问题,我建议对服务器响应中的条目进行排序,以便相同列表中的条目放在一起

    所以重申一下,问题不在于单个列表项的顺序,而在于您将属于两个不同列表的项交错