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;
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;
// 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 {
}
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) {
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)
@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);
}
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 {
.build(new CacheLoader<RIBSupport, RIBSupportContextImpl>(){
@Override
- public RIBSupportContextImpl load(RIBSupport key) {
+ public RIBSupportContextImpl load(final RIBSupport key) {
return createContext(key);
};
});
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);
}
}
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 {
*/
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);
+
}
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
*/
@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.
--- /dev/null
+/*
+ * 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());
+ }
+}
*/
package org.opendaylight.protocol.bgp.rib.spi;
+
import com.google.common.base.Preconditions;
import java.util.HashSet;
import java.util.Set;
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;
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) {
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() {
};
}
- 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()) {
}
}
- 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);
}
}
public GeneratedClassLoadingStrategy getClassLoadingStrategy() {
return classLoadingStrategy;
}
+
+ @Override
+ public RIBSupport getRIBSupport(final NodeIdentifierWithPredicates key) {
+ return domSupports.get(key);
+ }
}