Bug 2383: Added RibSupport lookup using DOM Path Argument. 29/17429/5
authorTony Tkacik <ttkacik@cisco.com>
Tue, 31 Mar 2015 11:01:22 +0000 (13:01 +0200)
committerDana Kutenicsova <dkutenic@cisco.com>
Tue, 31 Mar 2015 15:30:37 +0000 (17:30 +0200)
Change-Id: I26915e9187c1aa0e1c69668f0fd2e9722fcc6eec
Signed-off-by: Tony Tkacik <ttkacik@cisco.com>
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/AdjRibInWriter.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/EffectiveRibInWriter.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/RIBSupportContextImpl.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/RIBSupportContextRegistryImpl.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/RIBSupportContextRegistry.java
bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/RIBExtensionConsumerContext.java
bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/RibSupportUtils.java [new file with mode: 0644]
bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/SimpleRIBExtensionProviderContext.java

index 75f8e1579a5cb2faa5f3eda1f430efac08993599..a5a7f99ccff965c7926396e1ed989b73a5b899a1 100644 (file)
@@ -22,6 +22,7 @@ import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
 import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContext;
 import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
+import org.opendaylight.protocol.bgp.rib.spi.RibSupportUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.PathAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpReachNlri;
@@ -33,7 +34,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Attributes;
-import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.InstanceIdentifierBuilder;
@@ -173,11 +173,9 @@ final class AdjRibInWriter {
                 // We will use table keys very often, make sure they are optimized
                 final InstanceIdentifierBuilder idb = YangInstanceIdentifier.builder(newTablesRoot);
 
-                // FIXME: use codec to translate the key
-                final Map<QName, Object> keyValues = ImmutableMap.<QName, Object>of(AFI_QNAME, BindingReflections.getQName(k.getAfi()), SAFI_QNAME, BindingReflections.getQName(k.getSafi()));
-                final NodeIdentifierWithPredicates key = new NodeIdentifierWithPredicates(Tables.QNAME, keyValues);
-                idb.nodeWithKey(key.getNodeType(), keyValues);
-
+                // TODO: Use returned value once Instance Identifier builder allows for it.
+                final NodeIdentifierWithPredicates key = RibSupportUtils.toYangTablesKey(k);
+                idb.nodeWithKey(key.getNodeType(), key.getKeyValues());
                 ctx = new TableContext(rs, idb.build());
                 ctx.clearTable(tx);
             } else {
index 8b25aea06f5f2f74407fa3be09e884a2295b2ff2..47fe64c2b11440d01fc3fb43698a3885390ae28a 100644 (file)
@@ -164,8 +164,7 @@ final class EffectiveRibInWriter implements AutoCloseable {
         }
 
         private RIBSupportContext getRibSupport(final NodeIdentifierWithPredicates tableKey) {
-            // FIXME: use codec to translate tableKey
-            return this.registry.getRIBSupportContext(null);
+            return this.registry.getRIBSupportContext(tableKey);
         }
 
         private YangInstanceIdentifier effectiveTablePath(final NodeIdentifierWithPredicates peerKey, final NodeIdentifierWithPredicates tableKey) {
index ccbc33eae9017776e4d47746d3b9e70a4d6d1268..767e300a6270a08281031db93f444391c50ccca7 100644 (file)
@@ -64,6 +64,7 @@ class RIBSupportContextImpl extends RIBSupportContext {
     private static final Logger LOG = LoggerFactory.getLogger(RIBSupportContextImpl.class);
     private static final ContainerNode EMPTY_TABLE_ATTRIBUTES = ImmutableNodes.containerNode(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Attributes.QNAME);
     private static final Set<Class<? extends DataObject>> ATTRIBUTE_CACHEABLES;
+
     private static final InstanceIdentifier<Tables> TABLE_BASE_II = InstanceIdentifier.builder(BgpRib.class)
             .child(Rib.class)
             .child(LocRib.class)
@@ -158,17 +159,15 @@ class RIBSupportContextImpl extends RIBSupportContext {
 
     @Override
     public void deleteRoutes(final DOMDataWriteTransaction tx, final YangInstanceIdentifier tableId, final MpUnreachNlri nlri) {
-
-
         this.tableSupport.deleteRoutes(tx, tableId, serialiazeUnreachNlri(nlri));
     }
 
-    private ContainerNode serialiazeUnreachNlri(MpUnreachNlri nlri) {
+    private ContainerNode serialiazeUnreachNlri(final MpUnreachNlri nlri) {
         Preconditions.checkState(unreachNlriCodec != null, "MpReachNlri codec not available");
         return (ContainerNode) unreachNlriCodec.serialize(nlri);
     }
 
-    private ContainerNode serialiazeReachNlri(MpReachNlri nlri) {
+    private ContainerNode serialiazeReachNlri(final MpReachNlri nlri) {
         Preconditions.checkState(reachNlriCodec != null, "MpReachNlri codec not available");
         return (ContainerNode) reachNlriCodec.serialize(nlri);
     }
index 340a1b21d6aed5aed042dc2068f9370d2ed71fef..69b1922ed905bc18efba07901872061ac27f54fc 100644 (file)
@@ -20,6 +20,7 @@ import org.opendaylight.yangtools.binding.data.codec.api.BindingCodecTree;
 import org.opendaylight.yangtools.binding.data.codec.api.BindingCodecTreeFactory;
 import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
 import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 class RIBSupportContextRegistryImpl implements RIBSupportContextRegistry {
@@ -28,7 +29,7 @@ class RIBSupportContextRegistryImpl implements RIBSupportContextRegistry {
             .build(new CacheLoader<RIBSupport, RIBSupportContextImpl>(){
 
                 @Override
-                public RIBSupportContextImpl load(RIBSupport key) {
+                public RIBSupportContextImpl load(final RIBSupport key) {
                     return createContext(key);
                 };
             });
@@ -38,39 +39,50 @@ class RIBSupportContextRegistryImpl implements RIBSupportContextRegistry {
     private final GeneratedClassLoadingStrategy classContext;
     private volatile BindingCodecTree latestCodecTree;
 
-    private RIBSupportContextRegistryImpl(RIBExtensionConsumerContext extensions, BindingCodecTreeFactory codecFactory,
-            GeneratedClassLoadingStrategy strategy) {
+    private RIBSupportContextRegistryImpl(final RIBExtensionConsumerContext extensions, final BindingCodecTreeFactory codecFactory,
+            final GeneratedClassLoadingStrategy strategy) {
         this.extensionContext = Preconditions.checkNotNull(extensions);
         this.codecFactory = Preconditions.checkNotNull(codecFactory);
         this.classContext = Preconditions.checkNotNull(strategy);
     }
 
-    static RIBSupportContextRegistryImpl create(RIBExtensionConsumerContext extensions,
-            BindingCodecTreeFactory codecFactory, GeneratedClassLoadingStrategy classStrategy) {
+    static RIBSupportContextRegistryImpl create(final RIBExtensionConsumerContext extensions,
+            final BindingCodecTreeFactory codecFactory, final GeneratedClassLoadingStrategy classStrategy) {
         return new RIBSupportContextRegistryImpl(extensions, codecFactory, classStrategy);
     }
 
     @Override
-    public RIBSupportContext getRIBSupportContext(TablesKey key) {
-        RIBSupport ribSupport = extensionContext.getRIBSupport(key);
+    public RIBSupportContext getRIBSupportContext(final TablesKey key) {
+        final RIBSupport ribSupport = extensionContext.getRIBSupport(key);
         if(ribSupport != null) {
             return contexts.getUnchecked(ribSupport);
         }
         return null;
     }
 
-    private RIBSupportContextImpl createContext(RIBSupport ribSupport) {
-        RIBSupportContextImpl ribContext = new RIBSupportContextImpl(ribSupport);
+    @Override
+    public RIBSupportContext getRIBSupportContext(final NodeIdentifierWithPredicates key) {
+        final RIBSupport ribSupport = extensionContext.getRIBSupport(key);
+        if(ribSupport != null) {
+            return contexts.getUnchecked(ribSupport);
+        }
+        return null;
+    }
+
+    private RIBSupportContextImpl createContext(final RIBSupport ribSupport) {
+        final RIBSupportContextImpl ribContext = new RIBSupportContextImpl(ribSupport);
         if(latestCodecTree != null) {
+            // FIXME: Do we need to recalculate latestCodecTree? E.g. new rib support was added
+            // after bgp was started.
             ribContext.onCodecTreeUpdated(latestCodecTree);
         }
         return ribContext;
     }
 
-    void onSchemaContextUpdated(SchemaContext context) {
-        BindingRuntimeContext runtimeContext = BindingRuntimeContext.create(classContext, context);
+    void onSchemaContextUpdated(final SchemaContext context) {
+        final BindingRuntimeContext runtimeContext = BindingRuntimeContext.create(classContext, context);
         latestCodecTree  = codecFactory.create(runtimeContext);
-        for(RIBSupportContextImpl rib : contexts.asMap().values()) {
+        for(final RIBSupportContextImpl rib : contexts.asMap().values()) {
             rib.onCodecTreeUpdated(latestCodecTree);
         }
     }
index b79017bd13ea30baf8880e448df9452f797e43e7..31c2107c8534a23f15fd10d5d28d6c77cc30ab0d 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.protocol.bgp.rib.impl.spi;
 
 import javax.annotation.Nullable;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 
 public interface RIBSupportContextRegistry {
 
@@ -20,4 +21,12 @@ public interface RIBSupportContextRegistry {
     */
     public abstract @Nullable RIBSupportContext getRIBSupportContext(TablesKey key);
 
+    /**
+     * Acquire a RIB Support Context for a AFI/SAFI combination.
+     * @param key Tables key with AFI/SAFI key
+     * @return RIBSupport instance, or null if the AFI/SAFI is
+     *         not implemented.
+    */
+    public abstract @Nullable RIBSupportContext getRIBSupportContext(NodeIdentifierWithPredicates key);
+
 }
index f7292b0be73a3d3bcf6fc22f43112c612b0e4ead..41ff5fac740d1b3da49ebb7f0f9dd1d3ac97dfc3 100644 (file)
@@ -13,6 +13,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.SubsequentAddressFamily;
 import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 
 /**
  * Interface for acquiring AdjRIBsIn factories. In order for a model-driven RIB implementation to work correctly, it
@@ -46,6 +47,15 @@ public interface RIBExtensionConsumerContext {
      */
     @Nullable RIBSupport getRIBSupport(@Nonnull Class<? extends AddressFamily> afi, @Nonnull Class<? extends SubsequentAddressFamily> safi);
 
+    /**
+     * Acquire a RIB implementation factory for a AFI/SAFI combination.
+     * @param key Tables key with AFI/SAFI
+     * @return RIBSupport instance, or null if the AFI/SAFI is
+     *         not implemented.
+     */
+    @Nullable RIBSupport getRIBSupport(YangInstanceIdentifier.NodeIdentifierWithPredicates key);
+
+
     /**
      * Returns class loading strategy for loading YANG modeled classes
      * associated with registered RIB supports.
diff --git a/bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/RibSupportUtils.java b/bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/RibSupportUtils.java
new file mode 100644 (file)
index 0000000..303111d
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.bgp.rib.spi;
+
+import com.google.common.collect.ImmutableMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.SubsequentAddressFamily;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+
+public class RibSupportUtils {
+
+    private static final QName AFI_QNAME = QName.cachedReference(QName.create(Tables.QNAME, "afi"));
+    private static final QName SAFI_QNAME = QName.cachedReference(QName.create(Tables.QNAME, "safi"));
+
+    private RibSupportUtils() {
+        throw new UnsupportedOperationException("Utility class");
+    }
+
+    /**
+     * Creates Yang Instance Identifier path argument from supplied AFI and SAFI
+     *
+     * @param afi Class representing AFI
+     * @param safi Class representing SAFI
+     * @return NodeIdentifierWithPredicates of {@link Tables} for specified AFI, SAFI combination.
+     */
+    public static NodeIdentifierWithPredicates toYangTablesKey(final Class<? extends AddressFamily> afi,
+            final Class<? extends SubsequentAddressFamily> safi) {
+        final ImmutableMap<QName, Object> keyValues = ImmutableMap.<QName, Object>of(
+                        AFI_QNAME, BindingReflections.findQName(afi),
+                        SAFI_QNAME, BindingReflections.findQName(safi));
+        return new NodeIdentifierWithPredicates(Tables.QNAME, keyValues);
+    }
+
+    /**
+     * Creates Yang Instance Identifier path argument from supplied {@link TablesKey}
+     *
+     * @param k Tables key representing table.
+     * @return NodeIdentifierWithPredicates of {@link Tables} for specified AFI, SAFI combination.
+     */
+    public static NodeIdentifierWithPredicates toYangTablesKey(final TablesKey k) {
+        return toYangTablesKey(k.getAfi(), k.getSafi());
+    }
+}
index babf4f4389f435361428de5cc944bd9bf0e63337..82f2c9b1d220f854457eeceedb8cd324937e9ce3 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.protocol.bgp.rib.spi;
 
+
 import com.google.common.base.Preconditions;
 import java.util.HashSet;
 import java.util.Set;
@@ -20,6 +21,7 @@ import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadi
 import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -29,8 +31,11 @@ public class SimpleRIBExtensionProviderContext implements RIBExtensionProviderCo
 
     private final ConcurrentMap<TablesKey, AdjRIBsFactory> factories = new ConcurrentHashMap<>();
     private final ConcurrentMap<TablesKey, RIBSupport> supports = new ConcurrentHashMap<>();
+    private final ConcurrentMap<NodeIdentifierWithPredicates, RIBSupport> domSupports = new ConcurrentHashMap<>();
+
     private final ModuleInfoBackedContext classLoadingStrategy = ModuleInfoBackedContext.create();
 
+
     @Override
     public final synchronized AbstractRegistration registerAdjRIBsInFactory(final Class<? extends AddressFamily> afi,
             final Class<? extends SubsequentAddressFamily> safi, final AdjRIBsFactory factory) {
@@ -63,9 +68,9 @@ public class SimpleRIBExtensionProviderContext implements RIBExtensionProviderCo
             final Class<? extends SubsequentAddressFamily> safi, final T support) {
         final TablesKey key = new TablesKey(afi, safi);
         final RIBSupport prev = this.supports.putIfAbsent(key, support);
-        addClassLoadingSupport(afi, safi, support);
         Preconditions.checkArgument(prev == null, "AFI %s SAFI %s is already registered with %s", afi, safi, prev);
-
+        this.domSupports.put(RibSupportUtils.toYangTablesKey(afi,safi), support);
+        addClassLoadingSupport(afi, safi, support);
         return new AbstractRIBSupportRegistration<T>(support) {
             @Override
             protected void removeRegistration() {
@@ -74,7 +79,7 @@ public class SimpleRIBExtensionProviderContext implements RIBExtensionProviderCo
         };
     }
 
-    private void addClassLoadingSupport(Class<?> afi, Class<?> safi, RIBSupport s) {
+    private void addClassLoadingSupport(final Class<?> afi, final Class<?> safi, final RIBSupport s) {
         final Set<YangModuleInfo> moduleInfos =
                 getModuleInfos(afi, safi, s.routesListClass(), s.routesContainerClass(), s.routesCaseClass());
         if(!moduleInfos.isEmpty()) {
@@ -82,12 +87,12 @@ public class SimpleRIBExtensionProviderContext implements RIBExtensionProviderCo
         }
     }
 
-    private static Set<YangModuleInfo> getModuleInfos(Class<?>... clazzes) {
+    private static Set<YangModuleInfo> getModuleInfos(final Class<?>... clazzes) {
         final Set<YangModuleInfo> moduleInfos = new HashSet<>();
-        for(Class<?> clz : clazzes) {
+        for(final Class<?> clz : clazzes) {
             try {
                 moduleInfos.add(BindingReflections.getModuleInfo(clz));
-            } catch (Exception e) {
+            } catch (final Exception e) {
                 LOG.debug("Could not find module info for class {}", clz, e);
             }
         }
@@ -108,4 +113,9 @@ public class SimpleRIBExtensionProviderContext implements RIBExtensionProviderCo
     public GeneratedClassLoadingStrategy getClassLoadingStrategy() {
         return classLoadingStrategy;
     }
+
+    @Override
+    public RIBSupport getRIBSupport(final NodeIdentifierWithPredicates key) {
+        return domSupports.get(key);
+    }
 }