Details
-
Bug
-
Status: Resolved
-
Resolution: Done
-
None
-
None
-
None
-
None
-
Operating System: Mac OS
Platform: Macintosh
-
2689
-
Normal
Description
We get the following stack trace:
2015-02-06 15:20:10,954 | INFO | DOM-OPER-DCL-1 | SwitchManager | 178 - org.opendaylight.groupbasedpolicy - 0.2.0.SNAPSHOT | New switch Uri [_value=openflow:2] connected
java.lang.ClassCastException: Cannot cast org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId to org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress
at sun.invoke.util.ValueConversions.newClassCastException(ValueConversions.java:461)
at sun.invoke.util.ValueConversions.castReference(ValueConversions.java:456)
at org.opendaylight.yangtools.binding.data.codec.impl.IdentifiableItemCodec.deserialize(IdentifiableItemCodec.java:71)
at org.opendaylight.yangtools.binding.data.codec.impl.IdentifiableItemCodec.deserialize(IdentifiableItemCodec.java:28)
at org.opendaylight.yangtools.binding.data.codec.impl.KeyedListNodeCodecContext.getBindingChildValue(KeyedListNodeCodecContext.java:62)
at org.opendaylight.yangtools.binding.data.codec.impl.LazyDataObject.getBindingData(LazyDataObject.java:117)
at org.opendaylight.yangtools.binding.data.codec.impl.LazyDataObject.invoke(LazyDataObject.java:64)
at com.sun.proxy.$Proxy100.getKey(Unknown Source)
at org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address$StreamWriter.serialize(DataObjectSerializerPrototype.java)
at org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint$StreamWriter.serialize(DataObjectSerializerPrototype.java)
at org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry$DataObjectSerializerProxy.serialize(BindingNormalizedNodeCodecRegistry.java:273)
at org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry.toNormalizedNode(BindingNormalizedNodeCodecRegistry.java:99)
at org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec.toNormalizedNode(BindingToNormalizedNodeCodec.java:56)
at org.opendaylight.controller.md.sal.binding.impl.AbstractWriteTransaction.put(AbstractWriteTransaction.java:42)
at org.opendaylight.controller.md.sal.binding.impl.BindingDataWriteTransactionImpl.put(BindingDataWriteTransactionImpl.java:40)
at org.opendaylight.groupbasedpolicy.renderer.ofoverlay.EndpointManager$UpdateEndpoint.run(EndpointManager.java:375)
This happens when we try to update an Endpoint we've read back from the data store with an augmentation, using the builder:
EndpointBuilder epBuilder = new EndpointBuilder(ep);
... (update EP with augmentation)
The exception happens when we put this into the write transaction (i.e. before submit):
tx.put(LogicalDatastoreType.OPERATIONAL, iidEp, epBuilder.build());
We noticed that the Endpoint that we read from the data store (i.e. to do the update) has an empty augmentation in the L3Address:
Endpoint{getCondition=[], getEndpointGroup=Uuid [_value=1eaf9a67-a171-42a8-9282-71cf702f61dd], getL2Context=Uuid [_value=7b796915-adf4-4356-b5ca-de005ac410c1], getL3Address=[L3Address{getIpAddress=IpAddress [_ipv4Address=Ipv4Address [_value=10.0.35.2], _value=[1, 0, ., 0, ., 3, 5, ., 2]], getL3Context=Uuid [_value=cbe0cc07-b8ff-451d-8171-9eef002a8e80], augmentations={}}], getMacAddress=MacAddress [_value=00:00:00:00:35:02], getPortName=Name [_value=vethl26839], getTenant=Uuid [_value=f5c7d344-d1c7-4208-8531-2c2693657e12], getTimestamp=1423266774630, augmentations={interface org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext=OfOverlayContext{}}}
Here is the definition of the L3Address in the yang model:
list l3-address
{ description "All the layer 3 addresses associated with this endpoint"; key "l3-context ip-address"; uses l3-key; }where:
grouping l3-key {
description
"The fields that identify an endpoint by a layer 3 address";
leaf l3-context
leaf ip-address
{ type inet:ip-address; mandatory true; description "The actual IP address for the endpoint"; }}
(fwiw, the l3-context-id is just a UUID)
The resulting interface for the corresponding Java class (L3Address) has this:
public interface L3Address
extends
ChildOf<EndpointFields>,
Augmentable<org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address>,
L3Key,
Identifiable<L3AddressKey>
{ ... }We are able to work around this for now by manually (re-)constructing the L3Address:
List<L3Address> l3Addresses= new ArrayList<>();
for(L3Address l3Address: ep.getL3Address()) {
L3AddressBuilder l3AB = new L3AddressBuilder();
l3AB.setIpAddress(l3Address.getIpAddress())
.setL3Context(l3Address.getL3Context());
l3Addresses.add(l3AB.build());
}
epBuilder.setL3Address(l3Addresses);
However, it doesn't seem like we should have to do this.