[YANGTOOLS-160] String needs to be changed to Object (or Enum) in the method TypeDefinitionAwareCodec$EnumCodecStringImpl.serialize Created: 12/May/14  Updated: 10/Apr/22  Resolved: 21/May/14

Status: Verified
Project: yangtools
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug
Reporter: Flavio Fernandes Assignee: Tom Pantelis
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: PC


External issue ID: 990

 Description   

While following the md-sal tutorial on ping: https://wiki.opendaylight.org/view/Ping

I see the exception below when exercising the RPC rest call as shown:

http://localhost:8080/restconf/operations/ping:send-echo
With the following headers:
Content-Type: application/yang.operation+json
Cache-Control: no-cache
and the data set to raw Json encoded data (for POSTMAN at least)
{ "input" :

{ "destination" : "127.0.0.1" }

}

From: Tom Pantelis <tompantelis@gmail.com>
Subject: Re: 2014-05-10 16:21:48.964 EDT [http-bio-8080-exec-7] ERROR o.o.c.sal.restconf.impl.RestCodec - ClassCastException was thrown when codec is invoked with parameter Unreachable java.lang.ClassCastException: org.opendaylight.yang.gen.v1.urn.opendaylight.ping.rev130911.SendEchoOutput$EchoResult cannot be cast to java.lang.String
Date: May 12, 2014 at 11:06:04 AM EDT
To: Flavio Fernandes <ffernand@redhat.com>

That code is in the yangtools project - check the contributor list. I would say create a bug in the yangtools project to get the ball rolling.

I definitely think String needs to be changed to Object (or Enum) in the method and generic type signatures similar to what was done in YANGTOOLS-129.

On Mon, May 12, 2014 at 9:21 AM, Flavio Fernandes <ffernand@redhat.com> wrote:

Thanks, Tom. Yeah, I agree 100%. I played with TypeDefinitionAwareCodec.java as much as I could to make it work, but my Java skills are just
not there yet.

Do you know who would be the most familiar with that code? I’m trying to reach Tony T. but no answer yet.

Maybe he is busy at the OpenStack Summit.

Chhers,

— flavio

On May 11, 2014, at 12:56 PM, Tom Pantelis <tompantelis@gmail.com> wrote:

Flavio,

I'm not familiar with this code but it looks like the ex occurs when invoking the EnumCodecStringImp.serialize method because the JVM can't cast the input parameter of type EchoResult enum instance to a String. It seems to me that EnumCodecStringImp.serialize should take an Object param - all it does anyway is return toString() on the param.

Tom

On Sat, May 10, 2014 at 6:17 PM, Flavio Fernandes <ffernand@redhat.com> wrote:
Hi Tom,

While doing the MD-SAL tutorial on ping ( https://wiki.opendaylight.org/view/Ping ), I hit an exception that looks like this:

...
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_51]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_51]
at java.lang.Thread.run(Thread.java:744) [na:1.7.0_51]
2014-05-10 16:21:48.964 EDT [http-bio-8080-exec-7] ERROR o.o.c.sal.restconf.impl.RestCodec - ClassCastException was thrown when codec is invoked with parameter Unreachable
java.lang.ClassCastException: org.opendaylight.yang.gen.v1.urn.opendaylight.ping.rev130911.SendEchoOutput$EchoResult cannot be cast to java.lang.String
at org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec$EnumCodecStringImpl.serialize(TypeDefinitionAwareCodec.java:512) ~[bundlefile:na]
at org.opendaylight.controller.sal.restconf.impl.RestCodec$ObjectCodec.serialize(RestCodec.java:141) ~[bundlefile:na]
at org.opendaylight.controller.sal.rest.impl.JsonMapper.writeValueOfNodeByType(JsonMapper.java:240) [bundlefile:na]
at org.opendaylight.controller.sal.rest.impl.JsonMapper.writeLeaf(JsonMapper.java:193) [bundlefile:na]
...
Is this YANGTOOLS-129? I cannot tell if the issue is that yang tools is not providing a toString() in the generated source, or if the 'EnumCodecStringImpl' in TypeDefinitionAwareCodec.java should be made smarter to invoke 'getIntValue()' in this situation. If you think that should be the latter case, I may take a stab at 'fixing', under your wing, of course.

Thanks,

– flavio



 Comments   
Comment by Tom Pantelis [ 13/May/14 ]

This same issue occurs in the toaster example when invoking the make-toast RPC via restconf:

HTTP Method => POST
URL => http://localhost:8080/restconf/operations/toaster:make-toast
Header => Content-Type: application/yang.data+json
Body =>
{
"input" :

{ "toaster:toasterDoneness" : "10", "toaster:toasterToastType":"wheat-bread" }

}

osgi> 2014-05-06 18:35:47.476 EDT [http-bio-8080-exec-1] ERROR o.o.c.sal.restconf.impl.RestCodec - ClassCastException was thrown when codec is invoked with parameter Up
java.lang.ClassCastException: org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.Toaster$ToasterStatus cannot be cast to java.lang.String
at org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec$EnumCodecStringImpl.serialize(TypeDefinitionAwareCodec.java:512) ~[bundlefile:na]
at org.opendaylight.controller.sal.restconf.impl.RestCodec$ObjectCodec.serialize(RestCodec.java:141) ~[bundlefile:na]

Comment by Tom Pantelis [ 13/May/14 ]

In the Toaster example, the exception actually occurs on a GET to http://localhost:8080/restconf/operational/toaster:toaster when attempting to convert the ToasterStatus enum value.

The node value passed to EnumCodecStringImpl.serialize is an Enum type and not a String. RestCodec$ObjectCodec.serialize actually catches the exception, logs it and returns the original input value:

try

{ .... }

else {
TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<>>
typeAwarecodec = TypeDefinitionAwareCodec.from(type);
if (typeAwarecodec != null)

{ return typeAwarecodec.serialize(input); }

else

{ logger.debug("Codec for type \"" + type.getQName().getLocalName() + "\" is not implemented yet."); return null; }

}
}
catch (ClassCastException e)

{ // TODO remove this catch when // everyone use codecs logger.error(ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input), e); return input; }

JsonMapper.writeValueOfNodeByType then takes the returned ToasterStatus enum and "toString"'s it via String.valueOf:

String value = String.valueOf(RestCodec.from(baseType,
mountPoint).serialize(node.getValue()));

So the exception is actually benign - RestCodec.from fails internally but the JsonMapper works correctly and the json data is returned correctly to the client.

Changing EnumCodecStringImpl.serialize to take an Object should avoid the exception.

Comment by Tom Pantelis [ 14/May/14 ]

The root cause of this issue is actually in the codec generated toDomStatic method:

org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.Toaster$ToasterStatus getToasterStatus =
value.getToasterStatus();
if(getToasterStatus != null) {
org.opendaylight.yangtools.yang.common.QName _qname =
org.opendaylight.yangtools.yang.common.QName.create(_resultName,"toasterStatus");
Object _propValue = getToasterStatus;
if(_propValue != null)

{ Object _domValue = java.util.Collections.singletonMap(_qname,_propValue); _childNodes.add(_domValue); }

}

Instead of returning the enum, it should call:

org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.Toaster$ToasterStatus$Codec$DOM.toDomValue

Comment by Tom Pantelis [ 20/May/14 ]

This is issue was resolved by an upstream merge.

Comment by Tony Tkacik [ 21/May/14 ]

Bugfix was: https://git.opendaylight.org/gerrit/7019

Comment by Flavio Fernandes [ 21/May/14 ]

Fixed as of:

org.opendaylight.controller.version = 0.1
org.opendaylight.controller.build.scm.version = 0f1fdd655ea9dda3b0db24b6d1140fabcc10407d
org.opendaylight.controller.build.user = ffernand
org.opendaylight.controller.build.workspace = **********
org.opendaylight.controller.build.timestamp = 1400686832112
org.opendaylight.controller.build.machine = **********

Still seeing:

https://gist.github.com/0030bb1c3f3231846f3e
which is tracked under
https://bugs.opendaylight.org/show_bug.cgi?id=1027

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