Uploaded image for project: 'mdsal'
  1. mdsal
  2. MDSAL-730

Clean up InstanceIdentifier semantics

XMLWordPrintable

    • Icon: Improvement Improvement
    • Resolution: Done
    • Icon: Highest Highest
    • 9.0.0
    • None
    • Binding runtime
    • None

      With MDSAL-696, BGPCEP is not quite happy and reports this:

      org.opendaylight.mdsal.binding.dom.codec.api.IncorrectNestingException: interface org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.Update is not a valid data tree child of SchemaRootCodecContext [interface org.opendaylight.yangtools.yang.binding.DataRoot]
              at org.opendaylight.mdsal.binding.dom.codec.api.IncorrectNestingException.create(IncorrectNestingException.java:26)
              at org.opendaylight.mdsal.binding.dom.codec.impl.SchemaRootCodecContext.createDataTreeChildContext(SchemaRootCodecContext.java:280)
              at org.opendaylight.mdsal.binding.dom.codec.impl.SchemaRootCodecContext$1.load(SchemaRootCodecContext.java:70)
              at org.opendaylight.mdsal.binding.dom.codec.impl.SchemaRootCodecContext$1.load(SchemaRootCodecContext.java:67)
              at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3533)
              at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2282)
              at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2159)
              at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2049)
              at com.google.common.cache.LocalCache.get(LocalCache.java:3966)
              at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3989)
              at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4950)
              at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:4956)
              at org.opendaylight.mdsal.binding.dom.codec.impl.SchemaRootCodecContext.getOrRethrow(SchemaRootCodecContext.java:394)
              at org.opendaylight.mdsal.binding.dom.codec.impl.SchemaRootCodecContext.streamChild(SchemaRootCodecContext.java:231)
              at org.opendaylight.mdsal.binding.dom.codec.impl.DataContainerCodecContext.bindingPathArgumentChild(DataContainerCodecContext.java:113)
              at org.opendaylight.mdsal.binding.dom.codec.impl.SchemaRootCodecContext.bindingPathArgumentChild(SchemaRootCodecContext.java:376)
              at org.opendaylight.mdsal.binding.dom.codec.impl.BindingCodecContext.getCodecContextNode(BindingCodecContext.java:241)
              at org.opendaylight.mdsal.binding.dom.codec.impl.BindingCodecContext.newWriterAndIdentifier(BindingCodecContext.java:203)
              at org.opendaylight.mdsal.binding.dom.codec.impl.BindingCodecContext.toNormalizedNode(BindingCodecContext.java:522)
              at org.opendaylight.mdsal.binding.dom.codec.spi.ForwardingBindingDOMCodecServices.toNormalizedNode(ForwardingBindingDOMCodecServices.java:66)
              at org.opendaylight.protocol.bgp.rib.spi.AbstractRIBSupportTest.createNlriWithDrawnRoute(AbstractRIBSupportTest.java:125)
              at org.opendaylight.protocol.bgp.inet.IPv4RIBSupportTest.testDeleteRoutes(IPv4RIBSupportTest.java:85)
      
      

      As the error indicates, for some reason we are attempting to access a Notification as a data context – which is definitely not right. We are most likely missing a recognition that we need to access a class through Notification code path.

      The core problem is that InstanceIdentifier harks back to initial design where a DataObject was enough to identify an item. This capability was then relaxed to allow reuse of InstanceIdentifier to identify even RpcInput/RpcOutput/Notification and Groupings in the context of mdsal-binding-dom-codec. This is obviously wrong, as noted in MDSAL-724.

      Tie up the loose ends in InstanceIdentifier definition to require properly-rooted hierarchy, thus rejecting attempts to address invalid items.

      There are two different solutions. For simple cases, like

      module foo {
        namespace foo;
        prefix foo;
      
        container foo;
      }
      

      the following continues to work

      InstanceIdentifier<Foo> id = InstanceIdentifier.create(Foo.class);
      

      For more complex cases involving grouping and choices, such as:

      module foo {
        namespace foo;
        prefix foo;
      
        choice foo {
          container bar;
        }
      
        grouping grp {
          container baz;
        }
      
        uses grp;
      }

      The solution is to go through a specifically-crafted InstanceIdentifierBuilder. The choice/case interface is already covered with pre-existing methods, but for the case of used groupings, the root needs to be specified like this:

      InstanceIdentifier<Bar> id = InstanceIdentifier.builderOfInherited(FooData.class, Bar.class).build();
      

      Here FooData identifies the module in which the grouping is instantiated and Bar identifies the container as it would normally do.

            rovarga Robert Varga
            rovarga Robert Varga
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: