Ошибка «Дублирование пространства имен при вводе XML» при получении списка через NETCONF с использованием Opendaylight - PullRequest
0 голосов
/ 08 апреля 2020

Я использую Opendaylight (выпуск 0.10.1) в качестве клиента NETCONF для отправки запросов на сервер Netopeer2.
Моя модель 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>

Однако такой запрос вызывает ошибку «Master is down», которую я пытался исследовать, используя файл журнала 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 соответствует RF C 7950 :

7.8.5. XML Правила кодирования

Список кодируется в виде последовательности XML элементов, по одному для каждой записи в списке. Локальное имя каждого элемента является идентификатором списка, а его пространство имен является пространством имен модуля XML (см. Раздел 7.1.3). Нет элемента XML, окружающего список в целом.

Любое предложение будет с благодарностью. Спасибо!

Ответы [ 2 ]

0 голосов
/ 14 апреля 2020

Я мог наткнуться на что-то.
Я попробовал то же самое на другом сервере NETCONF (ConfD) и на тех же моделях, и, кажется, он работает нормально.
Я заметил одно отличие в том, что при выполнении get-request в TopElement или ParentElement, ConfD возвращает упорядоченные дочерние списки, т.е. сначала все элементы ChildElement1, а затем все элементы ChildElement2, даже если они были созданы в случайном порядке. Sysrepo-netopeer2, с другой стороны, возвращает дерево XML с элементами в том же порядке, в котором они были созданы, поэтому элементы ChildElement1 и элементы ChildElement2 смешаны (см. Мой пример).
Я не уверен, если они оба хороши, или если есть правильный и неправильный.

РЕДАКТИРОВАТЬ: В моем оригинальном сообщении я цитировал RF C 7950 и как-то пропустил соответствующую часть:

Элементы XML, представляющие записи списка, ДОЛЖНЫ появляться в порядке, указанном пользователем, если список «упорядочен пользователем»; в противном случае порядок зависит от реализации. Элементы XML, представляющие записи списка, МОГУТ чередоваться с элементами для родных элементов списка , если в списке не указаны RP C или параметры ввода или вывода действия.

Итак Если предположить, что я прав в своем предположении, похоже, что в этом случае ODL слишком ограничен.

0 голосов
/ 08 апреля 2020

Я не уверен, что знаю ответ здесь, но может ли быть проблема в том, что некоторые элементы списка названы одинаково? как в:

<ChildElement1 xmlns="child-element1">

Я знаю, что идентификаторы уникальны, но это то, что выделилось мне.

...