import static org.junit.Assert.assertNull;
import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import java.util.Collection;
import java.util.Collections;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidates;
@Test
public void testExtractPathId() {
- final NormalizedNode<?, ?> route = Iterables.getOnlyElement(createRoutes(ROUTES));
- // assertEquals(PATH_ID.getValue(), RIB_SUPPORT.extractPathId(route));
+ assertEquals(PATH_ID.getValue().longValue(), RIB_SUPPORT.extractPathId(ROUTES.getIpv4Route().get(0)));
}
@Test
@Test
public void testExtractPathId() {
- /* final NormalizedNode<?, ?> route = Iterables.getOnlyElement(createRoutes(ROUTES));
- assertEquals(PATH_ID.getValue(), RIB_SUPPORT.extractPathId(route));*/
+ assertEquals(PATH_ID.getValue().longValue(), RIB_SUPPORT.extractPathId(ROUTES.getIpv6Route().get(0)));
}
@Test
/**
* Extract PathId from route change received
*
- * @param data Data containing the path Id
+ * @param data Data containing the path Id
* @param pathNii Path Id NodeIdentifier specific per each Rib support
* @return The path identifier from data change
*/
return (Long) NormalizedNodes.findNode(data, pathNii).map(NormalizedNode::getValue).orElse(null);
}
- /**
- * Create a Add Path PathArgument Key(prefix+pathId).
- *
- * @param pathId Path Id value
- * @param routeId Route Id value
- * @param routeQname route QName provided per each RibSupport
- * @param pathidQname Path Id QName provided per each RibSupport
- * @param routeKeyQname Prefix QName provided per each RibSupport
- * @return Route Key Nid
- */
- public static NodeIdentifierWithPredicates createNidKey(final long pathId, final PathArgument routeId,
- final QName routeQname,
- final QName pathidQname, final QName routeKeyQname) {
- return createNodeIdentifierWithPredicates(routeQname, pathidQname, pathId, routeKeyQname,
- getObjectKey(routeId, routeKeyQname));
- }
-
/**
* Get route key object ( prefgit stat ix / key-value/ .. ).
*
- * @param routeId PathArgument containing the key
+ * @param routeId PathArgument containing the key
* @param routeKeyQname routeKey Qname
* @return key
*/
return ((NodeIdentifierWithPredicates) routeId).getKeyValues().get(routeKeyQname);
}
- public static NodeIdentifierWithPredicates createNodeIdentifierWithPredicates(final QName routeQname, final QName pathidQname, final Object pathId,
- final QName routeKeyQname, final Object keyObject) {
+ public static NodeIdentifierWithPredicates createNodeIdentifierWithPredicates(final QName routeQname,
+ final QName pathidQname, final Object pathId,
+ final QName routeKeyQname, final Object keyObject) {
final ImmutableMap<QName, Object> keyValues = ImmutableMap.of(pathidQname, pathId, routeKeyQname, keyObject);
return new NodeIdentifierWithPredicates(routeQname, keyValues);
}
* Build Path Id.
*
* @param routesCont route container
- * @param pathIdNii path Id node Identifier
+ * @param pathIdNii path Id node Identifier
* @return PathId or null in case is not the container
*/
public static PathId buildPathId(final DataContainerNode<? extends PathArgument> routesCont,
* Build Route Key for supporting mp.
* Key is composed by 2 elements (route-key + path Id).
*
- * @param routeQname route Qname
- * @param routeKeyQname route key Qname
- * @param pathIdQname path Id Qname
- * @param routeKeyValue route key value
+ * @param routeQname route Qname
+ * @param routeKeyQname route key Qname
+ * @param pathIdQname path Id Qname
+ * @param routeKeyValue route key value
* @param maybePathIdLeaf path id container, it might me supported or not, in that case default 0 value will
- * be
+ * be
* assigned
* @return Route Key Nid
*/
<artifactId>bgp-inet</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>mdsal-binding-dom-adapter</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-broker-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-broker-impl</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
package org.opendaylight.protocol.bgp.mode;
import java.util.List;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.attributes.as.path.Segments;
public final class BesthPathStateUtil {
throw new UnsupportedOperationException();
}
- public static AsNumber getPeerAs(final List<Segments> segments) {
- if (segments.isEmpty()) {
- return new AsNumber(0L);
- }
+ public static long getPeerAs(final List<Segments> segments) {
for (final Segments seg : segments) {
if (seg.getAsSequence() != null && !seg.getAsSequence().isEmpty()) {
- return segments.get(0).getAsSequence().get(0);
+ return segments.get(0).getAsSequence().get(0).getValue();
}
}
- return new AsNumber(0L);
+ return 0;
}
}
package org.opendaylight.protocol.bgp.mode.api;
import com.google.common.primitives.UnsignedInteger;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.Attributes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerId;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
public interface BestPath {
*
* @return the routerId (UnsignedInteger) converted to a PeerId
*/
+ @Nonnull
PeerId getPeerId();
/**
*
* @return the path attributes
*/
- ContainerNode getAttributes();
+ @Nonnull
+ Attributes getAttributes();
/**
* PathId.
package org.opendaylight.protocol.bgp.mode.api;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.Attributes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpOrigin;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
public interface BestPathState {
+ @Nullable
Long getLocalPref();
+ @Nullable
Long getMultiExitDisc();
+ @Nullable
BgpOrigin getOrigin();
- Long getPeerAs();
+ long getPeerAs();
int getAsPathLength();
- ContainerNode getAttributes();
+ @Nonnull
+ Attributes getAttributes();
}
\ No newline at end of file
import com.google.common.primitives.UnsignedInteger;
import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.protocol.bgp.rib.spi.PeerExportGroup;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.protocol.bgp.rib.spi.entry.RouteEntryDependenciesContainer;
import org.opendaylight.protocol.bgp.rib.spi.entry.RouteEntryInfo;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.Route;
+import org.opendaylight.yangtools.yang.binding.Identifier;
/**
* A single route entry inside a route table. Maintains the attributes of
* @param remotePathId remote path Id received
* @return return true if it was the last route on entry
*/
- boolean removeRoute(UnsignedInteger routerId, Long remotePathId);
+ boolean removeRoute(@Nonnull UnsignedInteger routerId, long remotePathId);
/**
* Indicates whether best has changed.
*
* @param routerId router ID in unsigned integer format from an Ipv4Address
* @param remotePathId remote path Id received
- * @param attrII route Attributes Identifier
- * @param data route Data change
+ * @param route route Data change
* @return returns the offset
*/
- int addRoute(UnsignedInteger routerId, Long remotePathId, NodeIdentifier attrII, NormalizedNode<?, ?> data);
+ int addRoute(@Nonnull UnsignedInteger routerId, long remotePathId, @Nonnull Route route);
/**
* Update LocRibOut and AdjRibsOut by removing stale best path and writing new best.
*
* @param entryDependencies entry Dependencies container
- * @param routeIdPA router ID pathArgument
+ * @param routeKey route key
* @param tx DOM transaction
*/
void updateBestPaths(
@Nonnull RouteEntryDependenciesContainer entryDependencies,
- @Nonnull NodeIdentifierWithPredicates routeIdPA,
- @Nonnull DOMDataWriteTransaction tx);
+ @Nonnull Identifier routeKey,
+ @Nonnull WriteTransaction tx);
/**
* Initialize LocRibOut and AdjRibsOut for new peers with already present best paths.
void initializeBestPaths(
@Nonnull RouteEntryDependenciesContainer entryDependencies,
@Nonnull RouteEntryInfo entryInfo,
- @Nullable PeerExportGroup peerGroup,
- @Nonnull DOMDataWriteTransaction tx);
+ @Nonnull WriteTransaction tx);
}
\ No newline at end of file
import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.collect.ImmutableList;
-import java.util.ArrayList;
-import java.util.Collection;
import java.util.List;
-import java.util.Optional;
-import java.util.concurrent.ExecutionException;
-import javax.annotation.concurrent.NotThreadSafe;
import org.opendaylight.protocol.bgp.mode.BesthPathStateUtil;
import org.opendaylight.protocol.bgp.mode.api.BestPathState;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.attributes.AsPath;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.attributes.LocalPref;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.attributes.MultiExitDisc;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.attributes.Origin;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.Attributes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.attributes.as.path.Segments;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.attributes.as.path.SegmentsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpOrigin;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.QNameModule;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-@NotThreadSafe
public final class BestPathStateImpl implements BestPathState {
- private static final class NamespaceSpecificIds {
- private final Collection<PathArgument> asPath;
- private final Collection<PathArgument> locPref;
- private final Collection<PathArgument> med;
- private final Collection<PathArgument> orig;
- private final NodeIdentifier asSetNid;
- private final NodeIdentifier asSeqNid;
-
- NamespaceSpecificIds(final QName namespace) {
- NodeIdentifier container = new NodeIdentifier(QName.create(namespace,
- AsPath.QNAME.getLocalName().intern()));
- NodeIdentifier leaf = new NodeIdentifier(QName.create(namespace, "segments").intern());
- this.asPath = ImmutableList.of(container, leaf);
-
- container = new NodeIdentifier(QName.create(namespace, LocalPref.QNAME.getLocalName()).intern());
- leaf = new NodeIdentifier(QName.create(namespace, "pref").intern());
- this.locPref = ImmutableList.of(container, leaf);
-
- container = new NodeIdentifier(QName.create(namespace, MultiExitDisc.QNAME.getLocalName()).intern());
- leaf = new NodeIdentifier(QName.create(namespace, "med").intern());
- this.med = ImmutableList.of(container, leaf);
-
- container = new NodeIdentifier(QName.create(namespace, Origin.QNAME.getLocalName()).intern());
- leaf = new NodeIdentifier(QName.create(namespace, "value").intern());
- this.orig = ImmutableList.of(container, leaf);
-
- this.asSetNid = new NodeIdentifier(QName.create(namespace, "as-set").intern());
- this.asSeqNid = new NodeIdentifier(QName.create(namespace, "as-sequence").intern());
- }
-
- Collection<PathArgument> getAsPath() {
- return this.asPath;
- }
-
- Collection<PathArgument> getLocPref() {
- return this.locPref;
- }
-
- Collection<PathArgument> getMed() {
- return this.med;
- }
-
- Collection<PathArgument> getOrig() {
- return this.orig;
- }
-
- NodeIdentifier getAsSet() {
- return this.asSetNid;
- }
-
- NodeIdentifier getAsSeq() {
- return this.asSeqNid;
- }
- }
-
- private static final Logger LOG = LoggerFactory.getLogger(BestPathStateImpl.class);
- private static final Cache<QNameModule, NamespaceSpecificIds> PATH_CACHE = CacheBuilder.newBuilder()
- .weakKeys().weakValues().build();
-
+ private final Attributes attributes;
private long peerAs = 0L;
private int asPathLength = 0;
-
- private final ContainerNode attributes;
- private final NamespaceSpecificIds ids;
private Long localPref;
private Long multiExitDisc;
private BgpOrigin origin;
private boolean resolved;
- public BestPathStateImpl(final ContainerNode attributes) {
- final NamespaceSpecificIds col;
- try {
- col = PATH_CACHE.get(attributes.getNodeType().getModule(),
- () -> new NamespaceSpecificIds(attributes.getNodeType()));
- } catch (final ExecutionException e) {
- LOG.error("Error creating namespace-specific attributes collection.", e);
- throw new IllegalStateException("Error creating namespace-specific attributes collection.", e);
- }
-
+ public BestPathStateImpl(final Attributes attributes) {
this.attributes = requireNonNull(attributes);
- this.ids = col;
resolveValues();
}
- private static BgpOrigin fromString(final String originStr) {
- switch (originStr) {
- case "igp":
- return BgpOrigin.Igp;
- case "egp":
- return BgpOrigin.Egp;
- case "incomplete":
- return BgpOrigin.Incomplete;
- default:
- throw new IllegalArgumentException("Unhandled origin value " + originStr);
+ private static int countAsPath(final List<Segments> segments) {
+ // an AS_SET counts as 1, no matter how many ASs are in the set.
+ int count = 0;
+ boolean setPresent = false;
+ for (final Segments s : segments) {
+ if (s.getAsSet() != null && !setPresent) {
+ setPresent = true;
+ count++;
+ } else if (s.getAsSequence() != null) {
+ count += s.getAsSequence().size();
+ }
}
+ return count;
}
private void resolveValues() {
return;
}
- final Optional<NormalizedNode<?, ?>> maybeLocalPref
- = NormalizedNodes.findNode(this.attributes, this.ids.getLocPref());
- if (maybeLocalPref.isPresent()) {
- this.localPref = (Long) maybeLocalPref.get().getValue();
+ if (this.attributes.getLocalPref() != null) {
+ this.localPref = this.attributes.getLocalPref().getPref();
} else {
this.localPref = null;
}
- final Optional<NormalizedNode<?, ?>> maybeMultiExitDisc
- = NormalizedNodes.findNode(this.attributes, this.ids.getMed());
- if (maybeMultiExitDisc.isPresent()) {
- this.multiExitDisc = (Long) maybeMultiExitDisc.get().getValue();
+ if (this.attributes.getMultiExitDisc() != null) {
+ this.multiExitDisc = this.attributes.getMultiExitDisc().getMed();
} else {
this.multiExitDisc = null;
}
- final Optional<NormalizedNode<?, ?>> maybeOrigin
- = NormalizedNodes.findNode(this.attributes, this.ids.getOrig());
- if (maybeOrigin.isPresent()) {
- this.origin = fromString((String) maybeOrigin.get().getValue());
+ if (this.attributes.getOrigin() != null) {
+ this.origin = this.attributes.getOrigin().getValue();
} else {
this.origin = null;
}
-
- final Optional<NormalizedNode<?, ?>> maybeSegments
- = NormalizedNodes.findNode(this.attributes, this.ids.getAsPath());
- if (maybeSegments.isPresent()) {
- final UnkeyedListNode segments = (UnkeyedListNode) maybeSegments.get();
- final List<Segments> segs = extractSegments(segments);
+ if (this.attributes.getAsPath() != null) {
+ final List<Segments> segs = this.attributes.getAsPath().getSegments();
if (!segs.isEmpty()) {
- this.peerAs = BesthPathStateUtil.getPeerAs(segs).getValue();
+ this.peerAs = BesthPathStateUtil.getPeerAs(segs);
this.asPathLength = countAsPath(segs);
}
}
}
@Override
- public Long getPeerAs() {
+ public long getPeerAs() {
resolveValues();
return this.peerAs;
}
return this.asPathLength;
}
- private static int countAsPath(final List<Segments> segments) {
- // an AS_SET counts as 1, no matter how many ASs are in the set.
- int count = 0;
- boolean setPresent = false;
- for (final Segments s : segments) {
- if (s.getAsSet() != null && !setPresent) {
- setPresent = true;
- count++;
- } else if (s.getAsSequence() != null) {
- count += s.getAsSequence().size();
- }
- }
- return count;
- }
-
-
-
- public List<Segments> extractSegments(final UnkeyedListNode segments) {
- // list segments
- final List<Segments> extracted = new ArrayList<>();
- for (final UnkeyedListEntryNode segment : segments.getValue()) {
- final SegmentsBuilder sb = new SegmentsBuilder();
- // We are expecting that segment contains either as-sequence or as-set,
- // so just one of them will be set, other would be null
- sb.setAsSequence(extractAsList(segment, this.ids.getAsSeq()))
- .setAsSet(extractAsList(segment, this.ids.getAsSet()));
- extracted.add(sb.build());
- }
- return extracted;
- }
-
- private static List<AsNumber> extractAsList(final UnkeyedListEntryNode segment, final NodeIdentifier nid) {
- final List<AsNumber> ases = new ArrayList<>();
- final Optional<NormalizedNode<?, ?>> maybeAsList = NormalizedNodes.findNode(segment, nid);
- if (maybeAsList.isPresent()) {
- final LeafSetNode<?> list = (LeafSetNode<?>)maybeAsList.get();
- for (final LeafSetEntryNode<?> as : list.getValue()) {
- ases.add(new AsNumber((Long)as.getValue()));
- }
- return ases;
- }
- return null;
- }
-
@Override
- public ContainerNode getAttributes() {
+ public Attributes getAttributes() {
return this.attributes;
}
import java.util.List;
import java.util.Optional;
import javax.annotation.concurrent.NotThreadSafe;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.protocol.bgp.mode.impl.BGPRouteEntryExportParametersImpl;
import org.opendaylight.protocol.bgp.mode.spi.AbstractRouteEntry;
import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
-import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.Peer;
-import org.opendaylight.protocol.bgp.rib.spi.PeerExportGroup;
import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
import org.opendaylight.protocol.bgp.rib.spi.RouterIds;
import org.opendaylight.protocol.bgp.rib.spi.entry.RouteEntryDependenciesContainer;
import org.opendaylight.protocol.bgp.rib.spi.entry.RouteEntryInfo;
+import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRouteEntryExportParameters;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.Attributes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerRole;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.Route;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.Tables;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.TablesKey;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
+import org.opendaylight.yangtools.yang.binding.Identifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private List<AddPathBestPath> bestPath;
private List<AddPathBestPath> bestPathRemoved;
protected OffsetMap offsets = OffsetMap.EMPTY;
- protected ContainerNode[] values = new ContainerNode[0];
+ protected Attributes[] values = new Attributes[0];
protected Long[] pathsId = new Long[0];
private long pathIdCounter = 0L;
private boolean oldNonAddPathBestPathTheSame;
private static final class RemovedPath {
private final RouteKey key;
- private final Long pathId;
+ private final long pathId;
- RemovedPath(final RouteKey key, final Long pathId) {
+ RemovedPath(final RouteKey key, final long pathId) {
this.key = key;
this.pathId = pathId;
}
- Long getPathId() {
+ long getPathId() {
return this.pathId;
}
}
}
- private int addRoute(final RouteKey key, final ContainerNode attributes) {
+ protected int addRoute(final RouteKey key, final Attributes attributes) {
int offset = this.offsets.offsetOf(key);
if (offset < 0) {
final OffsetMap newOffsets = this.offsets.with(key);
offset = newOffsets.offsetOf(key);
- final ContainerNode[] newAttributes = newOffsets.expand(this.offsets, this.values, offset);
+ final Attributes[] newAttributes = newOffsets.expand(this.offsets, this.values, offset);
final Long[] newPathsId = newOffsets.expand(this.offsets, this.pathsId, offset);
this.values = newAttributes;
this.offsets = newOffsets;
return offset;
}
- protected int addRoute(final RouteKey key, final NodeIdentifier attributesIdentifier,
- final NormalizedNode<?, ?> data) {
- LOG.trace("Find {} in {}", attributesIdentifier, data);
- final ContainerNode advertisedAttrs
- = (ContainerNode) NormalizedNodes.findNode(data, attributesIdentifier).orElse(null);
- return addRoute(key, advertisedAttrs);
- }
-
/**
* Remove route.
*
* @return true if it was the last route
*/
protected final boolean removeRoute(final RouteKey key, final int offset) {
- final Long pathId = this.offsets.getValue(this.pathsId, offset);
+ final long pathId = this.offsets.getValue(this.pathsId, offset);
this.values = this.offsets.removeValue(this.values, offset);
this.pathsId = this.offsets.removeValue(this.pathsId, offset);
this.offsets = this.offsets.without(key);
}
@Override
- public void updateBestPaths(final RouteEntryDependenciesContainer entryDependencies,
- final NodeIdentifierWithPredicates routeIdPA, final DOMDataWriteTransaction tx) {
+ public void updateBestPaths(
+ final RouteEntryDependenciesContainer entryDependencies,
+ final Identifier routeKey,
+ final WriteTransaction tx) {
+
final RIBSupport ribSupport = entryDependencies.getRibSupport();
- final ExportPolicyPeerTracker peerPT = entryDependencies.getExportPolicyPeerTracker();
+ final KeyedInstanceIdentifier<Tables, TablesKey> locRibTarget = entryDependencies.getLocRibTableTarget();
if (this.bestPathRemoved != null) {
this.bestPathRemoved.forEach(path -> {
- final PathArgument routeIdAddPath = ribSupport.getRouteIdAddPath(path.getPathId(), routeIdPA);
- final YangInstanceIdentifier pathAddPathTarget = ribSupport
- .routePath(entryDependencies.getLocRibTableTarget().node(ROUTES_IDENTIFIER), routeIdAddPath);
- fillLocRib(pathAddPathTarget, null, tx);
+ final Identifier newRouteKey = ribSupport.createNewRouteKey(path.getPathId(), routeKey);
+ final InstanceIdentifier routeTarget = ribSupport.createRouteIdentifier(locRibTarget, newRouteKey);
+ LOG.debug("Delete route from LocRib {}", routeTarget);
+ tx.delete(LogicalDatastoreType.OPERATIONAL, routeTarget);
});
this.bestPathRemoved = null;
}
if (this.removedPaths != null) {
this.removedPaths.forEach(removedPath -> {
- final PathArgument routeIdAddPath = ribSupport.getRouteIdAddPath(removedPath.getPathId(), routeIdPA);
- final PathArgument routeIdAddPathDefault = ribSupport.getRouteIdAddPath(NON_PATH_ID_VALUE, routeIdPA);
+ final Identifier routeKeyAddPath
+ = ribSupport.createNewRouteKey(removedPath.getPathId(), routeKey);
+ final Identifier routeKeyNonAddPath = ribSupport.createNewRouteKey(NON_PATH_ID_VALUE, routeKey);
fillAdjRibsOut(true, null, null, null,
- routeIdAddPathDefault, routeIdAddPath,
+ routeKeyNonAddPath, routeKeyAddPath,
RouterIds.createPeerId(removedPath.getRouteId()),
- peerPT, entryDependencies.getLocalTablesKey(), ribSupport, tx);
+ entryDependencies.getLocalTablesKey(), entryDependencies, tx);
});
this.removedPaths = null;
}
if (this.newBestPathToBeAdvertised != null) {
this.newBestPathToBeAdvertised.forEach(path -> addPathToDataStore(entryDependencies, path,
- isFirstBestPath(this.bestPath.indexOf(path)), routeIdPA,
- peerPT, tx));
+ isFirstBestPath(this.bestPath.indexOf(path)), routeKey, tx));
this.newBestPathToBeAdvertised = null;
}
}
@Override
public void initializeBestPaths(final RouteEntryDependenciesContainer entryDependencies,
- final RouteEntryInfo entryInfo, final PeerExportGroup peerGroup, final DOMDataWriteTransaction tx) {
- final PeerId toPeer = entryInfo.getToPeerId();
- final ExportPolicyPeerTracker peerPT = entryDependencies.getExportPolicyPeerTracker();
- final boolean destPeerSupAddPath = peerPT.isAddPathSupportedByPeer(toPeer);
+ final RouteEntryInfo entryInfo, final WriteTransaction tx) {
if (this.bestPath != null) {
+ final Peer toPeer = entryInfo.getToPeer();
final TablesKey localTk = entryDependencies.getLocalTablesKey();
- final RIBSupport ribSup = entryDependencies.getRibSupport();
- this.bestPath.stream().filter(path -> filterRoutes(path.getPeerId(), toPeer, localTk)
- && peersSupportsAddPathOrIsFirstBestPath(destPeerSupAddPath,
- isFirstBestPath(this.bestPath.indexOf(path))))
- .forEach(path -> writeRoutePath(entryInfo, peerGroup, destPeerSupAddPath,
- path, localTk, ribSup, tx));
+ final boolean destPeerSupAddPath = toPeer.supportsAddPathSupported(localTk);
+ for (final AddPathBestPath path : this.bestPath) {
+ if (!filterRoutes(path.getPeerId(), toPeer, localTk)) {
+ continue;
+ }
+ writeRoutePath(entryInfo, destPeerSupAddPath, path, localTk, entryDependencies, tx);
+ }
}
}
- private void writeRoutePath(final RouteEntryInfo entryInfo, final PeerExportGroup peerGroup,
+ @SuppressWarnings("unchecked")
+ private void writeRoutePath(final RouteEntryInfo entryInfo,
final boolean destPeerSupAddPath, final AddPathBestPath path,
- final TablesKey localTK, final RIBSupport ribSup, final DOMDataWriteTransaction tx) {
- final NodeIdentifierWithPredicates routeId = entryInfo.getRouteId();
- final Peer fromPeer = this.peerTracker.getPeer(path.getPeerId());
- final ContainerNode effectiveAttributes
- = peerGroup.effectiveAttributes(fromPeer.getRole(), path.getAttributes());
- final NodeIdentifierWithPredicates routeIdAddPath = ribSup
- .getRouteIdAddPath(destPeerSupAddPath ? path.getPathId() : NON_PATH_ID_VALUE, routeId);
-
- writeRoute(entryInfo.getToPeerId(), getAdjRibOutYII(ribSup, entryInfo.getRootPath(), routeIdAddPath, localTK),
- effectiveAttributes, createValue(routeIdAddPath, path), ribSup, tx);
+ final TablesKey localTK, final RouteEntryDependenciesContainer routeEntryDep, final WriteTransaction tx) {
+ final Identifier routeKey = entryInfo.getRouteKey();
+ final RIBSupport ribSupport = routeEntryDep.getRibSupport();
+ final BGPRouteEntryExportParameters baseExp = new BGPRouteEntryExportParametersImpl(
+ this.peerTracker.getPeer(path.getPeerId()), entryInfo.getToPeer());
+ final Optional<Attributes> effAttrib = routeEntryDep.getRoutingPolicies()
+ .applyExportPolicies(baseExp, path.getAttributes());
+
+ Identifier newRouteKey = ribSupport.createNewRouteKey(destPeerSupAddPath
+ ? path.getPathId() : NON_PATH_ID_VALUE, routeKey);
+ final Peer toPeer = entryInfo.getToPeer();
+ final Route route = createRoute(ribSupport, newRouteKey, destPeerSupAddPath
+ ? path.getPathId() : NON_PATH_ID_VALUE, path);
+ InstanceIdentifier ribOutIId = ribSupport.createRouteIdentifier(toPeer.getRibOutIId(localTK), newRouteKey);
+ if (effAttrib.isPresent() && route != null) {
+ LOG.debug("Write route {} to peer AdjRibsOut {}", route, toPeer.getPeerId());
+ tx.put(LogicalDatastoreType.OPERATIONAL, ribOutIId, route);
+ tx.put(LogicalDatastoreType.OPERATIONAL, ribOutIId.child(Attributes.class), effAttrib.get());
+ }
}
- private void addPathToDataStore(final RouteEntryDependenciesContainer entryDependencies, final AddPathBestPath path,
- final boolean isFirstBestPath, final NodeIdentifierWithPredicates routeIdPA,
- final ExportPolicyPeerTracker peerPT, final DOMDataWriteTransaction tx) {
- final RIBSupport ribSup = entryDependencies.getRibSupport();
- final NodeIdentifierWithPredicates routeIdAddPath = ribSup.getRouteIdAddPath(path.getPathId(), routeIdPA);
- final NodeIdentifierWithPredicates routeIdAddPathDefault
- = ribSup.getRouteIdAddPath(NON_PATH_ID_VALUE, routeIdPA);
- final YangInstanceIdentifier pathAddPathTarget = ribSup.routePath(entryDependencies.getLocRibTableTarget()
- .node(ROUTES_IDENTIFIER), routeIdAddPath);
- final MapEntryNode addPathValue = createValue(routeIdAddPath, path);
- final MapEntryNode defaultValue = createValue(routeIdAddPathDefault, path);
- LOG.trace("Selected best value {}", addPathValue);
- fillLocRib(pathAddPathTarget, addPathValue, tx);
- fillAdjRibsOut(isFirstBestPath, path.getAttributes(), defaultValue, addPathValue, routeIdAddPathDefault,
- routeIdAddPath, path.getPeerId(), peerPT, entryDependencies.getLocalTablesKey(), ribSup, tx);
+ private void addPathToDataStore(
+ final RouteEntryDependenciesContainer entryDep,
+ final AddPathBestPath path,
+ final boolean isFirstBestPath,
+ final Identifier routeKey,
+ final WriteTransaction tx) {
+ final RIBSupport ribSup = entryDep.getRibSupport();
+ final Identifier routeKeyAddPath = ribSup.createNewRouteKey(path.getPathId(), routeKey);
+ final Identifier routeKeyAddNonPath = ribSup.createNewRouteKey(NON_PATH_ID_VALUE, routeKey);
+ final Route routeAddPath = createRoute(ribSup, routeKeyAddPath, path.getPathId(), path);
+ final Route routeNonAddPath = createRoute(ribSup, routeKeyAddNonPath, NON_PATH_ID_VALUE, path);
+
+ final KeyedInstanceIdentifier<Tables, TablesKey> locRibTarget = entryDep.getLocRibTableTarget();
+ final InstanceIdentifier routeTarget = ribSup.createRouteIdentifier(locRibTarget, routeKeyAddPath);
+ LOG.debug("Write route to LocRib {}", routeAddPath);
+ tx.put(LogicalDatastoreType.OPERATIONAL, routeTarget, routeAddPath);
+
+ fillAdjRibsOut(isFirstBestPath, path.getAttributes(), routeNonAddPath, routeAddPath, routeKeyAddNonPath,
+ routeKeyAddPath, path.getPeerId(), entryDep.getLocalTablesKey(), entryDep, tx);
}
- private void fillAdjRibsOut(final boolean isFirstBestPath, final ContainerNode attributes,
- final MapEntryNode defaultValue, final MapEntryNode addPathValue,
- final PathArgument routeIdAddPathDefault,
- final PathArgument routeIdAddPath, final PeerId routePeerId, final ExportPolicyPeerTracker peerPT,
- final TablesKey localTK, final RIBSupport ribSup, final DOMDataWriteTransaction tx) {
+ @SuppressWarnings("unchecked")
+ private void fillAdjRibsOut(
+ final boolean isFirstBestPath,
+ final Attributes attributes,
+ final Route routeNonAddPath,
+ final Route routeAddPath,
+ final Identifier routeKeyAddNonPath,
+ final Identifier routeKeyAddPath,
+ final PeerId fromPeerId,
+ final TablesKey localTK,
+ final RouteEntryDependenciesContainer routeEntryDep,
+ final WriteTransaction tx) {
/*
* We need to keep track of routers and populate adj-ribs-out, too. If we do not, we need to
* expose from which client a particular route was learned from in the local RIB, and have
* if we have two eBGP peers, for example, there is no reason why we should perform the translation
* multiple times.
*/
- for (final PeerRole role : PeerRole.values()) {
- final PeerExportGroup peerGroup = peerPT.getPeerGroup(role);
- if (peerGroup != null) {
- final Peer fromPeer = this.peerTracker.getPeer(routePeerId);
- final ContainerNode effectiveAttributes = peerGroup.effectiveAttributes(
- fromPeer.getRole(), attributes);
- peerGroup.forEach((destPeer, rootPath) -> {
- final boolean destPeerSupAddPath = peerPT.isAddPathSupportedByPeer(destPeer);
- if (filterRoutes(routePeerId, destPeer, localTK)
- && peersSupportsAddPathOrIsFirstBestPath(destPeerSupAddPath, isFirstBestPath)) {
- if (destPeerSupAddPath) {
- update(destPeer, getAdjRibOutYII(ribSup, rootPath, routeIdAddPath, localTK),
- effectiveAttributes, addPathValue, ribSup, tx);
- } else if (!this.oldNonAddPathBestPathTheSame) {
- update(destPeer, getAdjRibOutYII(ribSup, rootPath, routeIdAddPathDefault, localTK),
- effectiveAttributes, defaultValue, ribSup, tx);
- }
- }
- });
+ final RIBSupport ribSupport = routeEntryDep.getRibSupport();
+ for (final Peer toPeer : this.peerTracker.getPeers()) {
+ if (!filterRoutes(fromPeerId, toPeer, localTK)) {
+ continue;
+ }
+ final boolean destPeerSupAddPath = toPeer.supportsAddPathSupported(localTK);
+
+ if (toPeer.getPeerId().getValue().equals("bgp://127.0.0.5")) {
+ LOG.debug("Write route {} to peer AdjRibsOut {}", toPeer.getPeerId());
+ }
+ if (peersSupportsAddPathOrIsFirstBestPath(destPeerSupAddPath, isFirstBestPath)) {
+
+ Optional<Attributes> effAttrib = Optional.empty();
+ final Peer fromPeer = this.peerTracker.getPeer(fromPeerId);
+
+ if (fromPeer != null && attributes != null) {
+ final BGPRouteEntryExportParameters baseExp
+ = new BGPRouteEntryExportParametersImpl(fromPeer, toPeer);
+ effAttrib = routeEntryDep.getRoutingPolicies()
+ .applyExportPolicies(baseExp, attributes);
+ }
+ Route newRoute = null;
+ InstanceIdentifier ribOutRoute = null;
+ if (destPeerSupAddPath) {
+ newRoute = routeAddPath;
+ ribOutRoute
+ = ribSupport.createRouteIdentifier(toPeer.getRibOutIId(localTK), routeKeyAddPath);
+ } else if (!this.oldNonAddPathBestPathTheSame) {
+ ribOutRoute
+ = ribSupport.createRouteIdentifier(toPeer.getRibOutIId(localTK), routeKeyAddNonPath);
+ newRoute = routeNonAddPath;
+ }
+
+ if (effAttrib.isPresent() && newRoute != null) {
+ LOG.debug("Write route {} to peer AdjRibsOut {}", newRoute, toPeer.getPeerId());
+ tx.put(LogicalDatastoreType.OPERATIONAL, ribOutRoute, newRoute);
+ tx.put(LogicalDatastoreType.OPERATIONAL, ribOutRoute.child(Attributes.class), effAttrib.get());
+ } else if (ribOutRoute != null) {
+ LOG.trace("Removing {} from transaction for peer {}", ribOutRoute, toPeer.getPeerId());
+ tx.delete(LogicalDatastoreType.OPERATIONAL, ribOutRoute);
+ }
}
}
}
private void selectBest(final RouteKey key, final AddPathSelector selector) {
final int offset = this.offsets.offsetOf(key);
- final ContainerNode attributes = this.offsets.getValue(this.values, offset);
- final Long pathId = this.offsets.getValue(this.pathsId, offset);
+ final Attributes attributes = this.offsets.getValue(this.values, offset);
+ final long pathId = this.offsets.getValue(this.pathsId, offset);
LOG.trace("Processing router key {} attributes {}", key, attributes);
selector.processPath(attributes, key, offset, pathId);
}
import org.opendaylight.protocol.bgp.mode.api.BestPathState;
import org.opendaylight.protocol.bgp.mode.impl.BestPathStateImpl;
import org.opendaylight.protocol.bgp.mode.spi.AbstractBestPathSelector;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.Attributes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private RouteKey bestRouteKey;
private int bestOffsetPosition;
- private Long bestPathId;
+ private long bestPathId;
- public AddPathSelector(final Long ourAs) {
+ public AddPathSelector(final long ourAs) {
super(ourAs);
}
- void processPath(final ContainerNode attrs, final RouteKey key, final int offsetPosition, final Long pathId) {
+ void processPath(final Attributes attrs, final RouteKey key, final int offsetPosition, final long pathId) {
requireNonNull(key.getRouteId(), "Router ID may not be null");
// Consider only non-null attributes
if (attrs != null) {
- final UnsignedInteger originatorId = replaceOriginator(key.getRouteId(), attrs);
+ final UnsignedInteger originatorId = replaceOriginator(key.getRouteId(), attrs.getOriginatorId());
/*
* Store the new details if we have nothing stored or when the selection algorithm indicates new details
import org.opendaylight.protocol.bgp.mode.impl.add.AddPathBestPath;
import org.opendaylight.protocol.bgp.mode.impl.add.RouteKey;
import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.Attributes;
abstract class AbstractAllPathsRouteEntry extends AddPathAbstractRouteEntry {
AbstractAllPathsRouteEntry(final BGPPeerTracker peerTracker) {
/*we add the rest of path, regardless in what order they are, since this is all path case */
for (final RouteKey key : keyList) {
final int offset = this.offsets.offsetOf(key);
- final ContainerNode attributes = this.offsets.getValue(this.values, offset);
+ final Attributes attributes = this.offsets.getValue(this.values, offset);
requireNonNull(key.getRouteId(), "Router ID may not be null");
if (attributes != null) {
final BestPathState state = new BestPathStateImpl(attributes);
import org.opendaylight.protocol.bgp.mode.impl.add.AddPathBestPath;
import org.opendaylight.protocol.bgp.mode.impl.add.OffsetMap;
import org.opendaylight.protocol.bgp.mode.impl.add.RouteKey;
-import org.opendaylight.protocol.bgp.mode.spi.RouteEntryUtil;
import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.Route;
+import org.opendaylight.yangtools.yang.binding.Identifier;
final class ComplexRouteEntry extends AbstractAllPathsRouteEntry {
- private static final MapEntryNode[] EMPTY_VALUES = new MapEntryNode[0];
- private MapEntryNode[] values = EMPTY_VALUES;
+ private static final Route[] EMPTY_VALUES = new Route[0];
+ private Route[] values = EMPTY_VALUES;
ComplexRouteEntry(final BGPPeerTracker peerTracker) {
super(peerTracker);
}
@Override
- public boolean removeRoute(final UnsignedInteger routerId, final Long remotePathId) {
+ public boolean removeRoute(final UnsignedInteger routerId, final long remotePathId) {
final RouteKey key = new RouteKey(routerId, remotePathId);
final OffsetMap map = getOffsets();
final int offset = map.offsetOf(key);
}
@Override
- public MapEntryNode createValue(final NodeIdentifierWithPredicates routeId, final AddPathBestPath path) {
+ public Route createRoute(final RIBSupport ribSup, final Identifier routeKey, final long pathId,
+ final AddPathBestPath path) {
final OffsetMap map = getOffsets();
- final MapEntryNode mapValues = map.getValue(this.values, map.offsetOf(path.getRouteKey()));
- return RouteEntryUtil.createComplexRouteValue(routeId, path, mapValues);
+ final Route route = map.getValue(this.values, map.offsetOf(path.getRouteKey()));
+ return ribSup.createRoute(route, routeKey, pathId, path.getAttributes());
}
@Override
- public int addRoute(final UnsignedInteger routerId, final Long remotePathId,
- final NodeIdentifier attII,
- final NormalizedNode<?, ?> data) {
+ public int addRoute(final UnsignedInteger routerId, final long remotePathId, final Route route) {
final OffsetMap oldMap = getOffsets();
- final int offset = addRoute(new RouteKey(routerId, remotePathId), attII, data);
+ final int offset = addRoute(new RouteKey(routerId, remotePathId), route.getAttributes());
final OffsetMap newMap = getOffsets();
if (!newMap.equals(oldMap)) {
this.values = newMap.expand(oldMap, this.values, offset);
}
- newMap.setValue(this.values, offset, data);
+ newMap.setValue(this.values, offset, route);
return offset;
}
}
import com.google.common.primitives.UnsignedInteger;
import org.opendaylight.protocol.bgp.mode.impl.add.AddPathBestPath;
import org.opendaylight.protocol.bgp.mode.impl.add.RouteKey;
-import org.opendaylight.protocol.bgp.mode.spi.RouteEntryUtil;
import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.Route;
+import org.opendaylight.yangtools.yang.binding.Identifier;
final class SimpleRouteEntry extends AbstractAllPathsRouteEntry {
SimpleRouteEntry(final BGPPeerTracker peerTracker) {
}
@Override
- public boolean removeRoute(final UnsignedInteger routerId, final Long remotePathId) {
+ public boolean removeRoute(final UnsignedInteger routerId, final long remotePathId) {
final RouteKey key = new RouteKey(routerId, remotePathId);
return removeRoute(key, getOffsets().offsetOf(key));
}
@Override
- public MapEntryNode createValue(final NodeIdentifierWithPredicates routeId, final AddPathBestPath path) {
- return RouteEntryUtil.createSimpleRouteValue(routeId, path);
+ public Route createRoute(final RIBSupport ribSup, final Identifier routeKey, final long pathId,
+ final AddPathBestPath path) {
+ return ribSup.createRoute(null, routeKey, pathId, path.getAttributes());
}
@Override
- public int addRoute(final UnsignedInteger routerId, final Long remotePathId, final NodeIdentifier attII,
- final NormalizedNode<?, ?> data) {
- return addRoute(new RouteKey(routerId, remotePathId), attII, data);
+ public int addRoute(final UnsignedInteger routerId, final long remotePathId, final Route route) {
+ return addRoute(new RouteKey(routerId, remotePathId), route.getAttributes());
}
}
import org.opendaylight.protocol.bgp.mode.impl.add.AddPathBestPath;
import org.opendaylight.protocol.bgp.mode.impl.add.OffsetMap;
import org.opendaylight.protocol.bgp.mode.impl.add.RouteKey;
-import org.opendaylight.protocol.bgp.mode.spi.RouteEntryUtil;
import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.Route;
+import org.opendaylight.yangtools.yang.binding.Identifier;
final class ComplexRouteEntry extends AbstractNPathsRouteEntry {
- private static final MapEntryNode[] EMPTY_VALUES = new MapEntryNode[0];
- private MapEntryNode[] values = EMPTY_VALUES;
+ private static final Route[] EMPTY_VALUES = new Route[0];
+ private Route[] values = EMPTY_VALUES;
ComplexRouteEntry(final long npaths, final BGPPeerTracker peerTracker) {
super(npaths, peerTracker);
}
@Override
- public boolean removeRoute(final UnsignedInteger routerId, final Long remotePathId) {
+ public boolean removeRoute(final UnsignedInteger routerId, final long remotePathId) {
final RouteKey key = new RouteKey(routerId, remotePathId);
final OffsetMap map = getOffsets();
final int offset = map.offsetOf(key);
}
@Override
- public MapEntryNode createValue(final NodeIdentifierWithPredicates routeId, final AddPathBestPath path) {
+ public Route createRoute(final RIBSupport ribSup, final Identifier routeKey, final long pathId,
+ final AddPathBestPath path) {
final OffsetMap map = getOffsets();
- final MapEntryNode mapValues = map.getValue(this.values, map.offsetOf(path.getRouteKey()));
- return RouteEntryUtil.createComplexRouteValue(routeId, path, mapValues);
+ final Route route = map.getValue(this.values, map.offsetOf(path.getRouteKey()));
+ return ribSup.createRoute(route, routeKey, pathId, path.getAttributes());
}
@Override
- public int addRoute(final UnsignedInteger routerId, final Long remotePathId,
- final NodeIdentifier attributesIdentifier, final NormalizedNode<?, ?> data) {
+ public int addRoute(final UnsignedInteger routerId, final long remotePathId, final Route route) {
final OffsetMap oldMap = getOffsets();
- final int offset = addRoute(new RouteKey(routerId, remotePathId), attributesIdentifier, data);
+ final int offset = addRoute(new RouteKey(routerId, remotePathId), route.getAttributes());
final OffsetMap newMap = getOffsets();
if (!newMap.equals(oldMap)) {
this.values = newMap.expand(oldMap, this.values, offset);
}
- newMap.setValue(this.values, offset, data);
+ newMap.setValue(this.values, offset, route);
return offset;
}
}
\ No newline at end of file
import com.google.common.primitives.UnsignedInteger;
import org.opendaylight.protocol.bgp.mode.impl.add.AddPathBestPath;
import org.opendaylight.protocol.bgp.mode.impl.add.RouteKey;
-import org.opendaylight.protocol.bgp.mode.spi.RouteEntryUtil;
import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.Route;
+import org.opendaylight.yangtools.yang.binding.Identifier;
final class SimpleRouteEntry extends AbstractNPathsRouteEntry {
SimpleRouteEntry(final Long npaths, final BGPPeerTracker peerTracker) {
}
@Override
- public boolean removeRoute(final UnsignedInteger routerId, final Long remotePathId) {
+ public boolean removeRoute(final UnsignedInteger routerId, final long remotePathId) {
final RouteKey key = new RouteKey(routerId, remotePathId);
return removeRoute(key, getOffsets().offsetOf(key));
}
@Override
- public MapEntryNode createValue(final NodeIdentifierWithPredicates routeId, final AddPathBestPath path) {
- return RouteEntryUtil.createSimpleRouteValue(routeId, path);
+ public Route createRoute(final RIBSupport ribSup, final Identifier routeKey, final long pathId,
+ final AddPathBestPath path) {
+ return ribSup.createRoute(null, routeKey, pathId, path.getAttributes());
}
@Override
- public int addRoute(final UnsignedInteger routerId, final Long remotePathId,
- final NodeIdentifier attributesIdentifier, final NormalizedNode<?, ?> data) {
- return addRoute(new RouteKey(routerId, remotePathId), attributesIdentifier, data);
+ public int addRoute(final UnsignedInteger routerId, final long remotePathId, final Route route) {
+ return addRoute(new RouteKey(routerId, remotePathId), route.getAttributes());
}
}
\ No newline at end of file
import com.google.common.annotations.VisibleForTesting;
import com.google.common.primitives.UnsignedInteger;
+import java.util.Optional;
+import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.protocol.bgp.mode.impl.BGPRouteEntryExportParametersImpl;
import org.opendaylight.protocol.bgp.mode.spi.AbstractRouteEntry;
import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
-import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.Peer;
-import org.opendaylight.protocol.bgp.rib.spi.PeerExportGroup;
import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
import org.opendaylight.protocol.bgp.rib.spi.entry.RouteEntryDependenciesContainer;
import org.opendaylight.protocol.bgp.rib.spi.entry.RouteEntryInfo;
+import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRibRoutingPolicy;
+import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRouteEntryExportParameters;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.Attributes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerRole;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.Route;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.Tables;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.TablesKey;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
+import org.opendaylight.yangtools.yang.binding.Identifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@NotThreadSafe
abstract class BaseAbstractRouteEntry extends AbstractRouteEntry<BaseBestPath> {
private static final Logger LOG = LoggerFactory.getLogger(BaseAbstractRouteEntry.class);
- private static final ContainerNode[] EMPTY_ATTRIBUTES = new ContainerNode[0];
+ private static final Attributes[] EMPTY_ATTRIBUTES = new Attributes[0];
private OffsetMap offsets = OffsetMap.EMPTY;
- private ContainerNode[] values = EMPTY_ATTRIBUTES;
+ private Attributes[] values = EMPTY_ATTRIBUTES;
private BaseBestPath bestPath;
private BaseBestPath removedBestPath;
// Select the best route.
for (int i = 0; i < this.offsets.size(); ++i) {
final UnsignedInteger routerId = this.offsets.getRouterKey(i);
- final ContainerNode attributes = this.offsets.getValue(this.values, i);
+ final Attributes attributes = this.offsets.getValue(this.values, i);
LOG.trace("Processing router id {} attributes {}", routerId, attributes);
selector.processPath(routerId, attributes);
}
}
@Override
- public int addRoute(final UnsignedInteger routerId, final Long remotePathId,
- final NodeIdentifier attributesIdentifier, final NormalizedNode<?, ?> data) {
- LOG.trace("Find {} in {}", attributesIdentifier, data);
- final ContainerNode advertisedAttrs
- = (ContainerNode) NormalizedNodes
- .findNode(data, attributesIdentifier).orElse(null);
+ public int addRoute(final UnsignedInteger routerId, final long remotePathId, final Route route) {
+ final Attributes advertisedAttrs = route.getAttributes();
int offset = this.offsets.offsetOf(routerId);
if (offset < 0) {
final OffsetMap newOffsets = this.offsets.with(routerId);
}
@Override
- public void updateBestPaths(final RouteEntryDependenciesContainer entryDependencies,
- final NodeIdentifierWithPredicates routeIdPA,
- final DOMDataWriteTransaction tx) {
+ public void updateBestPaths(
+ final RouteEntryDependenciesContainer entryDependencies,
+ final Identifier routeKey,
+ final WriteTransaction tx) {
if (this.removedBestPath != null) {
- removePathFromDataStore(entryDependencies, routeIdPA, tx);
+ removePathFromDataStore(entryDependencies, routeKey, tx);
this.removedBestPath = null;
}
if (this.bestPath != null) {
- addPathToDataStore(entryDependencies, routeIdPA, tx);
+ addPathToDataStore(entryDependencies, routeKey, tx);
}
}
@Override
- public void initializeBestPaths(final RouteEntryDependenciesContainer entryDep,
- final RouteEntryInfo entryInfo, final PeerExportGroup peerGroup, final DOMDataWriteTransaction tx) {
- if (this.bestPath != null) {
- final TablesKey localTK = entryDep.getLocalTablesKey();
- final BaseBestPath path = this.bestPath;
- final PeerId toPeerId = entryInfo.getToPeerId();
- if (filterRoutes(path.getPeerId(), toPeerId, localTK)) {
- final NodeIdentifierWithPredicates routeId = entryInfo.getRouteId();
- final RIBSupport ribSupport = entryDep.getRibSupport();
- NodeIdentifierWithPredicates routeIdDest = ribSupport.getRouteIdAddPath(path.getPathId(), routeId);
- if (routeIdDest == null) {
- routeIdDest = routeId;
- }
- final Peer fromPeer = this.peerTracker.getPeer(path.getPeerId());
- final ContainerNode effAttrib = peerGroup.effectiveAttributes(
- fromPeer.getRole(), path.getAttributes());
- final YangInstanceIdentifier rootPath = entryInfo.getRootPath();
- writeRoute(toPeerId, getAdjRibOutYII(ribSupport, rootPath, routeIdDest, localTK), effAttrib,
- createValue(routeIdDest, path), ribSupport, tx);
- }
+ @SuppressWarnings("unchecked")
+ public void initializeBestPaths(
+ final RouteEntryDependenciesContainer entryDep,
+ final RouteEntryInfo entryInfo,
+ final WriteTransaction tx) {
+ if (this.bestPath == null) {
+ return;
+ }
+ final TablesKey localTK = entryDep.getLocalTablesKey();
+ final Peer toPeer = entryInfo.getToPeer();
+ if (!filterRoutes(this.bestPath.getPeerId(), toPeer, localTK)) {
+ return;
+ }
+ final Identifier oldRouteKey = entryInfo.getRouteKey();
+ final RIBSupport ribSupport = entryDep.getRibSupport();
+ Identifier newRouteKey = ribSupport.createNewRouteKey(this.bestPath.getPathId(), oldRouteKey);
+ if (newRouteKey == null) {
+ newRouteKey = oldRouteKey;
+ }
+ final BGPRouteEntryExportParameters routeEntry = new BGPRouteEntryExportParametersImpl(
+ this.peerTracker.getPeer(this.bestPath.getPeerId()), toPeer);
+ final Optional<Attributes> effAttrib = entryDep.getRoutingPolicies()
+ .applyExportPolicies(routeEntry, this.bestPath.getAttributes());
+ final Route route = createRoute(ribSupport, newRouteKey, this.bestPath.getPathId(), this.bestPath);
+ InstanceIdentifier ribOutIId = ribSupport.createRouteIdentifier(toPeer.getRibOutIId(localTK), newRouteKey);
+ if (effAttrib.isPresent() && route != null) {
+ LOG.debug("Write route {} to peer AdjRibsOut {}", route, toPeer.getPeerId());
+ tx.put(LogicalDatastoreType.OPERATIONAL, ribOutIId, route);
+ tx.put(LogicalDatastoreType.OPERATIONAL, ribOutIId.child(Attributes.class), effAttrib.get());
}
}
+ @SuppressWarnings("unchecked")
private void removePathFromDataStore(final RouteEntryDependenciesContainer entryDep,
- final NodeIdentifierWithPredicates routeIdPA, final DOMDataWriteTransaction tx) {
+ final Identifier routeKey, final WriteTransaction tx) {
LOG.trace("Best Path removed {}", this.removedBestPath);
- final YangInstanceIdentifier locRibTarget = entryDep.getLocRibTableTarget();
+ final KeyedInstanceIdentifier<Tables, TablesKey> locRibTarget = entryDep.getLocRibTableTarget();
final RIBSupport ribSup = entryDep.getRibSupport();
- NodeIdentifierWithPredicates routeIdTarget
- = ribSup.getRouteIdAddPath(this.removedBestPath.getPathId(), routeIdPA);
- if (routeIdTarget == null) {
- routeIdTarget = routeIdPA;
+ Identifier newRouteKey = ribSup.createNewRouteKey(this.removedBestPath.getPathId(), routeKey);
+ if (newRouteKey == null) {
+ newRouteKey = routeKey;
}
- fillLocRib(ribSup.routePath(locRibTarget.node(ROUTES_IDENTIFIER), routeIdTarget), null, tx);
- fillAdjRibsOut(null, null, routeIdTarget, this.removedBestPath.getPeerId(), entryDep, tx);
+ final InstanceIdentifier routeTarget = ribSup.createRouteIdentifier(locRibTarget, newRouteKey);
+ LOG.debug("Delete route from LocRib {}", routeTarget);
+ tx.delete(LogicalDatastoreType.OPERATIONAL, routeTarget);
+ fillAdjRibsOut(null, null, newRouteKey, this.removedBestPath.getPeerId(),
+ entryDep, tx);
}
+ @SuppressWarnings("unchecked")
private void addPathToDataStore(final RouteEntryDependenciesContainer entryDep,
- final NodeIdentifierWithPredicates routeIdPA, final DOMDataWriteTransaction tx) {
+ final Identifier routeKey, final WriteTransaction tx) {
final RIBSupport ribSup = entryDep.getRibSupport();
- final YangInstanceIdentifier locRibTarget = entryDep.getLocRibTableTarget();
- NodeIdentifierWithPredicates routeIdDest = ribSup.getRouteIdAddPath(this.bestPath.getPathId(), routeIdPA);
- if (routeIdDest == null) {
- routeIdDest = routeIdPA;
+ Identifier newRouteKey = ribSup.createNewRouteKey(this.bestPath.getPathId(), routeKey);
+
+ if (newRouteKey == null) {
+ newRouteKey = routeKey;
}
- final MapEntryNode value = createValue(routeIdDest, this.bestPath);
- LOG.trace("Selected best value {}", value);
+ final Route route = createRoute(ribSup, newRouteKey, this.bestPath.getPathId(), this.bestPath);
+ LOG.trace("Selected best route {}", route);
+
+ final KeyedInstanceIdentifier<Tables, TablesKey> locRibTarget = entryDep.getLocRibTableTarget();
+ final InstanceIdentifier routeTarget = ribSup.createRouteIdentifier(locRibTarget, newRouteKey);
+ LOG.debug("Write route to LocRib {}", route);
+ tx.put(LogicalDatastoreType.OPERATIONAL, routeTarget, route);
+
- final YangInstanceIdentifier pathAddPathTarget
- = ribSup.routePath(locRibTarget.node(ROUTES_IDENTIFIER), routeIdDest);
- fillLocRib(pathAddPathTarget, value, tx);
- fillAdjRibsOut(this.bestPath.getAttributes(), value, routeIdDest, this.bestPath.getPeerId(), entryDep, tx);
+ fillAdjRibsOut(this.bestPath.getAttributes(), route, newRouteKey, this.bestPath.getPeerId(),
+ entryDep, tx);
}
final OffsetMap getOffsets() {
}
@VisibleForTesting
- private void fillAdjRibsOut(final ContainerNode attributes, final MapEntryNode value,
- final NodeIdentifierWithPredicates routeIdPA, final PeerId fromPeerId,
+ @SuppressWarnings("unchecked")
+ private void fillAdjRibsOut(
+ @Nullable final Attributes attributes,
+ @Nullable final Route route,
+ final Identifier routeKey, final PeerId fromPeerId,
final RouteEntryDependenciesContainer routeEntryDep,
- final DOMDataWriteTransaction tx) {
+ final WriteTransaction tx) {
/*
* We need to keep track of routers and populate adj-ribs-out, too. If we do not, we need to
* expose from which client a particular route was learned from in the local RIB, and have
* if we have two eBGP peers, for example, there is no reason why we should perform the translation
* multiple times.
*/
- final RIBSupport ribSup = routeEntryDep.getRibSupport();
- final ExportPolicyPeerTracker peerPT = routeEntryDep.getExportPolicyPeerTracker();
final TablesKey localTK = routeEntryDep.getLocalTablesKey();
- for (final PeerRole role : PeerRole.values()) {
- final PeerExportGroup peerGroup = peerPT.getPeerGroup(role);
- if (peerGroup != null) {
- final Peer fromPeer = this.peerTracker.getPeer(fromPeerId);
- final ContainerNode effAttrib = peerGroup.effectiveAttributes(fromPeer.getRole(), attributes);
- peerGroup.forEach((destPeer, rootPath) -> {
- if (!filterRoutes(fromPeerId, destPeer, localTK)) {
- return;
- }
- update(destPeer, getAdjRibOutYII(ribSup, rootPath, routeIdPA, localTK), effAttrib, value, ribSup,
- tx);
- });
+ final BGPRibRoutingPolicy routingPolicies = routeEntryDep.getRoutingPolicies();
+ final RIBSupport ribSupport = routeEntryDep.getRibSupport();
+ for (final Peer toPeer : this.peerTracker.getPeers()) {
+ if (!filterRoutes(fromPeerId, toPeer, localTK)) {
+ continue;
+ }
+ Optional<Attributes> effAttr = Optional.empty();
+ final Peer fromPeer = this.peerTracker.getPeer(fromPeerId);
+ if (fromPeer != null && attributes != null) {
+ final BGPRouteEntryExportParameters routeEntry
+ = new BGPRouteEntryExportParametersImpl(fromPeer, toPeer);
+ effAttr = routingPolicies.applyExportPolicies(routeEntry, attributes);
+ }
+ final InstanceIdentifier ribOutTarget
+ = ribSupport.createRouteIdentifier(toPeer.getRibOutIId(localTK), routeKey);
+ if (effAttr.isPresent() && route != null) {
+ LOG.debug("Write route {} to peer AdjRibsOut {}", route, toPeer.getPeerId());
+ tx.put(LogicalDatastoreType.OPERATIONAL, ribOutTarget, route);
+ tx.put(LogicalDatastoreType.OPERATIONAL, ribOutTarget.child(Attributes.class), effAttr.get());
+ } else if (fromPeer != null) {
+ LOG.trace("Removing {} from transaction for peer {}", ribOutTarget, toPeer.getPeerId());
+ tx.delete(LogicalDatastoreType.OPERATIONAL, ribOutTarget);
}
}
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerId;
final class BaseBestPath extends AbstractBestPath {
- private static final long PATH_ID = 0;
+ private static final short PATH_ID = 0;
private final UnsignedInteger routerId;
BaseBestPath(@Nonnull final UnsignedInteger routerId, @Nonnull final BestPathState state) {
import org.opendaylight.protocol.bgp.mode.api.BestPathState;
import org.opendaylight.protocol.bgp.mode.impl.BestPathStateImpl;
import org.opendaylight.protocol.bgp.mode.spi.AbstractBestPathSelector;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.Attributes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
super(ourAs);
}
- void processPath(final UnsignedInteger routerId, final ContainerNode attrs) {
+ void processPath(final UnsignedInteger routerId, final Attributes attrs) {
requireNonNull(routerId, "Router ID may not be null");
// Consider only non-null attributes
if (attrs != null) {
- final UnsignedInteger originatorId = replaceOriginator(routerId, attrs);
+ final UnsignedInteger originatorId = replaceOriginator(routerId, attrs.getOriginatorId());
/*
* Store the new details if we have nothing stored or when the selection algorithm indicates new details
* are better.
package org.opendaylight.protocol.bgp.mode.impl.base;
import com.google.common.primitives.UnsignedInteger;
-import org.opendaylight.protocol.bgp.mode.spi.RouteEntryUtil;
import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.Route;
+import org.opendaylight.yangtools.yang.binding.Identifier;
final class ComplexRouteEntry extends BaseAbstractRouteEntry {
- private static final MapEntryNode[] EMPTY_VALUES = new MapEntryNode[0];
- private MapEntryNode[] values = EMPTY_VALUES;
+ private static final Route[] EMPTY_VALUES = new Route[0];
+ private Route[] values = EMPTY_VALUES;
ComplexRouteEntry(final BGPPeerTracker peerTracker) {
super(peerTracker);
}
@Override
- public int addRoute(final UnsignedInteger routerId, final Long remotePathId, final NodeIdentifier attrII,
- final NormalizedNode<?, ?> data) {
+ public int addRoute(final UnsignedInteger routerId, final long remotePathId, final Route route) {
final OffsetMap oldMap = getOffsets();
- final int offset = super.addRoute(routerId, remotePathId, attrII, data);
+ final int offset = super.addRoute(routerId, remotePathId, route);
final OffsetMap newMap = getOffsets();
if (!newMap.equals(oldMap)) {
this.values = newMap.expand(oldMap, this.values, offset);
}
- newMap.setValue(this.values, offset, data);
+ newMap.setValue(this.values, offset, route);
return offset;
}
@Override
- public boolean removeRoute(final UnsignedInteger routerId, final Long remotePathId) {
+ public boolean removeRoute(final UnsignedInteger routerId, final long remotePathId) {
final OffsetMap map = getOffsets();
final int offset = map.offsetOf(routerId);
this.values = map.removeValue(this.values, offset);
}
@Override
- public MapEntryNode createValue(final NodeIdentifierWithPredicates routeId, final BaseBestPath path) {
+ public Route createRoute(final RIBSupport ribSup, Identifier routeKey, final long pathId,
+ final BaseBestPath path) {
final OffsetMap map = getOffsets();
- final MapEntryNode mapValues = map.getValue(this.values, map.offsetOf(path.getRouterId()));
- return RouteEntryUtil.createComplexRouteValue(routeId, path, mapValues);
+ final Route route = map.getValue(this.values, map.offsetOf(path.getRouterId()));
+ return ribSup.createRoute(route, routeKey, pathId, path.getAttributes());
}
}
package org.opendaylight.protocol.bgp.mode.impl.base;
import com.google.common.primitives.UnsignedInteger;
-import org.opendaylight.protocol.bgp.mode.spi.RouteEntryUtil;
import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.Route;
+import org.opendaylight.yangtools.yang.binding.Identifier;
final class SimpleRouteEntry extends BaseAbstractRouteEntry {
SimpleRouteEntry(final BGPPeerTracker peerTracker) {
}
@Override
- public boolean removeRoute(UnsignedInteger routerId, final Long remotePathId) {
- return removeRoute(routerId, getOffsets().offsetOf(routerId));
+ public Route createRoute(final RIBSupport ribSup, final Identifier routeKey, final long pathId,
+ final BaseBestPath path) {
+ return ribSup.createRoute(null, routeKey, pathId, path.getAttributes());
}
@Override
- public MapEntryNode createValue(final NodeIdentifierWithPredicates routeId, final BaseBestPath path) {
- return RouteEntryUtil.createSimpleRouteValue(routeId, path);
+ public boolean removeRoute(UnsignedInteger routerId, final long remotePathId) {
+ return removeRoute(routerId, getOffsets().offsetOf(routerId));
}
}
import com.google.common.base.MoreObjects;
import org.opendaylight.protocol.bgp.mode.api.BestPath;
import org.opendaylight.protocol.bgp.mode.api.BestPathState;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.Attributes;
public abstract class AbstractBestPath implements BestPath {
protected final BestPathState state;
}
@Override
- public final ContainerNode getAttributes() {
+ public final Attributes getAttributes() {
return this.state.getAttributes();
}
package org.opendaylight.protocol.bgp.mode.spi;
-import com.google.common.collect.ImmutableList;
import com.google.common.primitives.UnsignedInteger;
-import java.util.Collection;
-import java.util.Optional;
import javax.annotation.Nonnull;
import org.opendaylight.protocol.bgp.mode.api.BestPathState;
import org.opendaylight.protocol.bgp.rib.spi.RouterIds;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.OriginatorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.attributes.OriginatorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpOrigin;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
public class AbstractBestPathSelector {
- private static final Collection<YangInstanceIdentifier.PathArgument> ORIGINATOR_ID = ImmutableList.of(new
- YangInstanceIdentifier.NodeIdentifier(OriginatorId.QNAME),
- new YangInstanceIdentifier.NodeIdentifier(QName.create(OriginatorId.QNAME, "originator")));
-
- private final Long ourAs;
+ private final long ourAs;
protected UnsignedInteger bestOriginatorId = null;
protected BestPathState bestState = null;
- protected AbstractBestPathSelector(final Long ourAs) {
+ protected AbstractBestPathSelector(final long ourAs) {
this.ourAs = ourAs;
}
/**
* RFC 4456 mandates the use of Originator IDs instead of Router ID for
* selection purposes.
- * @param routerId routerID
- * @param attrs router attributes
+ *
+ * @param routerId routerID
+ * @param originatorId originator
* @return returns originators Id if present otherwise routerId
*/
- protected UnsignedInteger replaceOriginator(final UnsignedInteger routerId, final ContainerNode attrs) {
- final Optional<NormalizedNode<?, ?>> maybeOriginatorId = NormalizedNodes.findNode(attrs, ORIGINATOR_ID);
- if (maybeOriginatorId.isPresent()) {
- return RouterIds.routerIdForAddress((String) maybeOriginatorId.get().getValue());
+ protected UnsignedInteger replaceOriginator(final UnsignedInteger routerId, final OriginatorId originatorId) {
+ if (originatorId != null) {
+ RouterIds.routerIdForAddress(originatorId.getOriginator().getValue());
}
return routerId;
*
* FIXME: we should know this information from the peer directly.
*/
- if (!this.ourAs.equals(bestAs) && this.ourAs.equals(newAs)) {
+ if (this.ourAs != bestAs && this.ourAs == newAs) {
return true;
}
}
import static java.util.Objects.requireNonNull;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import javax.annotation.Nonnull;
import org.opendaylight.protocol.bgp.mode.api.BestPath;
import org.opendaylight.protocol.bgp.mode.api.RouteEntry;
import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.Peer;
import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
-import org.opendaylight.protocol.bgp.rib.spi.RibSupportUtils;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerRole;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.rib.peer.AdjRibOut;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.Tables;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.Route;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.TablesKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.tables.Routes;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.opendaylight.yangtools.yang.binding.Identifier;
public abstract class AbstractRouteEntry<T extends BestPath> implements RouteEntry {
-
- private static final Logger LOG = LoggerFactory.getLogger(AbstractRouteEntry.class);
-
- protected static final NodeIdentifier ROUTES_IDENTIFIER = new NodeIdentifier(Routes.QNAME);
protected final BGPPeerTracker peerTracker;
public AbstractRouteEntry(final BGPPeerTracker peerTracker) {
}
/**
- * Create value.
- *
- * @param routeId router ID pathArgument
- * @param path BestPath
- * @return MapEntryNode
+ * Create new Route with route jey created from passed parameters.
*/
- public abstract MapEntryNode createValue(NodeIdentifierWithPredicates routeId, T path);
-
- protected static void fillLocRib(final YangInstanceIdentifier routeTarget, final NormalizedNode<?, ?> value,
- final DOMDataWriteTransaction tx) {
- if (value != null) {
- LOG.debug("Write route to LocRib {}", value);
- tx.put(LogicalDatastoreType.OPERATIONAL, routeTarget, value);
- } else {
- LOG.debug("Delete route from LocRib {}", routeTarget);
- tx.delete(LogicalDatastoreType.OPERATIONAL, routeTarget);
- }
- }
-
- protected static void update(final PeerId destPeer, final YangInstanceIdentifier routeTarget,
- final ContainerNode effAttr, final NormalizedNode<?, ?> value, final RIBSupport ribSup,
- final DOMDataWriteTransaction tx) {
- if (!writeRoute(destPeer, routeTarget, effAttr, value, ribSup, tx)) {
- deleteRoute(destPeer, routeTarget, tx);
- }
- }
-
- protected static boolean writeRoute(final PeerId destPeer, final YangInstanceIdentifier routeTarget,
- final ContainerNode effAttrib, final NormalizedNode<?, ?> value, final RIBSupport ribSup,
- final DOMDataWriteTransaction tx) {
- if (effAttrib != null && value != null) {
- LOG.debug("Write route {} to peer AdjRibsOut {}", value, destPeer);
- tx.put(LogicalDatastoreType.OPERATIONAL, routeTarget, value);
- tx.put(LogicalDatastoreType.OPERATIONAL, routeTarget.node(ribSup.routeAttributesIdentifier()), effAttrib);
- return true;
- }
- return false;
- }
-
- private static void deleteRoute(final PeerId destPeer, final YangInstanceIdentifier routeTarget,
- final DOMDataWriteTransaction tx) {
- LOG.trace("Removing {} from transaction for peer {}", routeTarget, destPeer);
- tx.delete(LogicalDatastoreType.OPERATIONAL, routeTarget);
- }
+ public abstract Route createRoute(@Nonnull RIBSupport ribSup, @Nonnull Identifier routeKey, long pathId, T path);
- protected boolean filterRoutes(final PeerId rootPeer, final PeerId destPeer, final TablesKey localTK) {
- final Peer peer = this.peerTracker.getPeer(destPeer);
- return !(peer == null
- || !peer.supportsTable(localTK)
- || PeerRole.Internal.equals(peer.getRole()))
- && !rootPeer.equals(destPeer);
- }
-
- protected static YangInstanceIdentifier getAdjRibOutYII(final RIBSupport ribSup,
- final YangInstanceIdentifier rootPath, final PathArgument routeId, final TablesKey localTK) {
- return ribSup.routePath(rootPath.node(AdjRibOut.QNAME).node(Tables.QNAME)
- .node(RibSupportUtils.toYangTablesKey(localTK)).node(ROUTES_IDENTIFIER), routeId);
+ /**
+ * Returns true if route can be send.
+ */
+ protected boolean filterRoutes(final PeerId fromPeer, final Peer toPeer, final TablesKey localTK) {
+ return !(toPeer == null
+ || !toPeer.supportsTable(localTK)
+ || PeerRole.Internal.equals(toPeer.getRole()))
+ && !fromPeer.equals(toPeer.getPeerId());
}
}
+++ /dev/null
-/*
- * Copyright (c) 2016 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.mode.spi;
-
-import org.opendaylight.protocol.bgp.mode.api.BestPath;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
-
-public final class RouteEntryUtil {
- private RouteEntryUtil() {
- throw new UnsupportedOperationException();
- }
-
- public static MapEntryNode createSimpleRouteValue(final NodeIdentifierWithPredicates routeId, final BestPath path) {
- final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> b = Builders.mapEntryBuilder();
- b.withNodeIdentifier(routeId);
- b.addChild(path.getAttributes());
- return b.build();
- }
-
- public static MapEntryNode createComplexRouteValue(final NodeIdentifierWithPredicates routeId, final BestPath path,
- final MapEntryNode mapValues) {
- final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder
- =
- Builders.mapEntryBuilder();
- mapEntryBuilder.withNodeIdentifier(routeId);
- mapEntryBuilder.addChild(path.getAttributes());
- mapValues.getValue().forEach(mapEntryBuilder::addChild);
- return mapEntryBuilder.build();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2016 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.mode.impl;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.opendaylight.protocol.bgp.mode.impl.base.BasePathSelectorTest.ATTRS_EXTENSION_Q;
-import static org.opendaylight.protocol.bgp.mode.impl.base.BasePathSelectorTest.SEGMENTS_NID;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.primitives.UnsignedInteger;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.function.BiConsumer;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import org.mockito.Mock;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
-import org.opendaylight.protocol.bgp.rib.spi.PeerExportGroup;
-import org.opendaylight.protocol.bgp.rib.spi.PeerExportGroup.PeerExporTuple;
-import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
-import org.opendaylight.protocol.bgp.rib.spi.RibSupportUtils;
-import org.opendaylight.protocol.bgp.rib.spi.entry.RouteEntryDependenciesContainer;
-import org.opendaylight.protocol.bgp.rib.spi.entry.RouteEntryInfo;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev171207.ipv4.routes.Ipv4Routes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev171207.ipv4.routes.ipv4.routes.Ipv4Route;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.Attributes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.attributes.AsPath;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.attributes.AtomicAggregate;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.attributes.Origin;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.BgpRib;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerRole;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.rib.LocRib;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.rib.peer.AdjRibOut;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.Tables;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.tables.Routes;
-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.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-
-public abstract class AbstractRouteEntryTest extends BGPPeerTrackerMock {
- protected static final long REMOTE_PATH_ID = 1;
- protected static final YangInstanceIdentifier PEER_YII2 = YangInstanceIdentifier
- .of(QName.create("urn:opendaylight:params:xml:ns:yang:bgp-inet:test",
- "2015-03-05", "peer2"));
- protected static final long AS = 64444;
- protected static final UnsignedInteger ROUTER_ID = UnsignedInteger.ONE;
- protected static final YangInstanceIdentifier LOC_RIB_TARGET =
- YangInstanceIdentifier.create(YangInstanceIdentifier.of(BgpRib.QNAME).node(LocRib.QNAME)
- .node(Tables.QNAME).node(RibSupportUtils.toYangTablesKey(TABLES_KEY)).getPathArguments());
- private static final long PATH_ID = 1;
- private static final String PREFIX = "1.2.3.4/32";
- private static final String PREFIX2 = "2.2.2.2/32";
- private static final YangInstanceIdentifier PEER_YII
- = YangInstanceIdentifier.of(QName.create("urn:opendaylight:params:xml:ns:yang:bgp-inet:test",
- "2015-03-05", "peer1"));
- private static final NodeIdentifier ROUTES_IDENTIFIER = new NodeIdentifier(Routes.QNAME);
- private static final NodeIdentifier ORIGIN_NID = new NodeIdentifier(QName.create(ATTRS_EXTENSION_Q,
- Origin.QNAME.getLocalName()).intern());
- private static final NodeIdentifier ORIGIN_VALUE_NID = new NodeIdentifier(QName.create(ATTRS_EXTENSION_Q,
- "value").intern());
- private static final NodeIdentifier AS_PATH_NID = new NodeIdentifier(QName.create(ATTRS_EXTENSION_Q,
- AsPath.QNAME.getLocalName()).intern());
- private static final NodeIdentifier ATOMIC_NID = new NodeIdentifier(QName.create(ATTRS_EXTENSION_Q,
- AtomicAggregate.QNAME.getLocalName()));
- private static final QName Q_NAME = BindingReflections.findQName(Ipv4Routes.class).intern();
- private static final NodeIdentifier ROUTE_ATTRIBUTES_IDENTIFIER
- = new NodeIdentifier(QName.create(Q_NAME, Attributes.QNAME.getLocalName().intern()));
- private static final QName PREFIX_QNAME
- = QName.create(Ipv4Route.QNAME, "prefix").intern();
- protected static final NodeIdentifierWithPredicates ROUTE_ID_PA
- = new NodeIdentifierWithPredicates(Ipv4Route.QNAME, ImmutableMap.of(PREFIX_QNAME, PREFIX));
- private static final QName PATHID_QNAME = QName.create(Ipv4Route.QNAME, "path-id").intern();
- protected static final NodeIdentifierWithPredicates ROUTE_ID_PA_ADD_PATH
- = new NodeIdentifierWithPredicates(Ipv4Route.QNAME,
- ImmutableMap.of(PATHID_QNAME, PATH_ID, PREFIX_QNAME, PREFIX2));
- @Mock
- protected RIBSupport ribSupport;
- @Mock
- protected DOMDataWriteTransaction tx;
- @Mock
- protected ExportPolicyPeerTracker peerPT;
- @Mock
- protected PeerExportGroup peg;
- @Mock
- protected RouteEntryDependenciesContainer entryDep;
- @Mock
- protected RouteEntryInfo entryInfo;
-
- protected List<YangInstanceIdentifier> yiichanges;
- protected NormalizedNode<?, ?> attributes;
- protected YangInstanceIdentifier routePaYii;
- protected YangInstanceIdentifier routePaAddPathYii;
- protected YangInstanceIdentifier routeRiboutYii;
- protected YangInstanceIdentifier routeAddRiboutYii;
- protected YangInstanceIdentifier routeRiboutAttYii;
- protected YangInstanceIdentifier routeAddRiboutAttYii;
- protected YangInstanceIdentifier routeRiboutAttYiiPeer2;
- protected YangInstanceIdentifier routeRiboutYiiPeer2;
- protected YangInstanceIdentifier routeAddRiboutYiiPeer2;
- @Mock
- private PeerExportGroup pegNot;
- private YangInstanceIdentifier locRibTargetYii;
- private YangInstanceIdentifier locRibOutTargetYii;
- private YangInstanceIdentifier locRibOutTargetYiiPeer2;
-
- public void setUp() {
- super.setUp();
- this.yiichanges = new ArrayList<>();
- this.attributes = createAttr();
- this.locRibTargetYii = LOC_RIB_TARGET.node(ROUTES_IDENTIFIER);
- this.locRibOutTargetYii = PEER_YII.node(AdjRibOut.QNAME).node(Tables.QNAME)
- .node(RibSupportUtils.toYangTablesKey(TABLES_KEY)).node(ROUTES_IDENTIFIER);
- this.routePaYii = this.locRibTargetYii.node(ROUTE_ID_PA);
- this.routePaAddPathYii = this.locRibTargetYii.node(ROUTE_ID_PA_ADD_PATH);
- this.routeRiboutYii = this.locRibOutTargetYii.node(ROUTE_ID_PA);
- this.routeAddRiboutYii = this.locRibOutTargetYii.node(ROUTE_ID_PA_ADD_PATH);
- this.routeRiboutAttYii = this.locRibOutTargetYii.node(ROUTE_ID_PA).node(ATTRS_EXTENSION_Q);
- this.routeAddRiboutAttYii = this.locRibOutTargetYii.node(ROUTE_ID_PA_ADD_PATH).node(ATTRS_EXTENSION_Q);
- this.locRibOutTargetYiiPeer2 = PEER_YII2.node(AdjRibOut.QNAME).node(Tables.QNAME)
- .node(RibSupportUtils.toYangTablesKey(TABLES_KEY)).node(ROUTES_IDENTIFIER);
- this.routeRiboutYiiPeer2 = this.locRibOutTargetYiiPeer2.node(ROUTE_ID_PA);
- this.routeRiboutAttYiiPeer2 = this.locRibOutTargetYiiPeer2.node(ROUTE_ID_PA).node(ATTRS_EXTENSION_Q);
- this.routeAddRiboutYiiPeer2 = this.locRibOutTargetYiiPeer2.node(ROUTE_ID_PA_ADD_PATH);
- mockRibSupport();
- mockExportPolicies();
- mockExportGroup();
- mockTransactionChain();
- mockEntryDep();
- mockEntryInfo();
- }
-
- private void mockEntryInfo() {
- doReturn(PEER_ID).when(this.entryInfo).getToPeerId();
- doReturn(PEER_YII2).when(this.entryInfo).getRootPath();
- }
-
- private void mockEntryDep() {
- doReturn(this.ribSupport).when(this.entryDep).getRibSupport();
- doReturn(this.peerPT).when(this.entryDep).getExportPolicyPeerTracker();
- doReturn(TABLES_KEY).when(this.entryDep).getLocalTablesKey();
- doReturn(LOC_RIB_TARGET).when(this.entryDep).getLocRibTableTarget();
- }
-
- private void mockTransactionChain() {
- doAnswer(invocation -> {
- final Object[] args = invocation.getArguments();
- this.yiichanges.add((YangInstanceIdentifier) args[1]);
- return args[1];
- }).when(this.tx)
- .put(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class), any(NormalizedNode.class));
-
- doAnswer(invocation -> {
- final Object[] args = invocation.getArguments();
- if (this.routePaYii.equals(args[1])) {
- this.yiichanges.remove(this.routePaYii);
- } else if (this.routePaAddPathYii.equals(args[1])) {
- this.yiichanges.remove(this.routePaAddPathYii);
- } else if (this.routeRiboutYii.equals(args[1])) {
- this.yiichanges.remove(this.routeRiboutYii);
- this.yiichanges.remove(this.routeAddRiboutAttYii);
- } else if (this.routeAddRiboutYii.equals(args[1])) {
- this.yiichanges.remove(this.routeAddRiboutYii);
- this.yiichanges.remove(this.routeAddRiboutAttYii);
- }
- return args[1];
- }).when(this.tx).delete(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class));
- }
-
- private void mockExportGroup() {
- doReturn(this.attributes).when(this.peg).effectiveAttributes(any(PeerRole.class), any(ContainerNode.class));
- doReturn(null).when(this.pegNot).effectiveAttributes(any(PeerRole.class), any(ContainerNode.class));
-
- final Map<PeerId, PeerExportGroup.PeerExporTuple> peers = new HashMap<>();
- doAnswer(invocation -> {
- final BiConsumer<PeerId, YangInstanceIdentifier> action = (BiConsumer) invocation.getArguments()[0];
- for (final Entry<PeerId, PeerExporTuple> pid : peers.entrySet()) {
- action.accept(pid.getKey(), pid.getValue().getYii());
- }
- return null;
- }).when(this.pegNot).forEach(any());
- doReturn(Boolean.TRUE).when(this.pegNot).containsPeer(any(PeerId.class));
-
- peers.put(PEER_ID, new PeerExportGroup.PeerExporTuple(PEER_YII, PeerRole.Ibgp));
- peers.put(PEER_ID2, new PeerExportGroup.PeerExporTuple(PEER_YII2, PeerRole.Ibgp));
- doAnswer(invocation -> {
- final BiConsumer<PeerId, YangInstanceIdentifier> action = (BiConsumer) invocation.getArguments()[0];
- for (final Entry<PeerId, PeerExporTuple> pid : peers.entrySet()) {
- action.accept(pid.getKey(), pid.getValue().getYii());
- }
- return null;
- }).when(this.peg).forEach(any());
- }
-
- private void mockExportPolicies() {
- doReturn(Boolean.TRUE).when(this.peerPT).isTableStructureInitialized(any(PeerId.class));
- doReturn(Boolean.TRUE).when(this.peerPT).isTableSupported(PEER_ID);
- doReturn(Boolean.FALSE).when(this.peerPT).isTableSupported(PEER_ID2);
- doAnswer(invocation -> {
- final Object[] args = invocation.getArguments();
- if (PeerRole.Ibgp.equals(args[0])) {
- return this.peg;
- } else if (PeerRole.Ebgp.equals(args[0])) {
- return this.pegNot;
- } else {
- return null;
- }
- }).when(this.peerPT).getPeerGroup(any(PeerRole.class));
-
- doReturn(Boolean.TRUE).when(this.peerPT).isAddPathSupportedByPeer(PEER_ID);
- doReturn(Boolean.FALSE).when(this.peerPT).isAddPathSupportedByPeer(PEER_ID2);
- }
-
- private void mockRibSupport() {
- doReturn(ROUTE_ATTRIBUTES_IDENTIFIER).when(this.ribSupport).routeAttributesIdentifier();
- doReturn(ROUTE_ID_PA_ADD_PATH).when(this.ribSupport)
- .getRouteIdAddPath(any(Long.class), eq(ROUTE_ID_PA_ADD_PATH));
- doReturn(null).when(this.ribSupport).getRouteIdAddPath(any(Long.class), eq(ROUTE_ID_PA));
- doAnswer(invocation -> {
- final Object[] args = invocation.getArguments();
- final YangInstanceIdentifier yii = (YangInstanceIdentifier) args[0];
- final PathArgument paa = (PathArgument) args[1];
-
- if (ROUTE_ID_PA.equals(paa)) {
- if (yii.equals(this.locRibTargetYii)) {
- return this.routePaYii;
- } else if (yii.equals(this.locRibOutTargetYii)) {
- return this.routeRiboutYii;
- } else if (yii.equals(this.locRibOutTargetYiiPeer2)) {
- return this.routeRiboutYiiPeer2;
- }
- } else if (ROUTE_ID_PA_ADD_PATH.equals(paa)) {
- if (yii.equals(this.locRibTargetYii)) {
- return this.routePaAddPathYii;
- } else if (yii.equals(this.locRibOutTargetYii)) {
- return this.routeAddRiboutYii;
- } else if (yii.equals(this.locRibOutTargetYiiPeer2)) {
- return this.routeAddRiboutYiiPeer2;
- }
- }
- return null;
- }).when(this.ribSupport).routePath(any(YangInstanceIdentifier.class), any(PathArgument.class));
- }
-
- private static NormalizedNode<?, ?> createAttr() {
- final ContainerNode attributes = Builders.containerBuilder()
- .withNodeIdentifier(new NodeIdentifier(ATTRS_EXTENSION_Q))
- .addChild(Builders.containerBuilder().withNodeIdentifier(ORIGIN_NID)
- .addChild(Builders.leafBuilder().withNodeIdentifier(ORIGIN_VALUE_NID)
- .withValue("igp").build()).build())
- .addChild(Builders.containerBuilder().withNodeIdentifier(AS_PATH_NID)
- .addChild(Builders.unkeyedListBuilder().withNodeIdentifier(SEGMENTS_NID).build()).build())
- .addChild(Builders.containerBuilder().withNodeIdentifier(ATOMIC_NID).build()).build();
- return ImmutableContainerNodeBuilder.create().withNodeIdentifier(ROUTE_ATTRIBUTES_IDENTIFIER)
- .withChild(attributes).build();
- }
-
- protected Map<YangInstanceIdentifier, Long> collectInfo() {
- return this.yiichanges.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
- }
-}
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.md.sal.binding.test.AbstractConcurrentDataBrokerTest;
import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.Peer;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
-public class BGPPeerTrackerMock {
+public class BGPPeerTrackerMock extends AbstractConcurrentDataBrokerTest {
protected static final PeerId PEER_ID = new PeerId("bgp://42.42.42.42");
protected static final PeerId PEER_ID2 = new PeerId("bgp://43.43.43.43");
protected static final TablesKey TABLES_KEY = new TablesKey(Ipv4AddressFamily.class,
+++ /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.mode.impl.add.all.paths;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Map;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.protocol.bgp.mode.impl.AbstractRouteEntryTest;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-public final class SimpleRouteEntryTest extends AbstractRouteEntryTest {
- private SimpleRouteEntry testBARE;
-
- @Before
- public void setUp() {
- super.setUp();
- }
-
- @Test
- public void testSimpleRouteEntry() throws Exception {
- this.testBARE = (SimpleRouteEntry) new AllPathSelection(this.peerTracker)
- .createRouteEntry(false);
- testAddRouteSelectBestAndWriteOnDS();
- testRemoveRoute();
- }
-
- private void testAddRouteSelectBestAndWriteOnDS() {
- this.testBARE.addRoute(ROUTER_ID, REMOTE_PATH_ID, this.ribSupport
- .routeAttributesIdentifier(), this.attributes);
- assertFalse(this.testBARE.isEmpty());
- assertTrue(this.testBARE.selectBest(AS));
- this.testBARE.updateBestPaths(this.entryDep, ROUTE_ID_PA_ADD_PATH, this.tx);
- final Map<YangInstanceIdentifier, Long> yiiCount = collectInfo();
- assertEquals(3, yiiCount.size());
- assertEquals(1, (long) yiiCount.get(this.routePaAddPathYii));
- assertEquals(1, (long) yiiCount.get(this.routeAddRiboutYii));
- assertEquals(1, (long) yiiCount.get(this.routeAddRiboutAttYii));
- }
-
- private void testRemoveRoute() {
- Map<YangInstanceIdentifier, Long> yiiCount = collectInfo();
- assertEquals(3, yiiCount.size());
- assertEquals(1, (long) yiiCount.get(this.routePaAddPathYii));
- assertTrue(this.testBARE.removeRoute(ROUTER_ID, REMOTE_PATH_ID));
- assertTrue(this.testBARE.selectBest(AS));
- this.testBARE.updateBestPaths(this.entryDep, ROUTE_ID_PA_ADD_PATH, this.tx);
- yiiCount = collectInfo();
- assertEquals(0, yiiCount.size());
- assertFalse(yiiCount.containsKey(this.routePaAddPathYii));
- assertFalse(yiiCount.containsKey(this.routeAddRiboutYii));
- }
-}
+++ /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.mode.impl.add.n.paths;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.doReturn;
-
-import java.util.Map;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.protocol.bgp.mode.impl.AbstractRouteEntryTest;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-public final class SimpleRouteEntryTest extends AbstractRouteEntryTest {
- private static final long N_PATHS = 2;
- private SimpleRouteEntry testBARE;
-
- @Before
- public void setUp() {
- super.setUp();
- }
-
- @Test
- public void testSimpleRouteEntry() throws Exception {
- this.testBARE = (SimpleRouteEntry) new AddPathBestNPathSelection(N_PATHS, this.peerTracker)
- .createRouteEntry(false);
- testWriteEmptyBestPath();
- testAddRouteSelectBestAndWriteOnDS();
- testRewriteSameRoute();
- testInitializePeerWithExistentRoute();
- testRemoveRoute();
- }
-
- /**
- * Add non Add Path Route.
- */
- @Test(expected = NullPointerException.class)
- public void testAddRouteSelectBestAndWriteOnDSs() {
- this.testBARE.addRoute(ROUTER_ID, REMOTE_PATH_ID, this.ribSupport.routeAttributesIdentifier(), this.attributes);
- }
-
- private void testWriteEmptyBestPath() {
- doReturn(ROUTE_ID_PA).when(this.entryInfo).getRouteId();
-
- this.testBARE.initializeBestPaths(this.entryDep, this.entryInfo, this.peg, this.tx);
- assertEquals(0, this.yiichanges.size());
- }
-
- /**
- * Add AddPath Route.
- */
- private void testAddRouteSelectBestAndWriteOnDS() {
- this.testBARE.addRoute(ROUTER_ID, REMOTE_PATH_ID, this.ribSupport.routeAttributesIdentifier(),
- this.attributes);
- assertFalse(this.testBARE.isEmpty());
- assertTrue(this.testBARE.selectBest(AS));
- this.testBARE.updateBestPaths(this.entryDep, ROUTE_ID_PA_ADD_PATH, this.tx);
- final Map<YangInstanceIdentifier, Long> yiiCount = collectInfo();
- assertEquals(3, yiiCount.size());
- assertEquals(1, (long) yiiCount.get(this.routePaAddPathYii));
- assertEquals(1, (long) yiiCount.get(this.routeAddRiboutYii));
- assertEquals(1, (long) yiiCount.get(this.routeAddRiboutAttYii));
- }
-
- private void testRewriteSameRoute() {
- this.testBARE.addRoute(ROUTER_ID, REMOTE_PATH_ID, this.ribSupport.routeAttributesIdentifier(), this.attributes);
- assertFalse(this.testBARE.selectBest(AS));
- }
-
- private void testInitializePeerWithExistentRoute() {
- assertEquals(3, this.yiichanges.size());
- doReturn(ROUTE_ID_PA_ADD_PATH).when(this.entryInfo).getRouteId();
-
- this.testBARE.initializeBestPaths(this.entryDep, this.entryInfo, this.peg, this.tx);
- assertEquals(5, this.yiichanges.size());
- final Map<YangInstanceIdentifier, Long> yiiCount = collectInfo();
- assertEquals(1, (long) yiiCount.get(this.routeAddRiboutYiiPeer2));
- assertEquals(1, (long) yiiCount.get(this.routeAddRiboutYiiPeer2));
- }
-
- private void testRemoveRoute() {
- Map<YangInstanceIdentifier, Long> yiiCount = collectInfo();
- assertEquals(5, yiiCount.size());
- assertEquals(1, (long) yiiCount.get(this.routePaAddPathYii));
- assertTrue(this.testBARE.removeRoute(ROUTER_ID, REMOTE_PATH_ID));
- assertTrue(this.testBARE.selectBest(AS));
- this.testBARE.updateBestPaths(this.entryDep, ROUTE_ID_PA_ADD_PATH, this.tx);
- yiiCount = collectInfo();
- assertEquals(2, yiiCount.size());
- assertFalse(yiiCount.containsKey(this.routePaAddPathYii));
- assertFalse(yiiCount.containsKey(this.routeAddRiboutYii));
- }
-}
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.opendaylight.protocol.bgp.parser.spi.PathIdUtil.NON_PATH_ID_VALUE;
import com.google.common.primitives.UnsignedInteger;
import org.junit.Before;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerId;
public class BaseBestPathTest {
- private static final long PATH_ID = 0;
- private BaseBestPath baseBestPath;
private static final UnsignedInteger ROUTER_ID = UnsignedInteger.valueOf(2130706433);
private static final PeerId PEER_ID = new PeerId("bgp://127.0.0.1");
+ private BaseBestPath baseBestPath;
private BaseBestPath baseBestPathCopy;
@Before
- public void setUp() throws Exception {
+ public void setUp() {
final BasePathSelector selector = new BasePathSelector(20L);
selector.processPath(BasePathSelectorTest.ROUTER_ID2,
BasePathSelectorTest.createStateFromPrefMedOriginASPath().build());
}
@Test
- public void testGetRouterId() throws Exception {
+ public void testGetRouterId() {
assertEquals(ROUTER_ID, this.baseBestPath.getRouterId());
}
@Test
- public void testGetPeerId() throws Exception {
+ public void testGetPeerId() {
assertEquals(PEER_ID, this.baseBestPath.getPeerId());
}
@Test
- public void testGetPathId() throws Exception {
- assertEquals(PATH_ID, this.baseBestPath.getPathId());
+ public void testGetPathId() {
+ assertEquals(NON_PATH_ID_VALUE, this.baseBestPath.getPathId());
}
@Test
- public void testHashCodeAndEqual() throws Exception {
+ public void testHashCodeAndEqual() {
assertTrue(this.baseBestPath.equals(this.baseBestPathCopy)
&& this.baseBestPathCopy.equals(this.baseBestPath));
assertTrue(this.baseBestPath.hashCode() == this.baseBestPathCopy.hashCode());
- assertTrue(this.baseBestPath.getPathId() == PATH_ID);
}
@Test
- public void testToString() throws Exception {
+ public void testToString() {
assertTrue(this.baseBestPath.toString().equals(this.baseBestPathCopy.toString()));
}
}
\ No newline at end of file
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
import com.google.common.primitives.UnsignedInteger;
-import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import org.junit.Test;
import org.opendaylight.protocol.bgp.mode.impl.BestPathStateImpl;
import org.opendaylight.protocol.bgp.rib.spi.RouterIds;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.attributes.as.path.Segments;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.Attributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.AttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.attributes.AsPathBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.attributes.LocalPrefBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.attributes.MultiExitDiscBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.attributes.OriginBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.attributes.as.path.SegmentsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpOrigin;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeSchemaAwareBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListNodeBuilder;
public class BasePathSelectorTest {
-
- public static final QName ATTRS_EXTENSION_Q = QName.create("urn:opendaylight:params:xml:ns:yang:bgp-inet",
- "2017-12-07", "attributes");
- public static final QName AS_NUMBER_Q = QName.create(ATTRS_EXTENSION_Q, "as-number");
- public static final NodeIdentifier SEGMENTS_NID = new NodeIdentifier(QName.create(ATTRS_EXTENSION_Q,
- Segments.QNAME.getLocalName()));
- public static final NodeIdentifier SEQ_LEAFLIST_NID = new NodeIdentifier(QName.create(ATTRS_EXTENSION_Q,
- "as-sequence"));
- public static final UnkeyedListEntryNode SEQ_SEGMENT = Builders.unkeyedListEntryBuilder()
- .withNodeIdentifier(SEGMENTS_NID).addChild(Builders.orderedLeafSetBuilder()
- .withNodeIdentifier(SEQ_LEAFLIST_NID)
- .addChild(Builders.leafSetEntryBuilder()
- .withNodeIdentifier(new NodeWithValue<>(AS_NUMBER_Q, 1L)).withValue(1L).build())
- .addChild(Builders.leafSetEntryBuilder()
- .withNodeIdentifier(new NodeWithValue<>(AS_NUMBER_Q, 2L)).withValue(2L).build())
- .addChild(Builders.leafSetEntryBuilder()
- .withNodeIdentifier(new NodeWithValue<>(AS_NUMBER_Q, 3L)).withValue(3L).build())
- .build()).build();
- private static final NodeIdentifier SET_LEAFLIST_NID = new NodeIdentifier(QName.create(ATTRS_EXTENSION_Q,
- "as-set"));
- public static final UnkeyedListEntryNode SET_SEGMENT = Builders.unkeyedListEntryBuilder()
- .withNodeIdentifier(SEGMENTS_NID).addChild(Builders.leafSetBuilder().withNodeIdentifier(SET_LEAFLIST_NID)
- .addChild(Builders.leafSetEntryBuilder()
- .withNodeIdentifier(new NodeWithValue<>(AS_NUMBER_Q, 10L)).withValue(10L).build())
- .addChild(Builders.leafSetEntryBuilder()
- .withNodeIdentifier(new NodeWithValue<>(AS_NUMBER_Q, 11L)).withValue(11L).build())
- .build()).build();
- private static final UnkeyedListEntryNode SEQ_SEGMENT2 = Builders.unkeyedListEntryBuilder()
- .withNodeIdentifier(SEGMENTS_NID).addChild(Builders.orderedLeafSetBuilder()
- .withNodeIdentifier(SEQ_LEAFLIST_NID)
- .addChild(Builders.leafSetEntryBuilder()
- .withNodeIdentifier(new NodeWithValue<>(AS_NUMBER_Q, 20L)).withValue(20L).build())
- .addChild(Builders.leafSetEntryBuilder()
- .withNodeIdentifier(new NodeWithValue<>(AS_NUMBER_Q, 2L)).withValue(2L).build())
- .addChild(Builders.leafSetEntryBuilder()
- .withNodeIdentifier(new NodeWithValue<>(AS_NUMBER_Q, 3L)).withValue(3L).build())
- .build()).build();
- private static final QName LOCAL_PREF_Q_NAME = QName.create(ATTRS_EXTENSION_Q, "local-pref");
- private static final QName MULTI_EXIT_DISC_Q_NAME = QName.create(ATTRS_EXTENSION_Q, "multi-exit-disc");
- private static final QName ORIGIN_Q_NAME = QName.create(ATTRS_EXTENSION_Q, "origin");
- private static final QName AS_PATH_Q_NAME = QName.create(ATTRS_EXTENSION_Q, "as-path");
- private static final UnsignedInteger ROUTER_ID = RouterIds.routerIdForAddress("127.0.0.1");
+ private static final List<AsNumber> SEQ_SEGMENT
+ = Arrays.asList(new AsNumber(1L), new AsNumber(2L), new AsNumber(3L));
static final UnsignedInteger ROUTER_ID2 = RouterIds.routerIdForPeerId(new PeerId("bgp://127.0.0.1"));
+ private static final List<AsNumber> SEQ_SEGMENT2
+ = Arrays.asList(new AsNumber(20L), new AsNumber(2L), new AsNumber(3L));
+ private static final UnsignedInteger ROUTER_ID = RouterIds.routerIdForAddress("127.0.0.1");
private static final UnsignedInteger ROUTER_ID3 = RouterIds.routerIdForPeerId(new PeerId("bgp://127.0.0.2"));
private final BasePathSelector selector = new BasePathSelector(20L);
private final BestPathStateImpl state = new BestPathStateImpl(createStateFromPrefMedOriginASPath().build());
private final BaseBestPath originBestPath = new BaseBestPath(ROUTER_ID, this.state);
- @Test
- public void testBestPathForEquality() {
- this.selector.processPath(ROUTER_ID2, createStateFromPrefMedOriginASPath().build());
- final BaseBestPath processedPath = this.selector.result();
+ private static Attributes createStateFromPrefMedOrigin() {
+ AttributesBuilder dataContBuilder = new AttributesBuilder();
+ addLowerLocalRef(dataContBuilder);
+ addLowerMultiExitDisc(dataContBuilder);
+ addIgpOrigin(dataContBuilder);
+ return dataContBuilder.build();
+ }
- assertEquals(this.originBestPath.getPeerId(), processedPath.getPeerId());
- assertEquals(this.originBestPath.getState().getLocalPref(), processedPath.getState().getLocalPref());
- assertEquals(this.originBestPath.getState().getMultiExitDisc(), processedPath.getState().getMultiExitDisc());
- assertEquals(this.originBestPath.getState().getOrigin(), processedPath.getState().getOrigin());
- assertEquals(this.originBestPath.getState().getPeerAs(), processedPath.getState().getPeerAs());
- assertEquals(this.originBestPath.getState().getAsPathLength(), processedPath.getState().getAsPathLength());
+ protected static AttributesBuilder createStateFromPrefMedOriginASPath() {
+ AttributesBuilder dataContBuilder = new AttributesBuilder();
+ addHigherLocalRef(dataContBuilder);
+ addHigherMultiExitDisc(dataContBuilder);
+ addEgpOrigin(dataContBuilder);
+ addAsPath(dataContBuilder, SEQ_SEGMENT);
+ return dataContBuilder;
+ }
+
+ private static void addLowerLocalRef(final AttributesBuilder dataContBuilder) {
+ dataContBuilder.setLocalPref(new LocalPrefBuilder().setPref(123L).build());
+ }
+
+ private static void addHigherLocalRef(final AttributesBuilder dataContBuilder) {
+ dataContBuilder.setLocalPref(new LocalPrefBuilder().setPref(321L).build());
+ }
+
+ private static void addLowerMultiExitDisc(final AttributesBuilder dataContBuilder) {
+ dataContBuilder.setMultiExitDisc(new MultiExitDiscBuilder().setMed(1234L).build());
+ }
+
+ private static void addHigherMultiExitDisc(final AttributesBuilder dataContBuilder) {
+ dataContBuilder.setMultiExitDisc(new MultiExitDiscBuilder().setMed(4321L).build());
+ }
+
+ private static void addIgpOrigin(final AttributesBuilder dataContBuilder) {
+ dataContBuilder.setOrigin(new OriginBuilder().setValue(BgpOrigin.Igp).build());
+ }
+
+ private static void addEgpOrigin(final AttributesBuilder dataContBuilder) {
+ dataContBuilder.setOrigin(new OriginBuilder().setValue(BgpOrigin.Egp).build());
+ }
+
+ private static void addAsPath(final AttributesBuilder dataContBuilder, final List<AsNumber> segment) {
+ dataContBuilder.setAsPath(new AsPathBuilder().setSegments(
+ Collections.singletonList(new SegmentsBuilder().setAsSequence(segment).build())).build());
}
@Test
processedPath = this.selector.result();
assertEquals(321L, processedPath.getState().getLocalPref().longValue());
- DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> dataContBuilder =
- createContBuilder(ATTRS_EXTENSION_Q);
+ AttributesBuilder dataContBuilder = new AttributesBuilder();
addLowerLocalRef(dataContBuilder); // prefer path with higher LOCAL_PREF
this.selector.processPath(ROUTER_ID2, dataContBuilder.build());
processedPath = this.selector.result();
assertEquals(321L, processedPath.getState().getLocalPref().longValue());
}
+ @Test
+ public void testBestPathForEquality() {
+ this.selector.processPath(ROUTER_ID2, createStateFromPrefMedOriginASPath().build());
+ final BaseBestPath processedPath = this.selector.result();
+
+ assertEquals(this.originBestPath.getPeerId(), processedPath.getPeerId());
+ assertEquals(this.originBestPath.getState().getLocalPref(), processedPath.getState().getLocalPref());
+ assertEquals(this.originBestPath.getState().getMultiExitDisc(), processedPath.getState().getMultiExitDisc());
+ assertEquals(this.originBestPath.getState().getOrigin(), processedPath.getState().getOrigin());
+ assertEquals(this.originBestPath.getState().getPeerAs(), processedPath.getState().getPeerAs());
+ assertEquals(this.originBestPath.getState().getAsPathLength(), processedPath.getState().getAsPathLength());
+ }
+
@Test
public void testBestPathSelectionOptions() {
- DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> dataContBuilder
- = createStateFromPrefMedOriginASPath();
+ AttributesBuilder dataContBuilder = createStateFromPrefMedOriginASPath();
this.selector.processPath(ROUTER_ID2, dataContBuilder.build());
BaseBestPath processedPath = this.selector.result();
assertEquals(1, processedPath.getState().getOrigin().getIntValue());
addLowerMultiExitDisc(dataContBuilder);
addAsPath(dataContBuilder, SEQ_SEGMENT2);
- assertEquals(1L, (long) processedPath.getState().getPeerAs());
+ assertEquals(1L, processedPath.getState().getPeerAs());
assertEquals(3, processedPath.getState().getAsPathLength());
this.selector.processPath(ROUTER_ID2, dataContBuilder.build());
processedPath = this.selector.result();
- assertEquals(1L, (long) processedPath.getState().getPeerAs());
+ assertEquals(1L, processedPath.getState().getPeerAs());
assertEquals(3, processedPath.getState().getAsPathLength());
}
assertNotEquals(this.originBestPath.getState().getAsPathLength(), processedPath.getState().getAsPathLength());
}
- private static ContainerNode createStateFromPrefMedOrigin() {
- DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> dataContBuilder
- = createContBuilder(ATTRS_EXTENSION_Q);
- addLowerLocalRef(dataContBuilder);
- addLowerMultiExitDisc(dataContBuilder);
- addIgpOrigin(dataContBuilder);
- return dataContBuilder.build();
- }
-
- static DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> createStateFromPrefMedOriginASPath() {
- DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> dataContBuilder
- = createContBuilder(ATTRS_EXTENSION_Q);
- addHigherLocalRef(dataContBuilder);
- addHigherMultiExitDisc(dataContBuilder);
- addEgpOrigin(dataContBuilder);
- addAsPath(dataContBuilder,SEQ_SEGMENT);
- return dataContBuilder;
- }
-
- private static void addLowerLocalRef(
- final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> dataContBuilder) {
- dataContBuilder.addChild(createContBuilder(LOCAL_PREF_Q_NAME)
- .addChild(createValueBuilder(123L, LOCAL_PREF_Q_NAME, "pref").build()).build());
- }
-
- private static void addHigherLocalRef(
- final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> dataContBuilder) {
- dataContBuilder.addChild(createContBuilder(LOCAL_PREF_Q_NAME)
- .addChild(createValueBuilder(321L, LOCAL_PREF_Q_NAME, "pref").build()).build());
- }
-
- private static void addLowerMultiExitDisc(
- final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> dataContBuilder) {
- dataContBuilder.addChild(createContBuilder(MULTI_EXIT_DISC_Q_NAME)
- .addChild(createValueBuilder(1234L, MULTI_EXIT_DISC_Q_NAME, "med").build()).build());
- }
-
- private static void addHigherMultiExitDisc(
- final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> dataContBuilder) {
- dataContBuilder.addChild(createContBuilder(MULTI_EXIT_DISC_Q_NAME)
- .addChild(createValueBuilder(4321L, MULTI_EXIT_DISC_Q_NAME, "med").build()).build());
- }
-
- private static void addIgpOrigin(
- final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> dataContBuilder) {
- dataContBuilder.addChild(createContBuilder(ORIGIN_Q_NAME)
- .addChild(createValueBuilder("igp", ORIGIN_Q_NAME, "value").build()).build());
- }
-
- private static void addEgpOrigin(
- final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> dataContBuilder) {
- dataContBuilder.addChild(createContBuilder(ORIGIN_Q_NAME)
- .addChild(createValueBuilder("egp", ORIGIN_Q_NAME, "value").build()).build());
- }
-
- private static void addAsPath(final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> dataContBuilder,
- final UnkeyedListEntryNode segment) {
- final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> asPathContBuilder
- = ImmutableContainerNodeSchemaAwareBuilder.create();
- asPathContBuilder.withNodeIdentifier(new NodeIdentifier(AS_PATH_Q_NAME));
-
- final CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode> segments
- = ImmutableUnkeyedListNodeBuilder.create();
- segments.withNodeIdentifier(SEGMENTS_NID);
- segments.addChild(segment);
- asPathContBuilder.addChild(segments.build());
- dataContBuilder.addChild(asPathContBuilder.build());
- }
-
-
- private static DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> createContBuilder(final QName qname) {
- return ImmutableContainerNodeSchemaAwareBuilder.create().withNodeIdentifier(new NodeIdentifier(qname));
- }
-
- private static <T> ImmutableLeafNodeBuilder<T> createValueBuilder(final T value, final QName qname,
- final String localName) {
- final ImmutableLeafNodeBuilder<T> valueBuilder = new ImmutableLeafNodeBuilder<>();
- valueBuilder.withNodeIdentifier(new NodeIdentifier(QName.create(qname, localName))).withValue(value);
- return valueBuilder;
- }
-
@Test
- public void testExtractSegments() {
- // to be extracted from
- final CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode> builder = Builders.unkeyedListBuilder();
- builder.withNodeIdentifier(SEGMENTS_NID);
- builder.addChild(SET_SEGMENT);
- builder.addChild(SEQ_SEGMENT);
-
- // expected
- final List<AsNumber> sequences = new ArrayList<>();
- sequences.add(new AsNumber(1L));
- sequences.add(new AsNumber(2L));
- sequences.add(new AsNumber(3L));
- final List<Segments> expected = new ArrayList<>();
- expected.add(new SegmentsBuilder()
- .setAsSet(Lists.newArrayList(new AsNumber(11L), new AsNumber(10L))).build());
- expected.add(new SegmentsBuilder().setAsSequence(sequences).build());
- // test
- final List<Segments> actual = this.state.extractSegments(builder.build());
- assertEquals(expected.size(), actual.size());
- assertEquals(Sets.newHashSet(1, 2, 3), Sets.newHashSet(1, 3, 2));
- assertEquals(Sets.newHashSet(expected.get(0).getAsSet()), Sets.newHashSet(actual.get(0).getAsSet()));
- assertEquals(expected.get(1), actual.get(1));
- }
-
- @Test(expected = IllegalArgumentException.class)
public void testBgpOrigin() {
- DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> dataContBuilder
- = createContBuilder(ATTRS_EXTENSION_Q);
- final ContainerNode containerIncom = dataContBuilder.addChild(createContBuilder(ORIGIN_Q_NAME)
- .addChild(createValueBuilder("incomplete", ORIGIN_Q_NAME, "value")
- .build()).build()).build();
- this.selector.processPath(ROUTER_ID3, containerIncom);
+ this.selector.processPath(ROUTER_ID3, new AttributesBuilder().setOrigin(new OriginBuilder()
+ .setValue(BgpOrigin.Incomplete).build()).build());
final BaseBestPath processedPathIncom = this.selector.result();
assertEquals(BgpOrigin.Incomplete, processedPathIncom.getState().getOrigin());
-
- final ContainerNode containerException = dataContBuilder.addChild(createContBuilder(ORIGIN_Q_NAME)
- .addChild(createValueBuilder("LOL", ORIGIN_Q_NAME, "value").build()).build()).build();
- this.selector.processPath(ROUTER_ID3, containerException);
- final BaseBestPath processedPathException = this.selector.result();
- processedPathException.getState().getOrigin();
}
}
+++ /dev/null
-/*
- * Copyright (c) 2016 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.mode.impl.base;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.mockito.Mockito.doReturn;
-
-import java.util.Map;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.protocol.bgp.mode.impl.AbstractRouteEntryTest;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-public class BaseRouteEntryTest extends AbstractRouteEntryTest {
-
- private SimpleRouteEntry testBARE;
-
- @Before
- public void setUp() {
- super.setUp();
- }
-
- @Test
- public void testBaseSimpleRouteEntry() throws Exception {
- this.testBARE = new SimpleRouteEntry(this.peerTracker);
- testWriteEmptyBestPath();
- testAddRouteSelectBestAndWriteOnDS();
- testRewriteSameRoute();
- testInitializePeerWithExistentRoute();
- testRemoveRoute();
- }
-
- private void testRemoveRoute() {
- Map<YangInstanceIdentifier, Long> yiiCount = collectInfo();
- assertEquals(8, yiiCount.size());
- assertEquals(1, (long) yiiCount.get(this.routePaYii));
- this.testBARE.removeRoute(ROUTER_ID, REMOTE_PATH_ID);
- this.testBARE.selectBest(AS);
- this.testBARE.updateBestPaths(this.entryDep, ROUTE_ID_PA, this.tx);
- yiiCount = collectInfo();
- assertFalse(yiiCount.containsKey(this.routePaYii));
- assertFalse(yiiCount.containsKey(this.routeAddRiboutAttYii));
- }
-
- private void testInitializePeerWithExistentRoute() {
- doReturn(ROUTE_ID_PA).when(this.entryInfo).getRouteId();
- this.testBARE.initializeBestPaths(this.entryDep, this.entryInfo, this.peg, this.tx);
- assertEquals(8, this.yiichanges.size());
- Map<YangInstanceIdentifier, Long> yiiCount = collectInfo();
- assertEquals(1, (long) yiiCount.get(this.routeRiboutYiiPeer2));
- assertEquals(1, (long) yiiCount.get(this.routeRiboutAttYiiPeer2));
- }
-
- private void testRewriteSameRoute() {
- this.testBARE.addRoute(ROUTER_ID, REMOTE_PATH_ID, this.ribSupport.routeAttributesIdentifier(), this.attributes);
- assertEquals(1, this.testBARE.getOffsets().size());
- assertFalse(this.testBARE.selectBest(AS));
- }
-
- private void testAddRouteSelectBestAndWriteOnDS() {
- this.testBARE.addRoute(ROUTER_ID, REMOTE_PATH_ID, this.ribSupport.routeAttributesIdentifier(), this.attributes);
- assertFalse(this.testBARE.getOffsets().isEmpty());
- this.testBARE.selectBest(AS);
- this.testBARE.updateBestPaths(this.entryDep, ROUTE_ID_PA, this.tx);
- Map<YangInstanceIdentifier, Long> yiiCount = collectInfo();
- assertEquals(3, yiiCount.size());
- assertEquals(1, (long) yiiCount.get(this.routePaYii));
- assertEquals(1, (long) yiiCount.get(this.routeRiboutYii));
- assertEquals(1, (long) yiiCount.get(this.routeRiboutAttYii));
- this.testBARE.updateBestPaths(this.entryDep, ROUTE_ID_PA_ADD_PATH, this.tx);
- yiiCount = collectInfo();
- assertEquals(6, yiiCount.size());
- assertEquals(1, (long) yiiCount.get(this.routePaAddPathYii));
- assertEquals(1, (long) yiiCount.get(this.routeAddRiboutYii));
- assertEquals(1, (long) yiiCount.get(this.routeAddRiboutAttYii));
- }
-
- private void testWriteEmptyBestPath() {
- doReturn(ROUTE_ID_PA).when(this.entryInfo).getRouteId();
- this.testBARE.initializeBestPaths(this.entryDep, this.entryInfo, this.peg, this.tx);
- assertEquals(0, this.yiichanges.size());
- }
-}
</execution>
</executions>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>findbugs-maven-plugin</artifactId>
- <configuration>
- <failOnError>false</failOnError>
- </configuration>
- </plugin>
<!-- Disable offline link detection which breaks the build here -->
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
import static java.util.Objects.requireNonNull;
import com.google.common.base.Verify;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
import com.google.common.net.InetAddresses;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
import org.opendaylight.protocol.bgp.rib.impl.state.BGPPeerStateImpl;
import org.opendaylight.protocol.bgp.rib.impl.state.BGPSessionStateImpl;
-import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.IdentifierUtils;
import org.opendaylight.protocol.bgp.rib.spi.RibSupportUtils;
import org.opendaylight.protocol.bgp.rib.spi.RouterIds;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.rib.Peer;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.rib.PeerKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.rib.peer.AdjRibIn;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.rib.peer.AdjRibOut;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.Tables;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.TablesKey;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
private final byte[] rawIdentifier;
private final String name;
private final YangInstanceIdentifier adjRibsInId;
- private final Ipv4Address ipAddress;
private final RIB rib;
+ private final InstanceIdentifier<AdjRibOut> peerRibOutIId;
private final KeyedInstanceIdentifier<Peer, PeerKey> peerIId;
- private final YangInstanceIdentifier peerYIId;
private DOMTransactionChain chain;
private DOMTransactionChain writerChain;
private EffectiveRibInWriter effectiveRibInWriter;
private ListenerRegistration<ApplicationPeer> registration;
private final Set<NodeIdentifierWithPredicates> supportedTables = new HashSet<>();
private final BGPSessionStateImpl bgpSessionState = new BGPSessionStateImpl();
+ private final LoadingCache<TablesKey, KeyedInstanceIdentifier<Tables, TablesKey>> tablesIId
+ = CacheBuilder.newBuilder()
+ .build(new CacheLoader<TablesKey, KeyedInstanceIdentifier<Tables, TablesKey>>() {
+ @Override
+ public KeyedInstanceIdentifier<Tables, TablesKey> load(final TablesKey tablesKey) {
+ return ApplicationPeer.this.peerRibOutIId.child(Tables.class, tablesKey);
+ }
+ });
private final PeerId peerId;
private AbstractRegistration trackerRegistration;
final RIB targetRib = requireNonNull(rib);
this.rawIdentifier = InetAddresses.forString(ipAddress.getValue()).getAddress();
final NodeIdentifierWithPredicates peerIId = IdentifierUtils.domPeerId(RouterIds.createPeerId(ipAddress));
- this.peerYIId = targetRib.getYangRibId().node(Peer.QNAME).node(peerIId);
- this.adjRibsInId = this.peerYIId.node(AdjRibIn.QNAME).node(Tables.QNAME);
+ this.adjRibsInId = targetRib.getYangRibId().node(Peer.QNAME).node(peerIId)
+ .node(AdjRibIn.QNAME).node(Tables.QNAME);
this.rib = targetRib;
- this.ipAddress = ipAddress;
this.peerId = RouterIds.createPeerId(ipAddress);
this.peerIId = getInstanceIdentifier().child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns
.yang.bgp.rib.rev171207.bgp.rib.rib.Peer.class, new PeerKey(this.peerId));
+ this.peerRibOutIId = this.peerIId.child(AdjRibOut.class);
}
public synchronized void instantiateServiceInstance(final DOMDataTreeChangeService dataTreeChangeService,
final Set<TablesKey> localTables = this.rib.getLocalTablesKeys();
localTables.forEach(tablesKey -> {
- final ExportPolicyPeerTracker exportTracker = this.rib.getExportPolicyPeerTracker(tablesKey);
- if (exportTracker != null) {
- exportTracker.registerPeer(this.peerId, null, this.peerYIId, PeerRole.Internal);
- }
this.supportedTables.add(RibSupportUtils.toYangTablesKey(tablesKey));
});
setAdvertizedGracefulRestartTableTypes(Collections.emptyList());
}
@Override
- public YangInstanceIdentifier getPeerRibInstanceIdentifier() {
- return this.peerYIId;
+ public PeerRole getRole() {
+ return PeerRole.Internal;
}
@Override
- public PeerRole getRole() {
- return PeerRole.Internal;
+ public KeyedInstanceIdentifier<Tables, TablesKey> getRibOutIId(final TablesKey tablesKey) {
+ return this.tablesIId.getUnchecked(tablesKey);
}
@Override
import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Objects;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
import com.google.common.net.InetAddresses;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import org.opendaylight.protocol.bgp.parser.impl.message.update.LocalPreferenceAttributeParser;
import org.opendaylight.protocol.bgp.parser.spi.MessageUtil;
import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
-import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContext;
import org.opendaylight.protocol.bgp.rib.impl.state.BGPPeerStateImpl;
import org.opendaylight.protocol.bgp.rib.impl.state.BGPSessionStateProvider;
import org.opendaylight.protocol.bgp.rib.spi.BGPSession;
import org.opendaylight.protocol.bgp.rib.spi.BGPSessionListener;
import org.opendaylight.protocol.bgp.rib.spi.BGPTerminationReason;
-import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
-import org.opendaylight.protocol.bgp.rib.spi.IdentifierUtils;
import org.opendaylight.protocol.bgp.rib.spi.Peer;
+import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
import org.opendaylight.protocol.bgp.rib.spi.RouterIds;
import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRouteEntryImportParameters;
import org.opendaylight.protocol.bgp.rib.spi.state.BGPAfiSafiState;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerRole;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.rib.PeerKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.rib.peer.AdjRibOut;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.Tables;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.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.Ipv4AddressFamily;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.SubsequentAddressFamily;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.Notification;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
BGPSessionListener, Peer, TransactionChainListener {
private static final Logger LOG = LoggerFactory.getLogger(BGPPeer.class);
- @GuardedBy("this")
- private final Set<TablesKey> tables = new HashSet<>();
+ private Set<TablesKey> tables = Collections.emptySet();
private final RIB rib;
private final String name;
private final Map<TablesKey, AdjRibOutListener> adjRibOutListenerSet = new HashMap<>();
private final RpcProviderRegistry rpcRegistry;
private final PeerRole peerRole;
+ private final InstanceIdentifier<AdjRibOut> peerRibOutIId;
private final KeyedInstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib
.rev171207.bgp.rib.rib.Peer, PeerKey> peerIId;
@GuardedBy("this")
private AbstractRegistration trackerRegistration;
- @GuardedBy("this")
- private final Set<AbstractRegistration> tableRegistration = new HashSet<>();
private final PeerId peerId;
- private final YangInstanceIdentifier peerYIId;
+ private final LoadingCache<TablesKey, KeyedInstanceIdentifier<Tables, TablesKey>> tablesIId
+ = CacheBuilder.newBuilder()
+ .build(new CacheLoader<TablesKey, KeyedInstanceIdentifier<Tables, TablesKey>>() {
+ @Override
+ public KeyedInstanceIdentifier<Tables, TablesKey> load(final TablesKey tablesKey) {
+ return BGPPeer.this.peerRibOutIId.child(Tables.class, tablesKey);
+ }
+ });
+
@GuardedBy("this")
private BGPSession session;
@GuardedBy("this")
this.peerId = RouterIds.createPeerId(neighborAddress);
this.peerIId = getInstanceIdentifier().child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns
.yang.bgp.rib.rev171207.bgp.rib.rib.Peer.class, new PeerKey(this.peerId));
- this.peerYIId = this.rib.getYangRibId().node(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang
- .bgp.rib.rev171207.bgp.rib.rib.Peer.QNAME).node(IdentifierUtils.domPeerId(this.peerId));
+ this.peerRibOutIId = this.peerIId.child(AdjRibOut.class);
this.chain = rib.createPeerDOMChain(this);
}
private static Map<TablesKey, SendReceive> mapTableTypesFamilies(final List<AddressFamilies> addPathTablesType) {
return ImmutableMap.copyOf(addPathTablesType.stream().collect(Collectors.toMap(af -> new TablesKey(af.getAfi(),
- af.getSafi()),
- BgpAddPathTableType::getSendReceive)));
+ af.getSafi()), BgpAddPathTableType::getSendReceive)));
}
public synchronized void instantiateServiceInstance() {
LOG.info("Session with peer {} went up with tables {} and Add Path tables {}", this.name,
advertizedTableTypes, addPathTablesType);
this.rawIdentifier = InetAddresses.forString(session.getBgpId().getValue()).getAddress();
- this.tables.addAll(advertizedTableTypes.stream().map(t -> new TablesKey(t.getAfi(), t.getSafi()))
- .collect(Collectors.toList()));
+ final Set<TablesKey> setTables = advertizedTableTypes.stream().map(t -> new TablesKey(t.getAfi(), t.getSafi()))
+ .collect(Collectors.toSet());
+ this.tables = ImmutableSet.copyOf(setTables);
setAdvertizedGracefulRestartTableTypes(advertizedGracefulRestartTableTypes.stream()
.map(t -> new TablesKey(t.getAfi(), t.getSafi())).collect(Collectors.toList()));
- this.addPathTableMaps = mapTableTypesFamilies(addPathTablesType);
+ this.addPathTableMaps = ImmutableMap.copyOf(mapTableTypesFamilies(addPathTablesType));
+ this.trackerRegistration = this.rib.getPeerTracker().registerPeer(this);
for (final TablesKey key : this.tables) {
createAdjRibOutListener(key, true);
}
- for(final TablesKey tablesKey :this.tables) {
- final ExportPolicyPeerTracker exportTracker = this.rib.getExportPolicyPeerTracker(tablesKey);
- if (exportTracker != null) {
- this.tableRegistration.add(exportTracker.registerPeer(this.peerId, this.addPathTableMaps.get(tablesKey),
- this.peerYIId, this.peerRole));
- }
- }
addBgp4Support();
this.effRibInWriter = EffectiveRibInWriter.create(this, this.rib, this.rib.createPeerChain(this),
this.peerIId, this.tables);
+
+
registerPrefixesCounters(this.effRibInWriter, this.effRibInWriter);
this.ribWriter = this.ribWriter.transform(this.peerId, this.rib.getRibSupportContext(), this.tables,
this.addPathTableMaps);
.rib.Peer.class, new PeerKey(this.peerId));
this.rpcRegistration.registerPath(PeerContext.class, path);
}
- this.trackerRegistration = this.rib.getPeerTracker().registerPeer(this);
}
//try to add a support for old-school BGP-4, if peer did not advertise IPv4-Unicast MP capability
- private void addBgp4Support() {
+ private synchronized void addBgp4Support() {
final TablesKey key = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
- if (this.tables.add(key)) {
+ if (!this.tables.contains(key)) {
+ final HashSet<TablesKey> newSet = new HashSet<>(this.tables);
+ newSet.add(key);
+ this.tables = ImmutableSet.copyOf(newSet);
createAdjRibOutListener(key, false);
- final ExportPolicyPeerTracker exportTracker = this.rib.getExportPolicyPeerTracker(key);
- if (exportTracker != null) {
- this.tableRegistration.add(exportTracker.registerPeer(peerId, null, this.peerYIId,
- this.peerRole));
- }
}
}
private synchronized void createAdjRibOutListener(final TablesKey key,
final boolean mpSupport) {
- final RIBSupportContext context = this.rib.getRibSupportContext().getRIBSupportContext(key);
+ final RIBSupport ribSupport = this.rib.getRibSupportContext().getRIBSupport(key);
// not particularly nice
- if (context != null && this.session instanceof BGPSessionImpl) {
+ if (ribSupport != null && this.session instanceof BGPSessionImpl) {
final ChannelOutputLimiter limiter = ((BGPSessionImpl) this.session).getLimiter();
final AdjRibOutListener adjRibOut = AdjRibOutListener.create(this.peerId, key,
- this.rib.getYangRibId(), this.rib.getCodecsRegistry(), context.getRibSupport(),
+ this.rib.getYangRibId(), this.rib.getCodecsRegistry(), ribSupport,
this.rib.getService(), limiter, mpSupport);
this.adjRibOutListenerSet.put(key, adjRibOut);
registerPrefixesSentCounter(key, adjRibOut);
if (this.effRibInWriter != null) {
this.effRibInWriter.close();
}
- this.tables.clear();
+ this.tables = Collections.emptySet();
+ this.addPathTableMaps = Collections.emptyMap();
if (this.ribWriter != null) {
return this.ribWriter.removePeer();
}
}
@Override
- public void onSessionDown(final BGPSession session, final Exception e) {
+ public synchronized void onSessionDown(final BGPSession session, final Exception e) {
if (e.getMessage().equals(BGPSessionImpl.END_OF_INPUT)) {
LOG.info("Session with peer {} went down", this.name);
} else {
}
@Override
- public void onSessionTerminated(final BGPSession session, final BGPTerminationReason cause) {
+ public synchronized void onSessionTerminated(final BGPSession session, final BGPTerminationReason cause) {
LOG.info("Session with peer {} terminated: {}", this.name, cause);
releaseConnection();
}
}
this.session = null;
}
-
resetState();
return future;
}
private void closeRegistration() {
- this.tableRegistration.iterator().forEachRemaining(AbstractRegistration::close);
- this.tableRegistration.clear();
if (this.trackerRegistration != null) {
this.trackerRegistration.close();
this.trackerRegistration = null;
return this.peerId;
}
+ @SuppressFBWarnings("IS2_INCONSISTENT_SYNC")
@Override
public SendReceive getSupportedAddPathTables(final TablesKey tableKey) {
return this.addPathTableMaps.get(tableKey);
}
@Override
- public YangInstanceIdentifier getPeerRibInstanceIdentifier() {
- return this.peerYIId;
+ public PeerRole getRole() {
+ return this.peerRole;
}
@Override
- public PeerRole getRole() {
- return this.peerRole;
+ public KeyedInstanceIdentifier<Tables, TablesKey> getRibOutIId(final TablesKey tablesKey) {
+ return this.tablesIId.getUnchecked(tablesKey);
}
@Override
final KeyedInstanceIdentifier<Tables, TablesKey> tablePath
= this.effRibTables.child(Tables.class, tk);
final RIBSupport ribSupport = this.registry.getRIBSupport(tk);
-
+ if (ribSupport == null) {
+ break;
+ }
tx.put(LogicalDatastoreType.OPERATIONAL,
tablePath.child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp
.rib.rev171207.rib.tables.Attributes.class), after.getAttributes());
writeRoutes(tx, tableKey, ribSupport, tablePath, routeKey, (Route) routeChanged.getDataAfter());
break;
case DELETE:
- final InstanceIdentifier routeIID = ribSupport.createRouteIId(tablePath, routeKey);
+ final InstanceIdentifier routeIID = ribSupport.createRouteIdentifier(tablePath, routeKey);
tx.delete(LogicalDatastoreType.OPERATIONAL, routeIID);
break;
}
private void writeRoutes(final WriteTransaction tx, final TablesKey tk, final RIBSupport ribSupport,
final KeyedInstanceIdentifier<Tables, TablesKey> tablePath, final Identifier routeKey,
final Route route) {
- final InstanceIdentifier routeIID = ribSupport.createRouteIId(tablePath, routeKey);
+ final InstanceIdentifier routeIID = ribSupport.createRouteIdentifier(tablePath, routeKey);
CountersUtil.increment(this.prefixesReceived.get(tk), tk);
final Optional<Attributes> effAtt = this.ribPolicies
.applyImportPolicies(this.peerImportParameters, route.getAttributes());
final RIBSupport ribSupport = this.registry.getRIBSupport(tableKey);
final Routes routes = newTable.getRoutes();
- if (routes == null) {
+ if (ribSupport == null || routes == null) {
return;
}
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
-import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.LongAdder;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.GuardedBy;
import javax.annotation.concurrent.NotThreadSafe;
+import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
+import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.dom.api.ClusteredDOMDataTreeChangeListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeIdentifier;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
import org.opendaylight.protocol.bgp.mode.api.RouteEntry;
-import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
import org.opendaylight.protocol.bgp.rib.impl.state.rib.TotalPathsCounter;
import org.opendaylight.protocol.bgp.rib.impl.state.rib.TotalPrefixesCounter;
-import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
-import org.opendaylight.protocol.bgp.rib.spi.IdentifierUtils;
-import org.opendaylight.protocol.bgp.rib.spi.PeerExportGroup;
+import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
-import org.opendaylight.protocol.bgp.rib.spi.RibSupportUtils;
import org.opendaylight.protocol.bgp.rib.spi.RouterIds;
+import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRibRoutingPolicy;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerRole;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.Route;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.Rib;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.RibKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.rib.LocRib;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.rib.Peer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.rib.PeerKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.rib.peer.EffectiveRibIn;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.Tables;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.TablesKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.tables.Attributes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.tables.Routes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.tables.AttributesBuilder;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.Identifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@NotThreadSafe
final class LocRibWriter implements AutoCloseable, TotalPrefixesCounter, TotalPathsCounter,
- ClusteredDOMDataTreeChangeListener {
+ ClusteredDataTreeChangeListener<Tables> {
private static final Logger LOG = LoggerFactory.getLogger(LocRibWriter.class);
- private static final LeafNode<Boolean> ATTRIBUTES_UPTODATE_TRUE = ImmutableNodes
- .leafNode(QName.create(Attributes.QNAME, "uptodate"), Boolean.TRUE);
-
- private final Map<NodeIdentifierWithPredicates, RouteEntry> routeEntries = new HashMap<>();
- private final YangInstanceIdentifier locRibTarget;
- private final NodeIdentifierWithPredicates tableKey;
- private final ExportPolicyPeerTracker exportPolicyPeerTracker;
- private final NodeIdentifier attributesIdentifier;
+ private final Map<Identifier, RouteEntry> routeEntries = new HashMap<>();
private final Long ourAs;
private final RIBSupport ribSupport;
- private final YangInstanceIdentifier target;
- private final DOMDataTreeChangeService service;
+ private final DataBroker dataBroker;
private final PathSelectionMode pathSelectionMode;
private final LongAdder totalPathsCounter = new LongAdder();
private final LongAdder totalPrefixesCounter = new LongAdder();
private final RouteEntryDependenciesContainerImpl entryDep;
- private DOMTransactionChain chain;
+ private final BGPPeerTracker peerTracker;
+ private final KeyedInstanceIdentifier<Rib, RibKey> ribIId;
+ private final TablesKey tk;
+ private final KeyedInstanceIdentifier<Tables, TablesKey> locRibTableIID;
+ private BindingTransactionChain chain;
@GuardedBy("this")
private ListenerRegistration<LocRibWriter> reg;
- private LocRibWriter(final RIBSupportContextRegistry registry, final DOMTransactionChain chain,
- final YangInstanceIdentifier target, final Long ourAs, final DOMDataTreeChangeService service,
- final ExportPolicyPeerTracker exportPolicyPeerTracker, final TablesKey tablesKey,
+ private LocRibWriter(final RIBSupport ribSupport,
+ final BindingTransactionChain chain,
+ final KeyedInstanceIdentifier<Rib, RibKey> ribIId,
+ final Long ourAs,
+ final DataBroker dataBroker,
+ final BGPRibRoutingPolicy ribPolicies,
+ final BGPPeerTracker peerTracker,
+ final TablesKey tablesKey,
final PathSelectionMode pathSelectionMode) {
this.chain = requireNonNull(chain);
- this.target = requireNonNull(target);
- this.tableKey = RibSupportUtils.toYangTablesKey(requireNonNull(tablesKey));
- this.locRibTarget = YangInstanceIdentifier.create(target.node(LocRib.QNAME).node(Tables.QNAME)
- .node(this.tableKey).getPathArguments());
+ this.ribIId = requireNonNull(ribIId);
+ this.tk = requireNonNull(tablesKey);
+ this.locRibTableIID = ribIId.child(LocRib.class).child(Tables.class, this.tk);
this.ourAs = requireNonNull(ourAs);
- this.service = requireNonNull(service);
- this.ribSupport = registry.getRIBSupportContext(tablesKey).getRibSupport();
- this.attributesIdentifier = this.ribSupport.routeAttributesIdentifier();
- this.exportPolicyPeerTracker = exportPolicyPeerTracker;
+ this.dataBroker = requireNonNull(dataBroker);
+ this.ribSupport = requireNonNull(ribSupport);
+ this.peerTracker = peerTracker;
this.pathSelectionMode = pathSelectionMode;
- this.entryDep = new RouteEntryDependenciesContainerImpl(this.ribSupport,
- tablesKey, this.locRibTarget, this.exportPolicyPeerTracker);
+ this.entryDep = new RouteEntryDependenciesContainerImpl(this.ribSupport, ribPolicies,
+ tablesKey, this.locRibTableIID);
init();
}
- private synchronized void init() {
- final DOMDataWriteTransaction tx = this.chain.newWriteOnlyTransaction();
- tx.merge(LogicalDatastoreType.OPERATIONAL, this.locRibTarget.node(Routes.QNAME), this.ribSupport.emptyRoutes());
- tx.merge(LogicalDatastoreType.OPERATIONAL, this.locRibTarget.node(Attributes.QNAME)
- .node(ATTRIBUTES_UPTODATE_TRUE.getNodeType()), ATTRIBUTES_UPTODATE_TRUE);
- tx.submit();
-
- final YangInstanceIdentifier tableId = this.target.node(Peer.QNAME).node(Peer.QNAME).node(EffectiveRibIn.QNAME)
- .node(Tables.QNAME).node(this.tableKey);
- final DOMDataTreeIdentifier wildcard = new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, tableId);
- this.reg = this.service.registerDataTreeChangeListener(wildcard, this);
- }
-
- public static LocRibWriter create(@Nonnull final RIBSupportContextRegistry registry,
+ public static LocRibWriter create(@Nonnull final RIBSupport ribSupport,
@Nonnull final TablesKey tablesKey,
- @Nonnull final DOMTransactionChain chain,
- @Nonnull final YangInstanceIdentifier target,
+ @Nonnull final BindingTransactionChain chain,
+ @Nonnull final KeyedInstanceIdentifier<Rib, RibKey> ribIId,
@Nonnull final AsNumber ourAs,
- @Nonnull final DOMDataTreeChangeService service,
- @Nonnull final ExportPolicyPeerTracker ep,
+ @Nonnull final DataBroker dataBroker,
+ final BGPRibRoutingPolicy ribPolicies,
+ @Nonnull final BGPPeerTracker peerTracker,
@Nonnull final PathSelectionMode pathSelectionStrategy) {
- return new LocRibWriter(registry, chain, target, ourAs.getValue(), service, ep, tablesKey,
- pathSelectionStrategy);
+ return new LocRibWriter(ribSupport, chain, ribIId, ourAs.getValue(), dataBroker, ribPolicies,
+ peerTracker, tablesKey, pathSelectionStrategy);
+ }
+
+ @SuppressWarnings("unchecked")
+ private synchronized void init() {
+ final WriteTransaction tx = this.chain.newWriteOnlyTransaction();
+ tx.merge(LogicalDatastoreType.OPERATIONAL,
+ this.locRibTableIID.builder().child(Attributes.class).build(),
+ new AttributesBuilder().setUptodate(true).build());
+ tx.submit();
+
+ final InstanceIdentifier<Tables> tableId = this.ribIId.builder().child(Peer.class)
+ .child(EffectiveRibIn.class).child(Tables.class, this.tk).build();
+ this.reg = this.dataBroker.registerDataTreeChangeListener(
+ new DataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, tableId), this);
}
/**
*
* @param newChain new transaction chain
*/
- synchronized void restart(@Nonnull final DOMTransactionChain newChain) {
+ synchronized void restart(@Nonnull final BindingTransactionChain newChain) {
requireNonNull(newChain);
close();
this.chain = newChain;
}
@Nonnull
- private RouteEntry createEntry(final NodeIdentifierWithPredicates routeId) {
+ private RouteEntry createEntry(final Identifier routeId) {
final RouteEntry ret = this.pathSelectionMode.createRouteEntry(this.ribSupport.isComplexRoute());
this.routeEntries.put(routeId, ret);
this.totalPrefixesCounter.increment();
* @param changes on supported table
*/
@Override
- public void onDataTreeChanged(final Collection<DataTreeCandidate> changes) {
+ public void onDataTreeChanged(final Collection<DataTreeModification<Tables>> changes) {
LOG.trace("Received data change {} to LocRib {}", changes, this);
- final DOMDataWriteTransaction tx = this.chain.newWriteOnlyTransaction();
+ final WriteTransaction tx = this.chain.newWriteOnlyTransaction();
try {
final Map<RouteUpdateKey, RouteEntry> toUpdate = update(tx, changes);
}
}
- private Map<RouteUpdateKey, RouteEntry> update(final DOMDataWriteTransaction tx,
- final Collection<DataTreeCandidate> changes) {
+ @SuppressWarnings("unchecked")
+ private Map<RouteUpdateKey, RouteEntry> update(final WriteTransaction tx,
+ final Collection<DataTreeModification<Tables>> changes) {
final Map<RouteUpdateKey, RouteEntry> ret = new HashMap<>();
- changes.forEach(tc -> {
- final DataTreeCandidateNode table = tc.getRootNode();
- final YangInstanceIdentifier rootPath = tc.getRootPath();
- final PeerId peerId = IdentifierUtils.peerKeyToPeerId(rootPath);
- initializeTableWithExistentRoutes(table, peerId, rootPath, tx);
- updateNodes(table, peerId, tx, ret);
- });
+ for (final DataTreeModification<Tables> tc : changes) {
+ final DataObjectModification<Tables> table = tc.getRootNode();
+ final DataTreeIdentifier<Tables> rootPath = tc.getRootPath();
+ final KeyedInstanceIdentifier<Peer, PeerKey> peerKIid = (KeyedInstanceIdentifier<Peer, PeerKey>)
+ rootPath.getRootIdentifier().firstIdentifierOf(Peer.class);
+ final UnsignedInteger peerUuid = RouterIds.routerIdForPeerId(peerKIid.getKey().getPeerId());
+ /*
+ Initialize Peer with routes under loc rib
+ */
+ if (!this.routeEntries.isEmpty() && table.getDataBefore() == null) {
+ final org.opendaylight.protocol.bgp.rib.spi.Peer peer
+ = this.peerTracker.getPeer(peerKIid.getKey().getPeerId());
+ if (peer != null && peer.supportsTable(this.entryDep.getLocalTablesKey())) {
+ LOG.debug("Peer {} table has been created, inserting existent routes", peer.getPeerId());
+ this.routeEntries.forEach((key, value) -> value.initializeBestPaths(this.entryDep,
+ new RouteEntryInfoImpl(peer, key), tx));
+ }
+ }
+ /*
+ Process new routes from Peer
+ */
+ updateNodes(table, peerUuid, tx, ret);
+ }
return ret;
}
- private void initializeTableWithExistentRoutes(final DataTreeCandidateNode table, final PeerId peerIdOfNewPeer,
- final YangInstanceIdentifier rootPath, final DOMDataWriteTransaction tx) {
- if (!table.getDataBefore().isPresent() && this.exportPolicyPeerTracker.isTableSupported(peerIdOfNewPeer)) {
- this.exportPolicyPeerTracker.registerPeerAsInitialized(peerIdOfNewPeer);
- LOG.debug("Peer {} table has been created, inserting existent routes", peerIdOfNewPeer);
- if (this.routeEntries.isEmpty()) {
- return;
- }
- final PeerRole newPeerRole = this.exportPolicyPeerTracker.getRole(IdentifierUtils.peerPath(rootPath));
- final PeerExportGroup peerGroup = this.exportPolicyPeerTracker.getPeerGroup(newPeerRole);
- this.routeEntries.forEach((key, value) -> value.initializeBestPaths(this.entryDep,
- new RouteEntryInfoImpl(peerIdOfNewPeer, key, rootPath.getParent().getParent().getParent()),
- peerGroup, tx));
+ @SuppressWarnings("unchecked")
+ private void updateNodes(
+ final DataObjectModification<Tables> table,
+ final UnsignedInteger peerUuid,
+ final WriteTransaction tx,
+ final Map<RouteUpdateKey, RouteEntry> routes
+ ) {
+
+ final DataObjectModification<Attributes> attUpdate = table.getModifiedChildContainer(Attributes.class);
+
+ if (attUpdate != null && attUpdate.getDataAfter() != null) {
+ final Attributes newAttValue = attUpdate.getDataAfter();
+ LOG.trace("Uptodate found for {}", newAttValue);
+ tx.put(LogicalDatastoreType.OPERATIONAL, this.locRibTableIID.child(Attributes.class), newAttValue);
}
- }
- private void updateNodes(final DataTreeCandidateNode table, final PeerId peerId, final DOMDataWriteTransaction tx,
- final Map<RouteUpdateKey, RouteEntry> routes) {
- for (final DataTreeCandidateNode child : table.getChildNodes()) {
- LOG.debug("Modification type {}", child.getModificationType());
- if (Attributes.QNAME.equals(child.getIdentifier().getNodeType())) {
- if (child.getDataAfter().isPresent()) {
- // putting uptodate attribute in
- LOG.trace("Uptodate found for {}", child.getDataAfter());
- tx.put(LogicalDatastoreType.OPERATIONAL, this.locRibTarget.node(child.getIdentifier()),
- child.getDataAfter().get());
- }
- continue;
- }
- updateRoutesEntries(child, peerId, routes);
+ final DataObjectModification routesChangesContainer =
+ table.getModifiedChildContainer(this.ribSupport.routesContainerClass());
+ if (routesChangesContainer == null) {
+ return;
}
+ updateRoutesEntries(routesChangesContainer.getModifiedChildren(), peerUuid, routes);
}
- private void updateRoutesEntries(final DataTreeCandidateNode child, final PeerId peerId,
- final Map<RouteUpdateKey, RouteEntry> routes) {
- final UnsignedInteger routerId = RouterIds.routerIdForPeerId(peerId);
- final Collection<DataTreeCandidateNode> modifiedRoutes = this.ribSupport.changedDOMRoutes(child);
- for (final DataTreeCandidateNode route : modifiedRoutes) {
- final NodeIdentifierWithPredicates routeId = this.ribSupport
- .createRouteKeyPathArgument((NodeIdentifierWithPredicates) route.getIdentifier());
- RouteEntry entry = this.routeEntries.get(routeId);
- final Optional<NormalizedNode<?, ?>> maybeData = route.getDataAfter();
- final Optional<NormalizedNode<?, ?>> maybeDataBefore = route.getDataBefore();
- if (maybeData.isPresent()) {
+ @SuppressWarnings("unchecked")
+ private void updateRoutesEntries(
+ final Collection<DataObjectModification<? extends DataObject>> routeChanges,
+ final UnsignedInteger routerId,
+ final Map<RouteUpdateKey, RouteEntry> routes
+ ) {
+ for (final DataObjectModification<? extends DataObject> route : routeChanges) {
+ final Identifier routeKey = ((InstanceIdentifier.IdentifiableItem) route.getIdentifier()).getKey();
+ RouteEntry entry = this.routeEntries.get(routeKey);
+ final Route newRoute = (Route) route.getDataAfter();
+ final Route oldRoute = (Route) route.getDataBefore();
+ if (newRoute != null) {
if (entry == null) {
- entry = createEntry(routeId);
+ entry = createEntry(routeKey);
}
- entry.addRoute(routerId, this.ribSupport.extractPathId(maybeData.get()),
- this.attributesIdentifier, maybeData.get());
+ final long pathId = this.ribSupport.extractPathId(newRoute);
+ entry.addRoute(routerId, pathId, newRoute);
this.totalPathsCounter.increment();
- } else if (entry != null) {
+ } else if (oldRoute != null && entry != null) {
this.totalPathsCounter.decrement();
- if (entry.removeRoute(routerId, this.ribSupport.extractPathId(maybeDataBefore.get()))) {
- this.routeEntries.remove(routeId);
+ final long pathId = this.ribSupport.extractPathId(oldRoute);
+ if (entry.removeRoute(routerId, pathId)) {
+ this.routeEntries.remove(routeKey);
this.totalPrefixesCounter.decrement();
LOG.trace("Removed route from {}", routerId);
}
}
- final RouteUpdateKey routeUpdateKey = new RouteUpdateKey(peerId, routeId);
- LOG.debug("Updated route {} entry {}", routeId, entry);
+ final RouteUpdateKey routeUpdateKey = new RouteUpdateKey(routerId, routeKey);
+ LOG.debug("Updated route {} entry {}", routeKey, entry);
routes.put(routeUpdateKey, entry);
}
}
- private void walkThrough(final DOMDataWriteTransaction tx,
+ private void walkThrough(final WriteTransaction tx,
final Set<Map.Entry<RouteUpdateKey, RouteEntry>> toUpdate) {
for (final Map.Entry<RouteUpdateKey, RouteEntry> e : toUpdate) {
LOG.trace("Walking through {}", e);
public long getPathsCount() {
return this.totalPathsCounter.longValue();
}
+
+ public TablesKey getTableKey() {
+ return this.tk;
+ }
}
import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
-import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
import org.opendaylight.protocol.bgp.rib.impl.state.BGPRIBStateImpl;
import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
-import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
+import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
import org.opendaylight.protocol.bgp.rib.spi.RibSupportUtils;
import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRibRoutingPolicy;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
SchemaContextListener, AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(RIBImpl.class);
private static final QName RIB_ID_QNAME = QName.create(Rib.QNAME, "id").intern();
- private static final ContainerNode EMPTY_TABLE_ATTRIBUTES = ImmutableNodes.containerNode(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.tables.Attributes.QNAME);
+ private static final ContainerNode EMPTY_TABLE_ATTRIBUTES = ImmutableNodes.containerNode(org.opendaylight.yang
+ .gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.tables.Attributes.QNAME);
private final BGPDispatcher dispatcher;
private final AsNumber localAs;
private final CodecsRegistryImpl codecsRegistry;
@GuardedBy("this")
private ClusterSingletonServiceRegistration registration;
- private final DOMDataBrokerExtension service;
+ private final DOMDataBrokerExtension domService;
private final Map<TransactionChain<?, ?>, LocRibWriter> txChainToLocRibWriter = new HashMap<>();
private final Map<TablesKey, PathSelectionMode> bestPathSelectionStrategies;
private final RibId ribId;
private final BGPPeerTracker peerTracker;
private final BGPRibRoutingPolicy ribPolicies;
- private final Map<TablesKey, ExportPolicyPeerTracker> exportPolicyPeerTrackerMap;
@GuardedBy("this")
private DOMTransactionChain domChain;
public RIBImpl(final RibId ribId,
final AsNumber localAs,
final BgpId localBgpId,
- final ClusterIdentifier clusterId,
final RIBExtensionConsumerContext extensions,
final BGPDispatcher dispatcher,
final CodecsRegistryImpl codecsRegistry,
this.localTablesKeys = new HashSet<>();
this.domDataBroker = requireNonNull(domDataBroker);
this.dataBroker = requireNonNull(dataBroker);
- this.service = this.domDataBroker.getSupportedExtensions().get(DOMDataTreeChangeService.class);
+ this.domService = this.domDataBroker.getSupportedExtensions().get(DOMDataTreeChangeService.class);
this.extensions = requireNonNull(extensions);
this.ribPolicies = requireNonNull(ribPolicies);
this.peerTracker = requireNonNull(bgpPeerTracker);
final InstanceIdentifierBuilder yangRibIdBuilder = YangInstanceIdentifier.builder().node(BgpRib.QNAME).node(Rib.QNAME);
this.yangRibId = yangRibIdBuilder.nodeWithKey(Rib.QNAME, RIB_ID_QNAME, ribId.getValue()).build();
this.bestPathSelectionStrategies = requireNonNull(bestPathSelectionStrategies);
- final ClusterIdentifier cId = clusterId == null ? new ClusterIdentifier(localBgpId) : clusterId;
this.ribId = ribId;
- final PolicyDatabase policyDatabase = new PolicyDatabase(this.localAs.getValue(), localBgpId, cId);
- final ImmutableMap.Builder<TablesKey, ExportPolicyPeerTracker> exportPolicies = new ImmutableMap.Builder<>();
for (final BgpTableType t : this.localTables) {
final TablesKey key = new TablesKey(t.getAfi(), t.getSafi());
this.localTablesKeys.add(key);
- exportPolicies.put(key, new ExportPolicyPeerTrackerImpl(policyDatabase, key));
}
- this.exportPolicyPeerTrackerMap = exportPolicies.build();
}
private synchronized void startLocRib(final TablesKey key) {
table.withChild(EMPTY_TABLE_ATTRIBUTES);
final NodeIdentifierWithPredicates tableKey = RibSupportUtils.toYangTablesKey(key);
- final InstanceIdentifierBuilder tableId = YangInstanceIdentifier.builder(this.yangRibId.node(LocRib.QNAME).node(Tables.QNAME));
+ final InstanceIdentifierBuilder tableId = YangInstanceIdentifier
+ .builder(this.yangRibId.node(LocRib.QNAME).node(Tables.QNAME));
tableId.nodeWithKey(tableKey.getNodeType(), tableKey.getKeyValues());
for (final Entry<QName, Object> e : tableKey.getKeyValues().entrySet()) {
table.withChild(ImmutableNodes.leafNode(e.getKey(), e.getValue()));
} catch (final TransactionCommitFailedException e1) {
LOG.error("Failed to initiate LocRIB for key {}", key, e1);
}
- createLocRibWriter(key);
} else {
LOG.warn("There's no registered RIB Context for {}", key.getAfi());
}
}
private synchronized void createLocRibWriter(final TablesKey key) {
+ final RIBSupport ribSupport = this.ribContextRegistry.getRIBSupport(key);
+ if (ribSupport == null) {
+ return;
+ }
LOG.debug("Creating LocRIB writer for key {}", key);
- final DOMTransactionChain txChain = createPeerDOMChain(this);
+ final BindingTransactionChain txChain = createPeerChain(this);
PathSelectionMode pathSelectionStrategy = this.bestPathSelectionStrategies.get(key);
if (pathSelectionStrategy == null) {
pathSelectionStrategy = BasePathSelectionModeFactory.createBestPathSelectionStrategy(this.peerTracker);
}
- final LocRibWriter locRibWriter = LocRibWriter.create(this.ribContextRegistry, key, txChain,
- getYangRibId(), this.localAs, getService(), this.exportPolicyPeerTrackerMap.get(key), pathSelectionStrategy);
+ final LocRibWriter locRibWriter = LocRibWriter.create(
+ ribSupport,
+ key,
+ txChain,
+ getInstanceIdentifier(),
+ this.localAs,
+ getDataBroker(),
+ this.ribPolicies,
+ this.peerTracker,
+ pathSelectionStrategy);
registerTotalPathCounter(key, locRibWriter);
registerTotalPrefixesCounter(key, locRibWriter);
this.txChainToLocRibWriter.put(txChain, locRibWriter);
}
@Override
- public synchronized void onTransactionChainFailed(final TransactionChain<?, ?> chain, final AsyncTransaction<?, ?> transaction, final Throwable cause) {
- LOG.error("Broken chain in RIB {} transaction {}", getInstanceIdentifier(), transaction != null ? transaction.getIdentifier() : null, cause);
+ public synchronized void onTransactionChainFailed(final TransactionChain<?, ?> chain,
+ final AsyncTransaction<?, ?> transaction, final Throwable cause) {
+ LOG.error("Broken chain in RIB {} transaction {}",
+ getInstanceIdentifier(), transaction != null ? transaction.getIdentifier() : null, cause);
if (this.txChainToLocRibWriter.containsKey(chain)) {
final LocRibWriter locRibWriter = this.txChainToLocRibWriter.remove(chain);
- final DOMTransactionChain newChain = createPeerDOMChain(this);
+ final BindingTransactionChain newChain = createPeerChain(this);
+ startLocRib(locRibWriter.getTableKey());
locRibWriter.restart(newChain);
this.txChainToLocRibWriter.put(newChain, locRibWriter);
}
@Override
public DOMDataTreeChangeService getService() {
- return (DOMDataTreeChangeService) this.service;
+ return (DOMDataTreeChangeService) this.domService;
}
@Override
}
@Override
- public DOMTransactionChain createPeerDOMChain(final TransactionChainListener listener) {
- return this.domDataBroker.createTransactionChain(listener);
+ public BindingTransactionChain createPeerChain(final TransactionChainListener listener) {
+ return this.dataBroker.createTransactionChain(listener);
}
@Override
- public BindingTransactionChain createPeerChain(final TransactionChainListener listener) {
- return this.dataBroker.createTransactionChain(this);
+ public DOMTransactionChain createPeerDOMChain(final TransactionChainListener listener) {
+ return this.domDataBroker.createTransactionChain(listener);
}
@Override
return this.codecsRegistry;
}
- @Override
- public ExportPolicyPeerTracker getExportPolicyPeerTracker(final TablesKey tablesKey) {
- return this.exportPolicyPeerTrackerMap.get(tablesKey);
- }
-
public synchronized void instantiateServiceInstance() {
this.isServiceInstantiated = true;
setActive(true);
LOG.debug("Effective RIB created.");
this.localTablesKeys.forEach(this::startLocRib);
+ this.localTablesKeys.forEach(this::createLocRibWriter);
}
public synchronized ListenableFuture<Void> closeServiceInstance() {
import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.TablesKey;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
final class RIBSupportContextRegistryImpl implements RIBSupportContextRegistry {
+ private final RIBExtensionConsumerContext extensionContext;
+ private final CodecsRegistry codecs;
private final LoadingCache<RIBSupport, RIBSupportContextImpl> contexts = CacheBuilder.newBuilder()
- .build(new CacheLoader<RIBSupport, RIBSupportContextImpl>(){
+ .build(new CacheLoader<RIBSupport, RIBSupportContextImpl>() {
@Override
public RIBSupportContextImpl load(final RIBSupport key) {
return createRIBSupportContext(key);
}
});
- private final RIBExtensionConsumerContext extensionContext;
- private final CodecsRegistry codecs;
-
private RIBSupportContextRegistryImpl(final RIBExtensionConsumerContext extensions, final CodecsRegistry codecs) {
this.extensionContext = requireNonNull(extensions);
this.codecs = requireNonNull(codecs);
}
return null;
}
-
- @Override
- public RIBSupportContext getRIBSupportContext(final NodeIdentifierWithPredicates key) {
- final RIBSupport ribSupport = this.extensionContext.getRIBSupport(key);
- if (ribSupport != null) {
- return this.contexts.getUnchecked(ribSupport);
- }
- return null;
- }
}
import static java.util.Objects.requireNonNull;
-import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
import org.opendaylight.protocol.bgp.rib.spi.entry.RouteEntryDependenciesContainer;
import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRibRoutingPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.Tables;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.TablesKey;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
public final class RouteEntryDependenciesContainerImpl implements RouteEntryDependenciesContainer {
private final RIBSupport ribSupport;
private final TablesKey tablesKey;
- private final YangInstanceIdentifier locRibTarget;
- private final ExportPolicyPeerTracker exportPolicyPeerTracker;
+ private final KeyedInstanceIdentifier<Tables, TablesKey> locRibTarget;
+ private final BGPRibRoutingPolicy routingPolicies;
public RouteEntryDependenciesContainerImpl(
final RIBSupport ribSupport,
+ final BGPRibRoutingPolicy routingPolicies,
final TablesKey tablesKey,
- final YangInstanceIdentifier locRibTarget,
- final ExportPolicyPeerTracker exportPolicyPeerTracker) {
+ final KeyedInstanceIdentifier<Tables, TablesKey> locRibTarget) {
this.ribSupport = requireNonNull(ribSupport);
this.tablesKey = requireNonNull(tablesKey);
+ this.routingPolicies = requireNonNull(routingPolicies);
this.locRibTarget = requireNonNull(locRibTarget);
- this.exportPolicyPeerTracker = requireNonNull(exportPolicyPeerTracker);
}
@Override
}
@Override
- public YangInstanceIdentifier getLocRibTableTarget() {
+ public KeyedInstanceIdentifier<Tables, TablesKey> getLocRibTableTarget() {
return this.locRibTarget;
}
- @Override
- public ExportPolicyPeerTracker getExportPolicyPeerTracker() {
- return exportPolicyPeerTracker;
- }
-
@Override
public BGPRibRoutingPolicy getRoutingPolicies() {
- //FIXME
- return null;
+ return this.routingPolicies;
}
}
import static java.util.Objects.requireNonNull;
-import javax.annotation.Nonnull;
+import org.opendaylight.protocol.bgp.rib.spi.Peer;
import org.opendaylight.protocol.bgp.rib.spi.entry.RouteEntryInfo;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerId;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.binding.Identifier;
-public final class RouteEntryInfoImpl implements RouteEntryInfo {
- private final PeerId peerId;
- private final NodeIdentifierWithPredicates key;
- private final YangInstanceIdentifier rootPath;
+public final class RouteEntryInfoImpl<N extends Identifier> implements RouteEntryInfo<N> {
+ private final Peer peer;
+ private final N key;
- public RouteEntryInfoImpl(final PeerId peerId, final NodeIdentifierWithPredicates key,
- final YangInstanceIdentifier rootPath) {
- this.peerId = requireNonNull(peerId);
+ public RouteEntryInfoImpl(final Peer peer, final N key) {
+ this.peer = requireNonNull(peer);
this.key = requireNonNull(key);
- this.rootPath = requireNonNull(rootPath);
}
- @Nonnull
@Override
- public PeerId getToPeerId() {
- return this.peerId;
+ public Peer getToPeer() {
+ return this.peer;
}
- @Nonnull
@Override
- public NodeIdentifierWithPredicates getRouteId() {
+ public N getRouteKey() {
return this.key;
}
-
- @Nonnull
- @Override
- public YangInstanceIdentifier getRootPath() {
- return this.rootPath;
- }
}
import static java.util.Objects.requireNonNull;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerId;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import com.google.common.primitives.UnsignedInteger;
+import org.opendaylight.yangtools.yang.binding.Identifier;
/**
* Combined key formed as a concatenation of source peer and route identifiers.
* This is used to internally track updates which need to be processed.
*/
final class RouteUpdateKey {
- private final PeerId peerId;
- private final NodeIdentifierWithPredicates routeId;
+ private final UnsignedInteger peerId;
+ private final Identifier routeId;
- RouteUpdateKey(final PeerId peerId, final NodeIdentifierWithPredicates routeId) {
+ RouteUpdateKey(final UnsignedInteger peerId, final Identifier routeKey) {
this.peerId = requireNonNull(peerId);
- this.routeId = requireNonNull(routeId);
+ this.routeId = requireNonNull(routeKey);
}
- PeerId getPeerId() {
+ UnsignedInteger getPeerId() {
return this.peerId;
}
- NodeIdentifierWithPredicates getRouteId() {
+ Identifier getRouteId() {
return this.routeId;
}
import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
-import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRibRoutingPolicy;
import org.opendaylight.protocol.bgp.rib.spi.state.BGPRIBState;
}
@Override
- public BindingTransactionChain createPeerChain(final TransactionChainListener listener) {
- return this.ribImpl.createPeerChain(listener);
+ public DOMTransactionChain createPeerDOMChain(final TransactionChainListener listener) {
+ return this.ribImpl.createPeerDOMChain(listener);
}
@Override
- public DOMTransactionChain createPeerDOMChain(final TransactionChainListener listener) {
- return this.ribImpl.createPeerDOMChain(listener);
+ public BindingTransactionChain createPeerChain(final TransactionChainListener listener) {
+ return this.ribImpl.createPeerChain(listener);
}
@Override
this.serviceRegistration = serviceRegistration;
}
- @Override
- public ExportPolicyPeerTracker getExportPolicyPeerTracker(final TablesKey tablesKey) {
- return this.ribImpl.getExportPolicyPeerTracker(tablesKey);
- }
-
@Override
public Set<TablesKey> getLocalTablesKeys() {
return this.ribImpl.getLocalTablesKeys();
new RibId(bgpInstanceName),
this.asNumber,
new BgpId(this.routerId),
- this.clusterId,
this.extensions,
this.dispatcher,
codecsRegistry,
import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
import org.opendaylight.protocol.bgp.rib.RibReference;
import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
-import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRibRoutingPolicy;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
DOMDataTreeChangeService getService();
/**
- * Returns ExportPolicyPeerTracker for specific tableKey, where peer can register himself
- * as supporting the table. Same export policy can be used to check which peers support respective
- * table and announce then routes if required.
+ * Return DataBroker.
*
- * @param tablesKey supported table
- * @return ExportPolicyPeerTracker
- */
- ExportPolicyPeerTracker getExportPolicyPeerTracker(TablesKey tablesKey);
-
- /**
- * Return DataBroker
- *
- * @return DataTreeChangeService
+ * @return DataBroker
*/
DataBroker getDataBroker();
import javax.annotation.Nullable;
import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.TablesKey;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
public interface RIBSupportContextRegistry {
*/
@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.
- */
- @Nullable
- RIBSupportContext getRIBSupportContext(NodeIdentifierWithPredicates key);
}
protected static final Class<? extends SubsequentAddressFamily> SAFI = UnicastSubsequentAddressFamily.class;
protected static final TablesKey KEY = new TablesKey(AFI, SAFI);
protected static final QName PREFIX_QNAME = QName.create(Ipv4Route.QNAME, "prefix").intern();
- private static final ClusterIdentifier CLUSTER_ID = new ClusterIdentifier("128.0.0.1");
private static final BgpId RIB_ID = new BgpId("127.0.0.1");
private RIBImpl rib;
private BindingCodecTreeFactory codecFactory;
mockedMethods();
doReturn(mock(ClusterSingletonServiceRegistration.class)).when(this.clusterSingletonServiceProvider)
.registerClusterSingletonService(any(ClusterSingletonService.class));
- this.rib = new RIBImpl(new RibId("test"), new AsNumber(5L), RIB_ID, CLUSTER_ID, context,
- this.dispatcher, codecsRegistry, this.dom, getDataBroker(), this.policies, this.peerTracker, localTables,
- Collections.singletonMap(new TablesKey(AFI, SAFI),
- BasePathSelectionModeFactory.createBestPathSelectionStrategy(this.peerTracker)));
+ this.rib = new RIBImpl(new RibId("test"), new AsNumber(5L), RIB_ID, context,
+ this.dispatcher, codecsRegistry, this.dom, getDataBroker(), this.policies, this.peerTracker,
+ localTables, Collections.singletonMap(new TablesKey(AFI, SAFI),
+ BasePathSelectionModeFactory.createBestPathSelectionStrategy(this.peerTracker)));
this.rib.onGlobalContextUpdated(schemaContext);
- this.ribSupport = getRib().getRibSupportContext().getRIBSupportContext(KEY).getRibSupport();
+ this.ribSupport = getRib().getRibSupportContext().getRIBSupport(KEY);
}
@SuppressWarnings("unchecked")
final Map<TablesKey, PathSelectionMode> pathTables
= ImmutableMap.of(TABLES_KEY, new AllPathSelection(this.peerTracker));
- this.ribImpl = new RIBImpl(new RibId("test-rib"), AS_NUMBER, BGP_ID, null,
+ this.ribImpl = new RIBImpl(new RibId("test-rib"), AS_NUMBER, BGP_ID,
this.ribExtension, this.serverDispatcher, this.codecsRegistry,
getDomBroker(), getDataBroker(), this.policies, this.peerTracker, TABLES_TYPE, pathTables);
final Map<TablesKey, PathSelectionMode> pathTables = ImmutableMap.of(tk,
BasePathSelectionModeFactory.createBestPathSelectionStrategy(this.peerTracker));
- this.ribImpl = new RIBImpl(new RibId("test-rib"),
- AS_NUMBER, new BgpId(RIB_ID), null, this.ribExtension, this.serverDispatcher,
- this.codecsRegistry, getDomBroker(), getDataBroker(), this.policies, this.peerTracker, TABLES_TYPE, pathTables);
+ this.ribImpl = new RIBImpl(new RibId("test-rib"), AS_NUMBER, new BgpId(RIB_ID), this.ribExtension,
+ this.serverDispatcher, this.codecsRegistry, getDomBroker(), getDataBroker(), this.policies,
+ this.peerTracker, TABLES_TYPE, pathTables);
this.ribImpl.instantiateServiceInstance();
this.ribImpl.onGlobalContextUpdated(this.schemaContext);
final ChannelFuture channelFuture = this.serverDispatcher.createServer(new InetSocketAddress(RIB_ID, PORT));
final Map<TablesKey, PathSelectionMode> pathTables = ImmutableMap.of(tk,
new AddPathBestNPathSelection(2L, this.peerTracker));
- this.ribImpl = new RIBImpl(new RibId("test-rib"),
- AS_NUMBER, new BgpId(RIB_ID), null, this.ribExtension, this.serverDispatcher,
- this.codecsRegistry, getDomBroker(), getDataBroker(), this.policies, this.peerTracker, TABLES_TYPE, pathTables);
+ this.ribImpl = new RIBImpl(new RibId("test-rib"), AS_NUMBER, new BgpId(RIB_ID), this.ribExtension,
+ this.serverDispatcher, this.codecsRegistry, getDomBroker(), getDataBroker(), this.policies,
+ this.peerTracker, TABLES_TYPE, pathTables);
this.ribImpl.instantiateServiceInstance();
this.ribImpl.onGlobalContextUpdated(this.schemaContext);
final List<BgpTableType> tables = ImmutableList.of(new BgpTableTypeImpl(LinkstateAddressFamily.class,
LinkstateSubsequentAddressFamily.class));
- final RIBImpl rib = new RIBImpl(new RibId(TEST_RIB_ID),
- AS_NUMBER, new BgpId("127.0.0.1"), null, this.ext2, this.dispatcher,
+ final RIBImpl rib = new RIBImpl(new RibId(TEST_RIB_ID), AS_NUMBER, BGP_ID, this.ext2, this.dispatcher,
this.codecsRegistry, getDomBroker(), getDataBroker(), this.policies, this.peerTracker, tables,
Collections.singletonMap(TABLE_KEY, BasePathSelectionModeFactory
.createBestPathSelectionStrategy(this.peerTracker)));
public void testWithoutLinkstate() throws ReadFailedException {
final List<BgpTableType> tables = ImmutableList.of(new BgpTableTypeImpl(Ipv4AddressFamily.class,
UnicastSubsequentAddressFamily.class));
- final RIBImpl rib = new RIBImpl(new RibId(TEST_RIB_ID), AS_NUMBER, BGP_ID,
- null, this.ext1, this.dispatcher, this.codecsRegistry, getDomBroker(), getDataBroker(),
- this.policies, this.peerTracker, tables,
+ final RIBImpl rib = new RIBImpl(new RibId(TEST_RIB_ID), AS_NUMBER, BGP_ID, this.ext1, this.dispatcher,
+ this.codecsRegistry, getDomBroker(), getDataBroker(), this.policies, this.peerTracker, tables,
Collections.singletonMap(TABLE_KEY, BasePathSelectionModeFactory
.createBestPathSelectionStrategy(this.peerTracker)));
rib.instantiateServiceInstance();
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import static org.opendaylight.protocol.bgp.rib.impl.AdjRibInWriter.PEER_ID_QNAME;
-import com.google.common.collect.ImmutableMap;
+import com.google.common.primitives.UnsignedInteger;
import org.junit.Test;
+import org.opendaylight.protocol.bgp.rib.spi.RouterIds;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev171207.ipv4.routes.ipv4.routes.Ipv4RouteKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.PathId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.rib.Peer;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
public class RouteUpdateKeyTest {
- private static final PeerId PEER_ID = new PeerId("127.0.0.1");
- private static final PeerId PEER_ID_2 = new PeerId("127.0.0.2");
- private static final NodeIdentifierWithPredicates NIWP_PEER = new NodeIdentifierWithPredicates(Peer.QNAME,
- ImmutableMap.of(PEER_ID_QNAME, PEER_ID.getValue()));
+ private static final UnsignedInteger PEER_ID = RouterIds.routerIdForPeerId(new PeerId("bgp://127.0.0.1"));
+ private static final UnsignedInteger PEER_ID_2 = RouterIds.routerIdForPeerId(new PeerId("bgp://127.0.0.2"));
+ private static final Ipv4RouteKey NIWP_PEER = new Ipv4RouteKey(new PathId(1L),
+ new Ipv4Prefix("0.0.0.0/0"));
+ private static final Ipv4RouteKey NIWP_PEER2 = new Ipv4RouteKey(new PathId(1L),
+ new Ipv4Prefix("1.1.1.1/24"));
@Test
public void testRouteUpdateKey() {
assertTrue(rk.equals(rk));
assertFalse(rk.equals(null));
assertFalse(rk.equals(new RouteUpdateKey(PEER_ID_2, NIWP_PEER)));
- assertFalse(rk.equals(new RouteUpdateKey(PEER_ID, new NodeIdentifierWithPredicates(Peer.QNAME,
- ImmutableMap.of(PEER_ID_QNAME, PEER_ID_2.getValue())))));
+ assertFalse(rk.equals(new RouteUpdateKey(PEER_ID_2, NIWP_PEER2)));
}
-
}
\ No newline at end of file
public void testHandleMessageAfterException() {
final Map<TablesKey, PathSelectionMode> pathTables = ImmutableMap.of(TABLES_KEY,
BasePathSelectionModeFactory.createBestPathSelectionStrategy(this.peerTracker));
- final RIBImpl ribImpl = new RIBImpl( new RibId(RIB_ID), AS_NUMBER,
- new BgpId(RIB_ID), null, this.ribExtension, this.serverDispatcher, this.codecsRegistry,
- this.domBroker, getDataBroker(), this.policies, this.peerTracker, ImmutableList.of(this.ipv4tt), pathTables);
+ final RIBImpl ribImpl = new RIBImpl( new RibId(RIB_ID), AS_NUMBER, new BgpId(RIB_ID), this.ribExtension,
+ this.serverDispatcher, this.codecsRegistry, this.domBroker, getDataBroker(), this.policies,
+ this.peerTracker, ImmutableList.of(this.ipv4tt), pathTables);
ribImpl.instantiateServiceInstance();
ribImpl.onGlobalContextUpdated(this.schemaContext);
correct.setAttributes(ab.setLocalPref(new LocalPrefBuilder().setPref((long) 100).build()).build());
bgpSession.handleMessage(correct.build());
- verify(this.tx, times(4)).merge(eq(LogicalDatastoreType.OPERATIONAL),
+ verify(this.tx, times(2)).merge(eq(LogicalDatastoreType.OPERATIONAL),
any(YangInstanceIdentifier.class), any(NormalizedNode.class));
bgpSession.handleMessage(wrongMessage.build());
- verify(this.tx, times(4)).merge(eq(LogicalDatastoreType.OPERATIONAL),
+ verify(this.tx, times(2)).merge(eq(LogicalDatastoreType.OPERATIONAL),
any(YangInstanceIdentifier.class), any(NormalizedNode.class));
bgpSession.handleMessage(new UpdateBuilder().build());
- verify(this.tx, times(4)).merge(eq(LogicalDatastoreType.OPERATIONAL),
+ verify(this.tx, times(2)).merge(eq(LogicalDatastoreType.OPERATIONAL),
any(YangInstanceIdentifier.class), any(NormalizedNode.class));
verify(this.tx).delete(eq(LogicalDatastoreType.OPERATIONAL), eq(PEER_PATH));
verify(this.tx, times(0)).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(TABLE_PATH),
@Test
public void testUseCase1() {
final Map<TablesKey, PathSelectionMode> pathTables = ImmutableMap.of(TABLES_KEY,
- BasePathSelectionModeFactory.createBestPathSelectionStrategy(this.peerTracker));
- final RIBImpl ribImpl = new RIBImpl( new RibId(RIB_ID), AS_NUMBER,
- new BgpId(RIB_ID), null, this.ribExtension, this.serverDispatcher, this.codecsRegistry,
- this.domBroker, getDataBroker(), this.policies, this.peerTracker, ImmutableList.of(this.ipv4tt), pathTables);
+ BasePathSelectionModeFactory.createBestPathSelectionStrategy(this.peerTracker));
+ final RIBImpl ribImpl = new RIBImpl(new RibId(RIB_ID), AS_NUMBER, new BgpId(RIB_ID), this.ribExtension,
+ this.serverDispatcher, this.codecsRegistry, this.domBroker, getDataBroker(), this.policies,
+ this.peerTracker, ImmutableList.of(this.ipv4tt), pathTables);
ribImpl.instantiateServiceInstance();
ribImpl.onGlobalContextUpdated(this.schemaContext);
correct.setAttributes(ab.setLocalPref(new LocalPrefBuilder().setPref((long) 100).build()).build());
bgpSession.handleMessage(correct.build());
- verify(this.tx, times(4)).merge(eq(LogicalDatastoreType.OPERATIONAL),
+ verify(this.tx, times(2)).merge(eq(LogicalDatastoreType.OPERATIONAL),
any(YangInstanceIdentifier.class), any(NormalizedNode.class));
bgpSession.handleMessage(new UpdateBuilder().build());
- verify(this.tx, times(5)).merge(eq(LogicalDatastoreType.OPERATIONAL),
+ verify(this.tx, times(3)).merge(eq(LogicalDatastoreType.OPERATIONAL),
any(YangInstanceIdentifier.class), any(NormalizedNode.class));
verify(this.tx).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(TABLE_PATH),
private final Class<? extends AddressFamily> afiClass;
private final Class<? extends SubsequentAddressFamily> safiClass;
private final NodeIdentifier destinationNid;
- private final QName routesQname;
- private final NodeIdentifierWithPredicates tableQname;
/**
* Default constructor. Requires the QName of the container augmented under the routes choice
this.containerClass = requireNonNull(containerClass);
this.listClass = requireNonNull(listClass);
this.routeQname = QName.create(qname, BindingReflections.findQName(listClass).intern().getLocalName());
- this.routesQname = QName.create(qname, BindingReflections.findQName(this.containerClass).intern().getLocalName());
this.routesListIdentifier = new NodeIdentifier(this.routeQname);
this.emptyRoutes = Builders.choiceBuilder().withNodeIdentifier(ROUTES).addChild(Builders.containerBuilder()
.withNodeIdentifier(routesContainerIdentifier()).withChild(ImmutableNodes.mapNodeBuilder(this.routeQname)
this.afiClass = afiClass;
this.safiClass = safiClass;
this.destinationNid = new NodeIdentifier(destinationQname);
- this.tableQname = RibSupportUtils.toYangTablesKey(new TablesKey(afiClass, safiClass));
}
@Override
}
@Override
- public final InstanceIdentifier<R> createRouteIId(
+ public final InstanceIdentifier<R> createRouteIdentifier(
final KeyedInstanceIdentifier<Tables, TablesKey> tableIId, final N key) {
return tableIId.child((Class) routesContainerClass()).child(routesListClass(), key);
}
+++ /dev/null
-/*
- * Copyright (c) 2016 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 static org.opendaylight.protocol.bgp.parser.spi.PathIdUtil.NON_PATH_ID_VALUE;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-/**
- * Interface implemented to be extended by RibSupport.
- * This interface exposes methods to access to Add Path information
- * By default we implement non supported Multiple Path therefore
- * 0 Path Id is returned and null PathArgument
- */
-interface AddPathRibSupport {
- /**
- * Extract PathId from route change received.
- *
- * @param normalizedNode Path Id Container
- * @return pathId The path identifier value
- */
- default long extractPathId(@Nonnull NormalizedNode<?, ?> normalizedNode) {
- return NON_PATH_ID_VALUE;
- }
-
- /**
- * Construct a PathArgument to an AddPathRoute.
- *
- * @param pathId The path identifier
- * @param routeId PathArgument leaf path
- * @return routeId PathArgument + pathId or Null in case Add-path is not supported
- */
- @Nullable
- default NodeIdentifierWithPredicates getRouteIdAddPath(long pathId, @Nonnull PathArgument routeId) {
- return null;
- }
-
- /**
- * Create a new Path Argument for route Key removing remove Path Id from key.
- * For extension which do not support Multiple Path this step is not required.
- *
- * @param routeKeyPathArgument routeKey Path Argument
- * @return new route Key
- */
- default @Nonnull
- NodeIdentifierWithPredicates createRouteKeyPathArgument(
- @Nonnull NodeIdentifierWithPredicates routeKeyPathArgument) {
- return routeKeyPathArgument;
- }
-}
import com.google.common.collect.ImmutableMap;
import org.opendaylight.protocol.bgp.parser.spi.PathIdUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.PathId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.PathIdGrouping;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.Route;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.tables.Routes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
/**
* Implements common methods for Advertisement of Multiple Paths on ribSupport.
}
@Override
- public final long extractPathId(final NormalizedNode<?, ?> data) {
- final Long pathId = PathIdUtil.extractPathId(data, this.routePathIdNid());
- if (pathId == null) {
+ public final long extractPathId(final R route) {
+ if (route == null || route.getClass().isAssignableFrom(PathIdGrouping.class)) {
return PathIdUtil.NON_PATH_ID_VALUE;
}
- return pathId;
- }
-
- public final NodeIdentifierWithPredicates getRouteIdAddPath(final long pathId, final PathArgument routeId) {
- return PathIdUtil.createNidKey(pathId, routeId, routeQName(), pathIdQName(), routeKeyQName());
+ final PathId pathContainer = ((PathIdGrouping) route).getPathId();
+ if (pathContainer == null || pathContainer.getValue() == null) {
+ return PathIdUtil.NON_PATH_ID_VALUE;
+ }
+ return pathContainer.getValue();
}
@Override
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.SendReceive;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerRole;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.Tables;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.TablesKey;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
/**
* Exposes information required from peer to PeerTracker.
boolean supportsTable(@Nonnull TablesKey tableKey);
/**
- * Returns YangInstanceIdentifier pointing peer under specific rib.
+ * Creates Table Adj Rib Out Instance identifier.
*
- * @return Peer YangInstanceIdentifier
+ * @param tablekey table key
+ * @return instance identifier.
*/
@Nonnull
- YangInstanceIdentifier getPeerRibInstanceIdentifier();
+ KeyedInstanceIdentifier<Tables, TablesKey> getRibOutIId(@Nonnull TablesKey tablekey);
/**
* Returns Peer Role.
*/
package org.opendaylight.protocol.bgp.rib.spi;
+import static org.opendaylight.protocol.bgp.parser.spi.PathIdUtil.NON_PATH_ID_VALUE;
+
import com.google.common.collect.ImmutableCollection;
import java.util.Collection;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.PathId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.Update;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.Attributes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.Route;
* to register an implementation of this class and the RIB core then calls into it
* to inquire about details specific to that particular model.
*/
-public interface RIBSupport<R extends Route, N extends Identifier> extends AddPathRibSupport {
+public interface RIBSupport<R extends Route, N extends Identifier> {
/**
* Return the table-type-specific empty routes container, as augmented into the
* bgp-rib model under /rib/tables/routes choice node. This needs to include all
Class<? extends SubsequentAddressFamily> getSafi();
/**
- * Creates Route Rib out Peer InstanceIdentifier.
+ * Creates Route table Peer InstanceIdentifier.
*
- * @param ribOutIId table InstanceIdentifier
+ * @param tableKey table InstanceIdentifier
* @param newRouteKey route key
* @return InstanceIdentifier
*/
@Nonnull
- InstanceIdentifier<R> createRouteIId(
- @Nonnull KeyedInstanceIdentifier<Tables, TablesKey> ribOutIId,
+ InstanceIdentifier<R> createRouteIdentifier(
+ @Nonnull KeyedInstanceIdentifier<Tables, TablesKey> tableKey,
@Nonnull N newRouteKey);
@Nonnull
- R createRoute(@Nullable R route, N routeKey, long pathId, @Nonnull Attributes attributes);
+ R createRoute(@Nullable R route, N routeKey, @Nullable long pathId, @Nonnull Attributes attributes);
/**
- * Construct a PathArgument to an AddPathRoute.
+ * Construct a Route Key using new path Id for Families supporting additional path.
+ * Otherwise returns null.
*
* @param pathId The path identifier
* @param routeKey RouteKey
* @return routeId PathArgument + pathId or Null in case Add-path is not supported
*/
@Nullable
- default Identifier createNewRouteKey(long pathId, @Nonnull N routeKey) {
+ default N createNewRouteKey(@Nonnull long pathId, @Nonnull N routeKey) {
return null;
}
@Nonnull NodeIdentifierWithPredicates routeKey,
@Nonnull DataContainerNode<?> route, ContainerNode attributes);
}
+
+ /**
+ * Extract PathId from route change received.
+ *
+ * @param route Path Id Container
+ * @return pathId The path identifier value
+ */
+ default long extractPathId(@Nonnull R route) {
+ return NON_PATH_ID_VALUE;
+ }
+
+ /**
+ * Create a new Path Argument for route Key removing remove Path Id from key.
+ * For extension which do not support Multiple Path this step is not required.
+ *
+ * @param routeKey routeKey Path Argument
+ * @return new route Key
+ */
+ default @Nonnull
+ NodeIdentifierWithPredicates createRouteKeyPathArgument(@Nonnull NodeIdentifierWithPredicates routeKey) {
+ return routeKey;
+ }
}
package org.opendaylight.protocol.bgp.rib.spi.entry;
import javax.annotation.Nonnull;
-import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRibRoutingPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.Tables;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.TablesKey;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
/**
* Container wrapper for all dependencies related to Route Entry, required for process and storage.
/**
* Returns the loc-rib table to be updated and to which corresponds this Route Entry.
*
- * @return YangInstanceIdentifier containing the path to loc-rib table.
+ * @return InstanceIdentifier containing the path to loc-rib table.
*/
@Nonnull
- YangInstanceIdentifier getLocRibTableTarget();
-
- /**
- * Return the ExportPolicyPeerTracker which tracks peers.
- *
- * @return ExportPolicyPeerTracker
- */
- @Nonnull
- ExportPolicyPeerTracker getExportPolicyPeerTracker();
+ KeyedInstanceIdentifier<Tables, TablesKey> getLocRibTableTarget();
/**
* Return routing policies defined per RIB.
package org.opendaylight.protocol.bgp.rib.spi.entry;
import javax.annotation.Nonnull;
+import org.opendaylight.protocol.bgp.rib.spi.Peer;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerId;
+import org.opendaylight.yangtools.yang.binding.Identifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
/**
* RouteEntryInfo wrapper contains all related information from new best path.
*/
-public interface RouteEntryInfo extends RouteEntryKey {
+public interface RouteEntryInfo<N extends Identifier> extends RouteEntryKey<N> {
/**
* peer Id where best path will be advertized.
*
* @return PeerId
*/
@Nonnull
- PeerId getToPeerId();
-
- /**
- * Peer path of peer to which best path will be advertized.
- *
- * @return Root Path
- */
- @Nonnull
- YangInstanceIdentifier getRootPath();
+ Peer getToPeer();
}
package org.opendaylight.protocol.bgp.rib.spi.entry;
import javax.annotation.Nonnull;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.binding.Identifier;
/**
* Route Entry Key containing prefix.
*/
-public interface RouteEntryKey {
+public interface RouteEntryKey<N extends Identifier> {
/**
* Returns route containing prefix.
*
* @return Route key
*/
@Nonnull
- NodeIdentifierWithPredicates getRouteId();
+ N getRouteKey();
}
* Contains Peer destiny information for export route entry.
*/
public interface BGPRouteEntryExportParameters extends BGPRouteEntryImportParameters {
+
/**
- * Peer id of Peer destiny for route entry.
+ * Peer id of Peer route entry destiny.
*
- * @return peer Id of announced Peer
+ * @return peer Id of announcer Peer
*/
@Nonnull
PeerId getToPeerId();
/**
- * Peer role of Peer destiny for route entry.
+ * Peer id of Peer route entry destiny.
*
- * @return peer role of announced Peer
+ * @return peer Role of announcer Peer
*/
@Nonnull
PeerRole getToPeerRole();
+++ /dev/null
-/*
- * Copyright (c) 2016 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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.opendaylight.protocol.bgp.parser.spi.PathIdUtil.NON_PATH_ID_VALUE;
-
-import com.google.common.collect.ImmutableMap;
-import org.junit.Test;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev171207.ipv4.routes.ipv4.routes.Ipv4Route;
-
-public class AddPathRibSupportTest {
-
- private static final String PREFIX = "1.2.3.4/32";
- private static final String ROUTE_KEY = "prefix";
- private static final NodeIdentifierWithPredicates QNAME
- = new NodeIdentifierWithPredicates(Ipv4Route.QNAME,
- ImmutableMap.of(QName.create(Ipv4Route.QNAME, ROUTE_KEY).intern(), PREFIX));
-
- @Test
- public void defaultAddPathRibSupport() {
- final AddPathRibSupportLocalTest test = new AddPathRibSupportLocalTest();
- assertEquals(NON_PATH_ID_VALUE, test.extractPathId(null));
- assertNull(test.getRouteIdAddPath(NON_PATH_ID_VALUE, null));
- assertEquals(QNAME, test.createRouteKeyPathArgument(QNAME));
- }
-
- private static class AddPathRibSupportLocalTest implements AddPathRibSupport {
- }
-}
import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeSchemaAwareBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
public class MultiPathAbstractRIBSupportTest {
- private static final long PATH_ID = 0;
private static final String ROUTE_KEY = "prefix";
private static final String PREFIX = "1.2.3.4/32";
private static final QName PATH_ID_QNAME = QName.create(Ipv4Route.QNAME, "path-id").intern();
- private static final QName PREFIX_QNAME = QName.create(Ipv4Route.QNAME, ROUTE_KEY).intern();
private static final NodeIdentifierWithPredicates PREFIX_NII = new NodeIdentifierWithPredicates(Ipv4Route.QNAME,
ImmutableMap.of(QName.create(Ipv4Route.QNAME, ROUTE_KEY).intern(), PREFIX));
private static final MultiPathAbstractTest MULTI_PATH_ABSTRACT_TEST = new MultiPathAbstractTest();