[CONTROLLER-1494] Fails to inject config module with no list dependency entry Created: 01/Mar/16  Updated: 25/Jul/23  Resolved: 20/Apr/16

Status: Resolved
Project: controller
Component/s: config
Affects Version/s: None
Fix Version/s: None

Type: Bug
Reporter: Milos Fabian Assignee: Andrej Mak
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issue Links:
Blocks
blocks BGPCEP-409 Support Route Refresh operation from BGP Resolved
External issue ID: 5444

 Description   

Steps to reproduce:
1. Run ODL Karaf distribution (Boron)
2. Install features odl-bgpcep-bgp-all odl-restconf odl-netconf-connector-all
3. Via RESTCONF add BGP peer config module as per https://wiki.opendaylight.org/view/BGP_LS_PCEP:User_Guide#BGP_Peer_2
4. Observe the exception in response and ODL logs:

2016-03-01 11:00:24,011 | ERROR | entLoopGroup-6-2 | NetconfOperationRouterImpl | 285 - org.opendaylight.netconf.impl - 1.1.0.SNAPSHOT | Unexpected exception during netconf operation execution
java.lang.IllegalStateException: Unable to set attributes for org.opendaylight.controller:instanceName=example-bgp-peer,TransactionName=ConfigTransaction-105-113,type=Module,moduleFactoryName=bgp-peer, Error with attribute add-path:AttributeConfigElement [defaultValue=null, value=null]
at org.opendaylight.controller.config.facade.xml.strategy.ReplaceEditConfigStrategy.executeStrategy(ReplaceEditConfigStrategy.java:60)[133:org.opendaylight.controller.config-manager-facade-xml:0.5.0.SNAPSHOT]
at org.opendaylight.controller.config.facade.xml.strategy.AbstractEditConfigStrategy.executeConfiguration(AbstractEditConfigStrategy.java:33)[133:org.opendaylight.controller.config-manager-facade-xml:0.5.0.SNAPSHOT]
at org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade.setOnTransaction(ConfigSubsystemFacade.java:238)[133:org.opendaylight.controller.config-manager-facade-xml:0.5.0.SNAPSHOT]
at org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade.test(ConfigSubsystemFacade.java:165)[133:org.opendaylight.controller.config-manager-facade-xml:0.5.0.SNAPSHOT]
at org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade.executeTests(ConfigSubsystemFacade.java:149)[133:org.opendaylight.controller.config-manager-facade-xml:0.5.0.SNAPSHOT]
at org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade.executeConfigExecution(ConfigSubsystemFacade.java:123)[133:org.opendaylight.controller.config-manager-facade-xml:0.5.0.SNAPSHOT]
at org.opendaylight.netconf.confignetconfconnector.operations.editconfig.EditConfig.getResponseInternal(EditConfig.java:48)[287:org.opendaylight.netconf.config-netconf-connector:1.1.0.SNAPSHOT]
at org.opendaylight.netconf.confignetconfconnector.operations.editconfig.EditConfig.handleWithNoSubsequentOperations(EditConfig.java:75)[287:org.opendaylight.netconf.config-netconf-connector:1.1.0.SNAPSHOT]
at org.opendaylight.netconf.util.mapping.AbstractLastNetconfOperation.handle(AbstractLastNetconfOperation.java:33)[198:org.opendaylight.netconf.util:1.1.0.SNAPSHOT]
at org.opendaylight.netconf.util.mapping.AbstractNetconfOperation.handle(AbstractNetconfOperation.java:101)[198:org.opendaylight.netconf.util:1.1.0.SNAPSHOT]
at org.opendaylight.netconf.impl.osgi.NetconfOperationRouterImpl$NetconfOperationExecution.execute(NetconfOperationRouterImpl.java:182)[285:org.opendaylight.netconf.impl:1.1.0.SNAPSHOT]
at org.opendaylight.netconf.impl.osgi.NetconfOperationRouterImpl.executeOperationWithHighestPriority(NetconfOperationRouterImpl.java:111)[285:org.opendaylight.netconf.impl:1.1.0.SNAPSHOT]
at org.opendaylight.netconf.impl.osgi.NetconfOperationRouterImpl.onNetconfMessage(NetconfOperationRouterImpl.java:84)[285:org.opendaylight.netconf.impl:1.1.0.SNAPSHOT]
at org.opendaylight.netconf.impl.NetconfServerSessionListener.processDocument(NetconfServerSessionListener.java:113)[285:org.opendaylight.netconf.impl:1.1.0.SNAPSHOT]
at org.opendaylight.netconf.impl.NetconfServerSessionListener.onMessage(NetconfServerSessionListener.java:86)[285:org.opendaylight.netconf.impl:1.1.0.SNAPSHOT]
at org.opendaylight.netconf.impl.NetconfServerSessionListener.onMessage(NetconfServerSessionListener.java:29)[285:org.opendaylight.netconf.impl:1.1.0.SNAPSHOT]
at org.opendaylight.netconf.nettyutil.AbstractNetconfSession.handleMessage(AbstractNetconfSession.java:64)[199:org.opendaylight.netconf.netty-util:1.1.0.SNAPSHOT]
at org.opendaylight.netconf.nettyutil.AbstractNetconfSession.handleMessage(AbstractNetconfSession.java:35)[199:org.opendaylight.netconf.netty-util:1.1.0.SNAPSHOT]
at org.opendaylight.protocol.framework.AbstractProtocolSession.channelRead0(AbstractProtocolSession.java:53)[107:org.opendaylight.controller.protocol-framework:0.8.0.SNAPSHOT]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)[92:io.netty.transport:4.0.33.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:318)[92:io.netty.transport:4.0.33.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:304)[92:io.netty.transport:4.0.33.Final]
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:276)[93:io.netty.codec:4.0.33.Final]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:263)[93:io.netty.codec:4.0.33.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:318)[92:io.netty.transport:4.0.33.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:304)[92:io.netty.transport:4.0.33.Final]
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:276)[93:io.netty.codec:4.0.33.Final]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:263)[93:io.netty.codec:4.0.33.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:318)[92:io.netty.transport:4.0.33.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:304)[92:io.netty.transport:4.0.33.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:846)[92:io.netty.transport:4.0.33.Final]
at io.netty.channel.local.LocalChannel.finishPeerRead0(LocalChannel.java:427)[92:io.netty.transport:4.0.33.Final]
at io.netty.channel.local.LocalChannel.access$500(LocalChannel.java:48)[92:io.netty.transport:4.0.33.Final]
at io.netty.channel.local.LocalChannel$5.run(LocalChannel.java:383)[92:io.netty.transport:4.0.33.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:358)[91:io.netty.common:4.0.33.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:357)[92:io.netty.transport:4.0.33.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:112)[91:io.netty.common:4.0.33.Final]
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)[91:io.netty.common:4.0.33.Final]
at java.lang.Thread.run(Thread.java:745)[:1.8.0_66]
Caused by: javax.management.RuntimeMBeanException: javax.management.RuntimeMBeanException: java.lang.IllegalArgumentException: Null not supported
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.rethrow(DefaultMBeanServerInterceptor.java:839)[:1.8.0_66]
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.rethrowMaybeMBeanException(DefaultMBeanServerInterceptor.java:852)[:1.8.0_66]
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.setAttribute(DefaultMBeanServerInterceptor.java:752)[:1.8.0_66]
at com.sun.jmx.mbeanserver.JmxMBeanServer.setAttribute(JmxMBeanServer.java:739)[:1.8.0_66]
at org.opendaylight.controller.config.util.ConfigTransactionJMXClient.setAttribute(ConfigTransactionJMXClient.java:288)[127:org.opendaylight.controller.config-util:0.5.0.SNAPSHOT]
at org.opendaylight.controller.config.facade.xml.strategy.ReplaceEditConfigStrategy.executeStrategy(ReplaceEditConfigStrategy.java:49)[133:org.opendaylight.controller.config-manager-facade-xml:0.5.0.SNAPSHOT]
... 38 more
Caused by: javax.management.RuntimeMBeanException: java.lang.IllegalArgumentException: Null not supported
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.rethrow(DefaultMBeanServerInterceptor.java:839)[:1.8.0_66]
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.rethrowMaybeMBeanException(DefaultMBeanServerInterceptor.java:852)[:1.8.0_66]
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.setAttribute(DefaultMBeanServerInterceptor.java:752)[:1.8.0_66]
at com.sun.jmx.mbeanserver.JmxMBeanServer.setAttribute(JmxMBeanServer.java:739)[:1.8.0_66]
at org.opendaylight.controller.config.manager.impl.dynamicmbean.DynamicWritableWrapper.setAttribute(DynamicWritableWrapper.java:96)[131:org.opendaylight.controller.config-manager:0.5.0.SNAPSHOT]
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.setAttribute(DefaultMBeanServerInterceptor.java:746)[:1.8.0_66]
... 41 more
Caused by: java.lang.IllegalArgumentException: Null not supported
at org.opendaylight.controller.config.yang.bgp.rib.impl.AbstractBGPPeerModule.setAddPath(AbstractBGPPeerModule.java:282)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)[:1.8.0_66]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)[:1.8.0_66]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[:1.8.0_66]
at java.lang.reflect.Method.invoke(Method.java:497)[:1.8.0_66]
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)[:1.8.0_66]
at sun.reflect.GeneratedMethodAccessor29.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[:1.8.0_66]
at java.lang.reflect.Method.invoke(Method.java:497)[:1.8.0_66]
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)[:1.8.0_66]
at com.sun.jmx.mbeanserver.ConvertingMethod.invokeWithOpenReturn(ConvertingMethod.java:193)[:1.8.0_66]
at com.sun.jmx.mbeanserver.ConvertingMethod.invokeWithOpenReturn(ConvertingMethod.java:175)[:1.8.0_66]
at com.sun.jmx.mbeanserver.MXBeanIntrospector.invokeM2(MXBeanIntrospector.java:117)[:1.8.0_66]
at com.sun.jmx.mbeanserver.MXBeanIntrospector.invokeM2(MXBeanIntrospector.java:54)[:1.8.0_66]
at com.sun.jmx.mbeanserver.MBeanIntrospector.invokeSetter(MBeanIntrospector.java:267)[:1.8.0_66]
at com.sun.jmx.mbeanserver.PerInterface.setAttribute(PerInterface.java:102)[:1.8.0_66]
at com.sun.jmx.mbeanserver.MBeanSupport.setAttribute(MBeanSupport.java:230)[:1.8.0_66]
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.setAttribute(DefaultMBeanServerInterceptor.java:746)[:1.8.0_66]
... 44 more

The system complains about missing (null) "add-path" attribute. The "add-path" is defined in odl-bgp-rib-rib-impl-cfg.yang as
list add-path {
key "type name";
uses config:service-ref {
refine type

{ config:required-identity add-path; }

}
}

The input XML does not contain any entry with add-path dependency. When the same module is defined in initial config xml file - it works.



 Comments   
Comment by Kangqian Yin [ 07/Apr/16 ]

Did you specify value of "replace" in "default-operation" attribute of "edit-config" tag in your netconf message to configure example-bgp-peer module?

I've tested that if "merge" specifed, such netconf message in https://wiki.opendaylight.org/view/BGP_LS_PCEP:User_Guide#BGP_Peer_2 can be commited correctly. If "replace" specified, such netconf message will yield similar errors as you encounterd.

RFC6241 definitely says that "merge" is the default behaviour in Section 7.2. So odl config subsystem pushes xml config file in merge strategy. That's why such netconf messages in 41-bgp-example.xml can be pushed correctly.

Comment by Vratko Polak [ 07/Apr/16 ]

As far as I know, using RESTCONF via netconf-connector picks operation based on HTTP method. POST means create, PUT means replace, and I guess merge can be achieved using PATCH.
I have not tried using POST (or PATCH), but I believe replace ought to work in this use case.

