[MDSAL-131] toString() throws exception for 'type binary' binding Created: 02/Mar/16 Updated: 08/Apr/22 Resolved: 13/May/16 |
|
| Status: | Verified |
| Project: | mdsal |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Bug | ||
| Reporter: | Lori Jakab | Assignee: | Peter Kajsa |
| Resolution: | Done | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Environment: |
Operating System: All |
||
| External issue ID: | 5446 |
| Priority: | Normal |
| Description |
|
In the lispflowmapping project we're trying to add support for binary IPv4 and IPv6 address types to use internally to improve performance when we don't need a string representation of the addresses. (See lines 24-51 in https://git.opendaylight.org/gerrit/gitweb?p=lispflowmapping.git;a=blob;f=mappingservice/lisp-proto/src/main/yang/odl-lisp-proto.yang;h=58bf372611c9937ec6c9a373966a3c8275f548a4;hb=HEAD) However, when we do try to get a string representation of the binary object, we get the following stack trace: 2016-03-01 15:47:28,756 | ERROR | pool-28-thread-1 | DOMNotificationRouterEvent | 140 - org.opendaylight.controller.sal-broker-impl - 1.4.0.SNAPSHOT | Delivery of notification org.opendaylight.controller.md.sal.binding.impl.LazySerializedDOMNotification@352556f7 caused an error in listener org.opendaylight.controller.md.sal.binding.impl.BindingDOMNotificationListenerAdapter@1c213c0c java.lang.IllegalStateException: Could not construct instance at org.opendaylight.yangtools.binding.data.codec.impl.UnionTypeCodec.deserialize(UnionTypeCodec.java:71)[91:org.opendaylight.mdsal.binding-dom-codec:0.9.0.SNAPSHOT] at org.opendaylight.yangtools.binding.data.codec.impl.LeafNodeCodecContext.deserializeObject(LeafNodeCodecContext.java:199)[91:org.opendaylight.mdsal.binding-dom-codec:0.9.0.SNAPSHOT] at org.opendaylight.yangtools.binding.data.codec.impl.DataObjectCodecContext.getBindingChildValue(DataObjectCodecContext.java:329)[91:org.opendaylight.mdsal.binding-dom-codec:0.9.0.SNAPSHOT] at org.opendaylight.yangtools.binding.data.codec.impl.LazyDataObject.getBindingData(LazyDataObject.java:122)[91:org.opendaylight.mdsal.binding-dom-codec:0.9.0.SNAPSHOT] at org.opendaylight.yangtools.binding.data.codec.impl.LazyDataObject.invoke(LazyDataObject.java:69)[91:org.opendaylight.mdsal.binding-dom-codec:0.9.0.SNAPSHOT] at com.sun.proxy.$Proxy86.getSourceRloc(Unknown Source)[237:org.opendaylight.lispflowmapping.mappingservice.lisp-proto:1.4.0.SNAPSHOT] at org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.mapping.record.container.MappingRecordBuilder$MappingRecordImpl.equals(MappingRecordBuilder.java:462)[237:org.opendaylight.lispflowmapping.mappingservice.lisp-proto:1.4.0.SNAPSHOT] at org.opendaylight.lispflowmapping.implementation.lisp.MapServer.handleMapRegister(MapServer.java:116)[240:org.opendaylight.lispflowmapping.mappingservice.implementation:1.4.0.SNAPSHOT] at org.opendaylight.lispflowmapping.implementation.LispMappingService.handleMapRegister(LispMappingService.java:156)[240:org.opendaylight.lispflowmapping.mappingservice.implementation:1.4.0.SNAPSHOT] at org.opendaylight.lispflowmapping.implementation.LispMappingService.onAddMapping(LispMappingService.java:184)[240:org.opendaylight.lispflowmapping.mappingservice.implementation:1.4.0.SNAPSHOT] at org.opendaylight.yangtools.yang.binding.util.NotificationListenerInvoker.invokeNotification(NotificationListenerInvoker.java:91)[70:org.opendaylight.mdsal.yang-binding:0.9.0.SNAPSHOT] at org.opendaylight.controller.md.sal.binding.impl.BindingDOMNotificationListenerAdapter.onNotification(BindingDOMNotificationListenerAdapter.java:44)[142:org.opendaylight.controller.sal-binding-broker-impl:1.4.0.SNAPSHOT] at org.opendaylight.controller.md.sal.dom.broker.impl.DOMNotificationRouterEvent.deliverNotification(DOMNotificationRouterEvent.java:56)[140:org.opendaylight.controller.sal-broker-impl:1.4.0.SNAPSHOT] at org.opendaylight.controller.md.sal.dom.broker.impl.DOMNotificationRouter$1.onEvent(DOMNotificationRouter.java:68)[140:org.opendaylight.controller.sal-broker-impl:1.4.0.SNAPSHOT] at org.opendaylight.controller.md.sal.dom.broker.impl.DOMNotificationRouter$1.onEvent(DOMNotificationRouter.java:65)[140:org.opendaylight.controller.sal-broker-impl:1.4.0.SNAPSHOT] at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:128)[137:com.lmax.disruptor:3.3.2] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)[:1.8.0_74] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)[:1.8.0_74] at java.lang.Thread.run(Thread.java:745)[:1.8.0_74] Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.GeneratedConstructorAccessor75.newInstance(Unknown Source)[:1.8.0_74] at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)[:1.8.0_74] at java.lang.reflect.Constructor.newInstance(Constructor.java:423)[:1.8.0_74] at org.opendaylight.yangtools.binding.data.codec.impl.UnionTypeCodec.deserialize(UnionTypeCodec.java:69)[91:org.opendaylight.mdsal.binding-dom-codec:0.9.0.SNAPSHOT] ... 18 more Caused by: java.lang.IllegalArgumentException: com.google.common.io.BaseEncoding$DecodingException: Unrecognized character: [ at com.google.common.io.BaseEncoding.decode(BaseEncoding.java:228)[62:com.google.guava:18.0.0] at org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.Ipv4AddressBinary.getDefaultInstance(Ipv4AddressBinary.java:51)[237:org.opendaylight.lispflowmapping.mappingservice.lisp-proto:1.4.0.SNAPSHOT] at org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.IpAddressBinaryBuilder.getDefaultInstance(IpAddressBinaryBuilder.java:16)[237:org.opendaylight.lispflowmapping.mappingservice.lisp-proto:1.4.0.SNAPSHOT] at org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.IpAddressBinary.<init>(IpAddressBinary.java:37)[237:org.opendaylight.lispflowmapping.mappingservice.lisp-proto:1.4.0.SNAPSHOT] ... 22 more Caused by: com.google.common.io.BaseEncoding$DecodingException: Unrecognized character: [ at com.google.common.io.BaseEncoding$Alphabet.decode(BaseEncoding.java:503)[62:com.google.guava:18.0.0] at com.google.common.io.BaseEncoding$StandardBaseEncoding$2.read(BaseEncoding.java:675)[62:com.google.guava:18.0.0] at com.google.common.io.BaseEncoding.decodeChecked(BaseEncoding.java:245)[62:com.google.guava:18.0.0] at com.google.common.io.BaseEncoding.decode(BaseEncoding.java:226)[62:com.google.guava:18.0.0] ... 25 more |
| Comments |
| Comment by Tony Tkacik [ 02/Mar/16 ] |
|
Could you please point to the model which triggered this and also binary data you were trying to set? |
| Comment by Lori Jakab [ 03/Mar/16 ] |
|
The module is odl-lisp-proto.yang, lines 24-51, see my initial report for a link to gitweb. The binary data we tried to set was an byte[] taken from am InetAddress. The problem happens not when trying to set it, but when it has to be converted to text with .toString(). |
| Comment by zhuweisheng [ 24/Mar/16 ] |
|
From the error log, may be you use Ipv4AddressBinary.getDefaultInstance("XXXX") to set binary data, and the "XXXX" contains '[', so you have the error. |
| Comment by Vina Ermagan [ 22/Apr/16 ] |
|
Any updates on this? Would really appreciate a fix. Thanks, |
| Comment by Lori Jakab [ 25/Apr/16 ] |
|
(In reply to Tony Tkacik from comment #1) On line 42 of the model that I linked to in the original bug report (odl-lisp-proto.yang) I'm defining a union of two binary types ipv4-address-binary and ipv6-address-binary as ip-address-binary. Yangtools autogenerates the IpAddressBinaryBuilder.java file under src/main/java instead of generated-sources/mdsal-binding, because it needs to be implemented. The implementation looks like this: Robert gave a quick look at the implementation (at the design forum), and said it should work as-is. However, if I try a IpAddressBinaryBuilder.getDefaultInstance("127.0.0.1") for example, I will get an exception. The exception from the original bug report for example is trying to log a packet address, where the address is stored in an Ipv4AddressBinary type. |
| Comment by Lori Jakab [ 25/Apr/16 ] |
|
Some additional info, I retested things, since the original report was a while ago. When I add an Ipv4AddressBinary object to the datastore and read it back with RESTCONF, it is represented like this: "fwAAAQ==", which is the expected base64 encoding of the binary data (127.0.0.1). However, an IpAddressBinary object, which is the union, looks like this: "[B@6fadb49c" which looks an awful lot like a reference instead of the object inside. Hope this helps fix the bug quicker. |
| Comment by Peter Kajsa [ 04/May/16 ] |
|
fix: |
| Comment by Lori Jakab [ 04/May/16 ] |
|
(In reply to Peter Kajsa from comment #7) I just tried the suggested fix. I still see "[B@125afdf3" for an ip-address-binary based field in RESTCONF output. The _value member in the IpAddressBinary object however looks ok. Here's some code I used to test the logging output, after reading an IPv4 address from a packet: if (sourceRloc instanceof Inet4Address) { The output looks like this: 2016-05-04 12:55:09,426 | INFO | lisp-sb-6-1 | MapRegisterSerializer | 255 - org.opendaylight.lispflowmapping.mappingservice.lisp-proto - 1.4.0.SNAPSHOT | Ipv4AddressBinary: Ipv4AddressBinary [_value=[127, 0, 0, 1]] | IpAddressBinary: IpAddressBinary [_ipv4AddressBinary=Ipv4AddressBinary [_value=[127, 0, 0, 1]], _value=[f, w, A, A, A, Q, =, =]] RESTCONF output still shows the memory reference. I just pushed some code that I use for RESTCONF testing here: |
| Comment by Peter Kajsa [ 04/May/16 ] |
|
Please let us know, whether the exception from your first comment (java.lang.IllegalStateException: Could not construct instance ...) still persists ? I think it should be ok now. However, there could be the same problem somewhere in Restconf as well, so we will look at it. |
| Comment by Lori Jakab [ 04/May/16 ] |
|
(In reply to Peter Kajsa from comment #9) I can't reproduce that exception anymore, so I think it's ok. > Thanks! |
| Comment by Lori Jakab [ 06/May/16 ] |
|
(In reply to Lori Jakab from comment #10) Actually, now that I tried to build some code using the union, I still see issues regardless of RESTCONF. You can take a look at the unit tests from the mappingservice.implementation module after applying this patch https://git.opendaylight.org/gerrit/#/c/38496/ LispMappingServiceTest.onAddMappingTest_noTransportAddress:196 If you take a look at the IpAddressBinary _value, it still shows a memory reference instead of a base64 string. |
| Comment by Lori Jakab [ 06/May/16 ] |
|
(In reply to Lori Jakab from comment #11) Or the bytes themselves, as it's shown for Ipv4AddressBinary _value. |
| Comment by Peter Kajsa [ 12/May/16 ] |
|
Yangtools union codec fix: https://git.opendaylight.org/gerrit/#/c/38669/ |
| Comment by Peter Kajsa [ 12/May/16 ] |
|
Please retest with the both patches and let us know the result. Thanks. |
| Comment by Lori Jakab [ 12/May/16 ] |
|
The two patches together fix all issues, including correct encoding in RESTCONF output. Thanks! |
| Comment by Robert Varga [ 12/May/16 ] |
|
mdsal Be: https://git.opendaylight.org/gerrit/38358 yangtools need a manual cherry-pick. |
| Comment by Peter Kajsa [ 13/May/16 ] |
|
Yangtools Be: https://git.opendaylight.org/gerrit/#/c/38853/1 |