[NETCONF-1082] Unable to write unkeyed list with RESTCONF PUT request Created: 12/Jul/23  Updated: 08/Aug/23  Resolved: 08/Aug/23

Status: Resolved
Project: netconf
Component/s: None
Affects Version/s: None
Fix Version/s: 7.0.0

Type: Bug Priority: Medium
Reporter: Peter Suna Assignee: Šimon Ukuš
Resolution: Won't Do Votes: 0
Labels: pt
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: PNG File image-2023-07-12-12-37-48-403.png     File test.yang     File toaster2@2009-11-20.yang    

 Description   

Prepared PUT operation in OpenApi for request "/yang-ext:mount/toaster2:lst'" return 500 with error-message "java.lang.IllegalArgumentException: Invalid nesting of data."



 Comments   
Comment by Peter Suna [ 19/Jul/23 ]

I have identified an issue in netconf. This problem can be replicated using the simple model provided in the attachment.

The issue occurs when a PUT request is sent to data with an unkeyed list. For instance, attempting to send this request to the provided "test.yang" model results in the problem.

curl --request PUT 'http://localhost:8181/rests/data/network-topology:network-topology/topology=topology-netconf/node=36001-sim-device/yang-ext:mount/test5:list' \
     --header 'accept: */*' \
     --header 'Content-Type: application/json' \
     --header 'Authorization: Basic YWRtaW46YWRtaW4=' \
     --data '{
        "test:list": [
            {
                "leaf": "Some leaf"
            }
        ]
     }'

Issue shown in karaf.log after sending this request pointing that problem could be at this place:
`NetconfMessageTransformUtil.createEditConfigAnyxml(NetconfMessageTransformUtil.java:325)`

13:12:21.481 WARN [qtp1489084574-906] Transaction(PUT) FAILED!
java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Invalid nesting of data.
    at com.google.common.util.concurrent.AbstractFuture.getDoneValue(AbstractFuture.java:592) ~[bundleFile:?]
    at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:571) ~[bundleFile:?]
    at com.google.common.util.concurrent.AbstractFuture$TrustedFuture.get(AbstractFuture.java:111) ~[bundleFile:?]
    at com.google.common.util.concurrent.ForwardingFluentFuture.get(ForwardingFluentFuture.java:68) ~[bundleFile:?]
    at org.opendaylight.restconf.nb.rfc8040.rests.utils.FutureCallbackTx.addCallback(FutureCallbackTx.java:71) ~[bundleFile:?]
    at org.opendaylight.restconf.nb.rfc8040.rests.utils.PutDataTransactionUtil.putData(PutDataTransactionUtil.java:73) ~[bundleFile:?]
    at org.opendaylight.restconf.nb.rfc8040.rests.services.impl.RestconfDataServiceImpl.putData(RestconfDataServiceImpl.java:227) ~[bundleFile:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[?:?]
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:568) ~[?:?]
    at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52) ~[?:?]
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:146) ~[?:?]
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:189) ~[?:?]
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:176) ~[?:?]
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:93) ~[?:?]
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:478) ~[?:?]
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:400) ~[?:?]
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:81) ~[?:?]
    at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:256) ~[?:?]
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248) ~[?:?]
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244) ~[?:?]
    at org.glassfish.jersey.internal.Errors.process(Errors.java:292) ~[?:?]
    at org.glassfish.jersey.internal.Errors.process(Errors.java:274) ~[?:?]
    at org.glassfish.jersey.internal.Errors.process(Errors.java:244) ~[?:?]
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265) ~[?:?]
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:235) ~[?:?]
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:684) ~[?:?]
    at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:394) ~[?:?]
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346) ~[?:?]
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:358) ~[?:?]
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:311) ~[?:?]
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205) ~[?:?]
    at org.ops4j.pax.web.service.spi.servlet.OsgiInitializedServlet.service(OsgiInitializedServlet.java:102) ~[bundleFile:?]
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1656) ~[bundleFile:9.4.50.v20221201]
    at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61) ~[?:?]
    at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108) ~[?:?]
    at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137) ~[?:?]
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:154) ~[?:?]
    at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66) ~[?:?]
    at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108) ~[?:?]
    at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137) ~[?:?]
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:154) ~[?:?]
    at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66) ~[?:?]
    at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:458) ~[?:?]
    at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:373) ~[?:?]
    at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90) ~[?:?]
    at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83) ~[?:?]
    at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:387) ~[?:?]
    at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:370) ~[?:?]
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:154) ~[?:?]
    at org.ops4j.pax.web.service.spi.servlet.OsgiInitializedFilter.doFilter(OsgiInitializedFilter.java:176) ~[bundleFile:?]
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626) ~[bundleFile:9.4.50.v20221201]
    at org.opendaylight.aaa.filterchain.filters.CustomFilterAdapter.doFilter(CustomFilterAdapter.java:73) ~[bundleFile:?]
    at org.ops4j.pax.web.service.spi.servlet.OsgiInitializedFilter.doFilter(OsgiInitializedFilter.java:176) ~[bundleFile:?]
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626) ~[bundleFile:9.4.50.v20221201]
    at org.ops4j.pax.web.service.spi.servlet.OsgiFilterChain.doFilter(OsgiFilterChain.java:100) ~[bundleFile:?]
    at org.ops4j.pax.web.service.jetty.internal.PaxWebServletHandler.doHandle(PaxWebServletHandler.java:310) ~[bundleFile:?]
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:600) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:505) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:234) ~[bundleFile:9.4.50.v20221201]
    at org.ops4j.pax.web.service.jetty.internal.PrioritizedHandlerCollection.handle(PrioritizedHandlerCollection.java:96) ~[bundleFile:?]
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.server.Server.handle(Server.java:516) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883) ~[bundleFile:9.4.50.v20221201]
    at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034) ~[bundleFile:9.4.50.v20221201]
    at java.lang.Thread.run(Thread.java:833) ~[?:?]
Caused by: java.lang.IllegalArgumentException: Invalid nesting of data.
    at com.google.common.base.Preconditions.checkArgument(Preconditions.java:143) ~[bundleFile:?]
    at org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter.checkDataNodeContainer(ImmutableNormalizedNodeStreamWriter.java:290) ~[bundleFile:?]
    at org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter.startUnkeyedList(ImmutableNormalizedNodeStreamWriter.java:154) ~[bundleFile:?]
    at org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter.wasProcessedAsCompositeNode(NormalizedNodeWriter.java:195) ~[bundleFile:?]
    at org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter.write(NormalizedNodeWriter.java:99) ~[bundleFile:?]
    at org.opendaylight.netconf.client.mdsal.impl.NetconfMessageTransformUtil.createEditConfigAnyxml(NetconfMessageTransformUtil.java:325) ~[?:?]
    at org.opendaylight.netconf.client.mdsal.impl.NetconfRpcStructureTransformer.createEditConfigStructure(NetconfRpcStructureTransformer.java:64) ~[?:?]
    at org.opendaylight.netconf.client.mdsal.impl.NetconfBaseOps.createEditConfigStructure(NetconfBaseOps.java:362) ~[?:?]
    at org.opendaylight.netconf.client.mdsal.spi.AbstractNetconfDataTreeService.replace(AbstractNetconfDataTreeService.java:303) ~[?:?]
    at org.opendaylight.restconf.nb.rfc8040.rests.transactions.NetconfRestconfTransaction.lambda$replace$6(NetconfRestconfTransaction.java:115) ~[bundleFile:?]
    at org.opendaylight.restconf.nb.rfc8040.rests.transactions.NetconfRestconfTransaction.lambda$enqueueOperation$7(NetconfRestconfTransaction.java:210) ~[bundleFile:?]
    at com.google.common.util.concurrent.AbstractTransformFuture$AsyncTransformFuture.doTransform(AbstractTransformFuture.java:223) ~[bundleFile:?]
    at com.google.common.util.concurrent.AbstractTransformFuture$AsyncTransformFuture.doTransform(AbstractTransformFuture.java:210) ~[bundleFile:?]
    at com.google.common.util.concurrent.AbstractTransformFuture.run(AbstractTransformFuture.java:123) ~[bundleFile:?]
    at com.google.common.util.concurrent.DirectExecutor.execute(DirectExecutor.java:31) ~[bundleFile:?]
    at com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1286) ~[bundleFile:?]
    at com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:1055) ~[bundleFile:?]
    at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:782) ~[bundleFile:?]
    at com.google.common.util.concurrent.CombinedFuture$CallableInterruptibleTask.setValue(CombinedFuture.java:201) ~[bundleFile:?]
    at com.google.common.util.concurrent.CombinedFuture$CombinedFutureInterruptibleTask.afterRanInterruptiblySuccess(CombinedFuture.java:129) ~[bundleFile:?]
    at com.google.common.util.concurrent.InterruptibleTask.run(InterruptibleTask.java:88) ~[bundleFile:?]
    at com.google.common.util.concurrent.DirectExecutor.execute(DirectExecutor.java:31) ~[bundleFile:?]
    at com.google.common.util.concurrent.CombinedFuture$CombinedFutureInterruptibleTask.execute(CombinedFuture.java:108) ~[bundleFile:?]
    at com.google.common.util.concurrent.CombinedFuture.handleAllCompleted(CombinedFuture.java:65) ~[bundleFile:?]
    at com.google.common.util.concurrent.AggregateFuture.processCompleted(AggregateFuture.java:301) ~[bundleFile:?]
    at com.google.common.util.concurrent.AggregateFuture.decrementCountAndMaybeComplete(AggregateFuture.java:283) ~[bundleFile:?]
    at com.google.common.util.concurrent.AggregateFuture.lambda$init$1(AggregateFuture.java:181) ~[bundleFile:?]
    at com.google.common.util.concurrent.DirectExecutor.execute(DirectExecutor.java:31) ~[bundleFile:?]
    at com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1286) ~[bundleFile:?]
    at com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:1055) ~[bundleFile:?]
    at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:782) ~[bundleFile:?]
    at com.google.common.util.concurrent.SettableFuture.set(SettableFuture.java:49) ~[bundleFile:?]
    at org.opendaylight.netconf.client.mdsal.spi.NetconfDeviceRpc$1.onSuccess(NetconfDeviceRpc.java:68) ~[?:?]
    at org.opendaylight.netconf.client.mdsal.spi.NetconfDeviceRpc$1.onSuccess(NetconfDeviceRpc.java:56) ~[?:?]
    at com.google.common.util.concurrent.Futures$CallbackListener.run(Futures.java:1133) ~[bundleFile:?]
    at com.google.common.util.concurrent.DirectExecutor.execute(DirectExecutor.java:31) ~[bundleFile:?]
    at com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1286) ~[bundleFile:?]
    at com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:1055) ~[bundleFile:?]
    at com.google.common.util.concurrent.AbstractFuture.set(AbstractFuture.java:782) ~[bundleFile:?]
    at org.opendaylight.netconf.client.mdsal.UncancellableFuture.set(UncancellableFuture.java:45) ~[?:?]
    at org.opendaylight.netconf.client.mdsal.NetconfDeviceCommunicator.processMessage(NetconfDeviceCommunicator.java:299) ~[?:?]
    at org.opendaylight.netconf.client.mdsal.NetconfDeviceCommunicator.onMessage(NetconfDeviceCommunicator.java:218) ~[?:?]
    at org.opendaylight.netconf.client.mdsal.NetconfDeviceCommunicator.onMessage(NetconfDeviceCommunicator.java:48) ~[?:?]
    at org.opendaylight.netconf.nettyutil.AbstractNetconfSession.handleMessage(AbstractNetconfSession.java:68) ~[?:?]
    at org.opendaylight.netconf.nettyutil.AbstractNetconfSession.channelRead0(AbstractNetconfSession.java:195) ~[?:?]
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99) ~[?:?]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[?:?]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[?:?]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[?:?]
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346) ~[?:?]
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318) ~[?:?]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[?:?]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[?:?]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[?:?]
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346) ~[?:?]
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318) ~[?:?]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[?:?]
    at io.netty.channel.AbstractChannelHandlerContext.access$600(AbstractChannelHandlerContext.java:61) ~[?:?]
    at io.netty.channel.AbstractChannelHandlerContext$7.run(AbstractChannelHandlerContext.java:425) ~[?:?]
    at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174) ~[?:?]
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167) ~[?:?]
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470) ~[?:?]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569) ~[?:?]
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[?:?]
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[?:?]
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[?:?]
    ... 1 more
 

 

Comment by Ivan Hrasko [ 19/Jul/23 ]
The "key" statement, which MUST be present if the list represents
configuration and MAY be present otherwise, takes as an argument a
string that specifies a space-separated list of one or more leaf
identifiers of this list.

https://datatracker.ietf.org/doc/html/rfc7950#section-7.8.2

I would expect that list like this in config:false.

Comment by Ivan Hrasko [ 21/Jul/23 ]

We will just change our testing data to config false; in order to be compliant with rfc7950. In addition, there is a bug created into yangtools project: YANGTOOLS-1526.

Comment by Ivan Hrasko [ 08/Aug/23 ]

We have no intention to control any knob. For our purposes, just changing test data to conform to specification is OK.

Generated at Wed Feb 07 20:16:37 UTC 2024 using Jira 8.20.10#820010-sha1:ace47f9899e9ee25d7157d59aa17ab06aee30d3d.