Comment by Kangqian Yin [ 08/Apr/16 ]

Just as Vratko said, POST means create, PUT means replace. So when I tried to POST or PUT a new value to an attribute of an existing module through RESTCONF, both failed. When I tried to PATCH, ODL controller complained as following:

< HTTP/1.1 405 Method Not Allowed
< Allow: POST,GET,DELETE,OPTIONS,HEAD,PUT
< Content-Length: 0
< Server: Jetty(8.1.15.v20140411)

Since PUT means replace, then I wanted to PUT new value to RESTCONF URI of the node of the attribute of the module, it still failed because the attribute node is a Leaf yang type. Current ODL netconf operations only support to PUT a node of Container or List yang type.

Summing up my experiments, I haven't found a convenient way to assign new value to a leaf node attribute of an existing module. If it's true for ODL, we need to add a such way.

Comment by Kangqian Yin [ 08/Apr/16 ]

(In reply to Kangqian Yin from comment #3)
> Just as Vratko said, POST means create, PUT means replace. So when I tried
> to POST or PUT a new value to an attribute of an existing module through
> RESTCONF, both failed. When I tried to PATCH, ODL controller complained as
> following:
>
> < HTTP/1.1 405 Method Not Allowed
> < Allow: POST,GET,DELETE,OPTIONS,HEAD,PUT
> < Content-Length: 0
> < Server: Jetty(8.1.15.v20140411)
>
> Since PUT means replace, then I wanted to PUT new value to RESTCONF URI of
> the node of the attribute of the module, it still failed because the
> attribute node is a Leaf yang type. Current ODL netconf operations only
> support to PUT a node of Container or List yang type.
>
> Summing up my experiments, I haven't found a convenient way to assign new
> value to a leaf node attribute of an existing module. If it's true for ODL,
> we need to add a such way.

It's more accurate to say that current ODL netconf server only supports to PUT a node of Container or List yang type through RESTCONF. And there is a convenient way to assign new value to a leaf node attribute of an existing module through netconf messages issued by sucn netconf client as Netconf Browser. It seems lacking of such way through RESTCONF in ODL.

Comment by Vratko Polak [ 08/Apr/16 ]

< Allow: POST,GET,DELETE,OPTIONS,HEAD,PUT

Which version of ODL are you using? I believe PATCH is supported since Beryllium-SR1.
https://git.opendaylight.org/gerrit/36163

> only supports to PUT a node of Container or List yang type through RESTCONF.

True for RESTCONF as far as I know.
https://bugs.opendaylight.org/show_bug.cgi?id=1013

> current ODL netconf server only supports to PUT a node of Container or List yang type

ODL contains two netconf servers. One for config subsystem (relevant for this Bug) and one for MD-SAL (not relevant here).
The config subsystem server supports operations on containers (maybe also lists), but only if they are at the top level of their module.
https://bugs.opendaylight.org/show_bug.cgi?id=3753

Comment by Kangqian Yin [ 11/Apr/16 ]

(In reply to Vratko Polák from comment #5)
> < Allow: POST,GET,DELETE,OPTIONS,HEAD,PUT
>
> Which version of ODL are you using? I believe PATCH is supported since
> Beryllium-SR1.
> https://git.opendaylight.org/gerrit/36163
>

>> My experiments were done with Li-SR4 version of ODL. And I've just tried the master branch version of ODL and got the same result. It's because Jetty server is still 8.1.5.v20140411 in current version of ODL as in Li-SR4.

Comment by Andrej Mak [ 12/Apr/16 ]

Empty list allowed by patch
https://git.opendaylight.org/gerrit/#/c/37433/

However, module odl-bgp-rib-impl-cfg.yang is not valid.
Augment "/config:modules/config:module/config:configuration" cases bgp-peer and bgp-application-peer contains node with same name - "peer-registry", which is not allowed by yang rfc.

Comment by Milos Fabian [ 12/Apr/16 ]

(In reply to Andrej Mak from comment #7)
> Empty list allowed by patch
> https://git.opendaylight.org/gerrit/#/c/37433/
>
> However, module odl-bgp-rib-impl-cfg.yang is not valid.
> Augment "/config:modules/config:module/config:configuration" cases bgp-peer
> and bgp-application-peer contains node with same name - "peer-registry",
> which is not allowed by yang rfc.

Good point, thanks Andrej!

Comment by Kangqian Yin [ 19/Apr/16 ]

Let me explain Andrej's fixing. Andrej just modified a few lines in TemplateFactory.java which is part of yang-jmx-generator plugin.
How does it fix this bug?

The key to understand this is in the attribute setters of AbstractXXXModule
generated by yang-jmx-generator plugin from the YANG file of a ODL
configuration module.

Current setter of a list node attribute is like the following:

public void setLocalTable(java.util.List<javax.management.ObjectName> localTable) {
if (localTable == null) throw new IllegalArgumentException("Null not supported");
this.localTable = localTable;
}

Andrej's fixing changed it to be somehow like this:

public void setLocalTable(java.util.List<javax.management.ObjectName> localTable) {
if (localTable == null)

{ localTable = new java.util.ArrayList<>(); }

;
this.localTable = localTable;
}

So new attributes of a module with empty lists can be set and merged with current attributes of a module successfully.

Generated at Wed Feb 07 19:55:41 UTC 2024 using Jira 8.20.10#820010-sha1:ace47f9899e9ee25d7157d59aa17ab06aee30d3d.