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

Clean up InstanceIdentifier semantics

    XMLWordPrintable

Details

    • Improvement
    • Status: Resolved
    • Highest
    • Resolution: Done
    • None
    • 9.0.0
    • Binding runtime
    • None

    Description

      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.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

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

            Dates

              Created:
              Updated:
              Resolved: