Race condition is observed under Loc rib when new peer is connected.
There is a chance that Eff-rib-in changes are notified before
than changes under supported tables, therefore none existing route
is announced to the peer.
Fix by implement a unique ExportPolicyPeerTrackee per TableType and
per Rib.
On session stablished, peer will register itself to supported tables,
and remove himself when session down. This allow us to remove
CacheDisconnected peer, since it wont be longer required.
Also LocRib will be exclusively updated only related routes.
-Implement Base Path selection test
-Implement ExportPolicyPeerTrackerImpl test
Change-Id: I38b72f0ac9db09c64c4acdfeeb8eabade6ed046c
Signed-off-by: Claudio D. Gasparini <cgaspari@cisco.com>
import com.google.common.primitives.UnsignedInteger;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.protocol.bgp.rib.spi.CacheDisconnectedPeers;
import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.PeerExportGroup;
import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
* @param peerPT peer export policy
* @param locRibTarget YII local rib
* @param ribSupport rib support
- * @param discPeers list of disconnected peers
* @param tx DOM transaction
* @param routeIdPA router ID pathArgument
*/
void updateRoute(TablesKey localTK, ExportPolicyPeerTracker peerPT, YangInstanceIdentifier locRibTarget, RIBSupport ribSupport,
- CacheDisconnectedPeers discPeers, DOMDataWriteTransaction tx, PathArgument routeIdPA);
+ DOMDataWriteTransaction tx, PathArgument routeIdPA);
/**
* Write Route on LocRibOut and AdjRibsOut
* @param tx DOM transaction
*/
void writeRoute(PeerId peerId, PathArgument routeId, YangInstanceIdentifier rootPath, PeerExportGroup peerGroup, TablesKey localTK,
- ExportPolicyPeerTracker peerPT, RIBSupport ribSupport, CacheDisconnectedPeers discPeers, DOMDataWriteTransaction tx);
+ ExportPolicyPeerTracker peerPT, RIBSupport ribSupport, DOMDataWriteTransaction tx);
}
\ No newline at end of file
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
import org.opendaylight.protocol.bgp.mode.api.BestPath;
import org.opendaylight.protocol.bgp.mode.spi.AbstractRouteEntry;
-import org.opendaylight.protocol.bgp.rib.spi.CacheDisconnectedPeers;
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;
}
@Override
- public void updateRoute(final TablesKey localTK, final ExportPolicyPeerTracker peerPT, final YangInstanceIdentifier locRibTarget, final RIBSupport ribSup,
- final CacheDisconnectedPeers discPeers, final DOMDataWriteTransaction tx, final PathArgument routeIdPA) {
- //FIXME: Here we should have 2 independent removal for LocRib and RibOut, first will be only executed for best path changes, the second
- // when the owner of the route removes it.
+ public void updateRoute(final TablesKey localTK, final ExportPolicyPeerTracker peerPT, final YangInstanceIdentifier locRibTarget,
+ final RIBSupport ribSupport, final DOMDataWriteTransaction tx, final PathArgument routeIdPA) {
if(this.bestPathRemoved != null) {
this.bestPathRemoved.forEach(path -> {
- final PathArgument routeIdAddPath = ribSup.getRouteIdAddPath(path.getPathId(), routeIdPA);
- final YangInstanceIdentifier pathAddPathTarget = ribSup.routePath(locRibTarget.node(ROUTES_IDENTIFIER), routeIdAddPath);
+ final PathArgument routeIdAddPath = ribSupport.getRouteIdAddPath(path.getPathId(), routeIdPA);
+ final YangInstanceIdentifier pathAddPathTarget = ribSupport.routePath(locRibTarget.node(ROUTES_IDENTIFIER), routeIdAddPath);
fillLocRib(pathAddPathTarget, null, tx);
});
this.bestPathRemoved = null;
}
if(this.removedPaths != null) {
this.removedPaths.forEach(removedPath -> {
- final PathArgument routeIdAddPath = ribSup.getRouteIdAddPath(removedPath.getPathId(), routeIdPA);
+ final PathArgument routeIdAddPath = ribSupport.getRouteIdAddPath(removedPath.getPathId(), routeIdPA);
fillAdjRibsOut(true, null, null, null, routeIdPA, routeIdAddPath, RouterIds.createPeerId(removedPath.getRouteId()),
- peerPT, localTK, ribSup, discPeers, tx);
+ peerPT, localTK, ribSupport, tx);
});
this.removedPaths = null;
}
if(this.newBestPathToBeAdvertised != null) {
this.newBestPathToBeAdvertised.forEach(path -> addPathToDataStore(path, isFirstBestPath(this.bestPath.indexOf(path)), routeIdPA,
- locRibTarget, ribSup, peerPT, localTK, discPeers, tx));
+ locRibTarget, ribSupport, peerPT, localTK, tx));
this.newBestPathToBeAdvertised = null;
}
}
@Override
public void writeRoute(final PeerId destPeer, final PathArgument routeId, final YangInstanceIdentifier rootPath, final PeerExportGroup peerGroup,
- final TablesKey localTK, final ExportPolicyPeerTracker peerPT, final RIBSupport ribSup, final CacheDisconnectedPeers discPeers,
- final DOMDataWriteTransaction tx) {
+ final TablesKey localTK, final ExportPolicyPeerTracker peerPT, final RIBSupport ribSup, final DOMDataWriteTransaction tx) {
final boolean destPeerSupAddPath = peerPT.isAddPathSupportedByPeer(destPeer);
if(this.bestPath != null) {
final PeerRole destPeerRole = getRoutePeerIdRole(peerPT, destPeer);
- this.bestPath.stream().filter(path -> filterRoutes(path.getPeerId(), destPeer, peerPT, localTK, discPeers, destPeerRole) &&
+ this.bestPath.stream().filter(path -> filterRoutes(path.getPeerId(), destPeer, peerPT, localTK, destPeerRole) &&
peersSupportsAddPathOrIsFirstBestPath(destPeerSupAddPath, isFirstBestPath(this.bestPath.indexOf(path))))
.forEach(path -> writeRoutePath(destPeer, routeId, peerPT, peerGroup, destPeerSupAddPath, path, rootPath, localTK, ribSup, tx));
}
}
private void addPathToDataStore(final BestPath path, final boolean isFirstBestPath, final PathArgument routeIdPA, final YangInstanceIdentifier locRibTarget,
- final RIBSupport ribSup, final ExportPolicyPeerTracker peerPT, final TablesKey localTK, final CacheDisconnectedPeers discPeers,
- final DOMDataWriteTransaction tx) {
+ final RIBSupport ribSup, final ExportPolicyPeerTracker peerPT, final TablesKey localTK, final DOMDataWriteTransaction tx) {
final PathArgument routeIdAddPath = ribSup.getRouteIdAddPath(path.getPathId(), routeIdPA);
final YangInstanceIdentifier pathAddPathTarget = ribSup.routePath(locRibTarget.node(ROUTES_IDENTIFIER), routeIdAddPath);
final MapEntryNode addPathValue = createValue(routeIdAddPath, path);
LOG.trace("Selected best value {}", addPathValue);
fillLocRib(pathAddPathTarget, addPathValue, tx);
fillAdjRibsOut(isFirstBestPath, path.getAttributes(), value, addPathValue, routeIdPA, routeIdAddPath, path.getPeerId(), peerPT, localTK,
- ribSup, discPeers, tx);
+ ribSup, tx);
}
private void fillAdjRibsOut(final boolean isFirstBestPath, final ContainerNode attributes, final NormalizedNode<?, ?> value, final MapEntryNode addPathValue,
final PathArgument routeId, final PathArgument routeIdAddPath, final PeerId routePeerId, final ExportPolicyPeerTracker peerPT, final TablesKey
- localTK, final RIBSupport ribSup, final CacheDisconnectedPeers discPeers, final DOMDataWriteTransaction tx) {
+ localTK, final RIBSupport ribSup, final DOMDataWriteTransaction 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
for (final Map.Entry<PeerId, PeerExporTuple> pid : peerGroup.getPeers()) {
final PeerId destPeer = pid.getKey();
final boolean destPeerSupAddPath = peerPT.isAddPathSupportedByPeer(destPeer);
- if (filterRoutes(routePeerId, destPeer, peerPT, localTK, discPeers, getRoutePeerIdRole(peerPT, destPeer))
+ if (filterRoutes(routePeerId, destPeer, peerPT, localTK, getRoutePeerIdRole(peerPT, destPeer))
&& peersSupportsAddPathOrIsFirstBestPath(destPeerSupAddPath, isFirstBestPath)) {
if (destPeerSupAddPath) {
update(destPeer, getAdjRibOutYII(ribSup, pid.getValue().getYii(), routeIdAddPath, localTK), effectiveAttributes,
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
import org.opendaylight.protocol.bgp.mode.api.BestPath;
import org.opendaylight.protocol.bgp.mode.spi.AbstractRouteEntry;
-import org.opendaylight.protocol.bgp.rib.spi.CacheDisconnectedPeers;
import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.PeerExportGroup;
import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
@Override
public void updateRoute(final TablesKey localTK, final ExportPolicyPeerTracker peerPT, final YangInstanceIdentifier locRibTarget, final RIBSupport ribSup,
- final CacheDisconnectedPeers discPeers, final DOMDataWriteTransaction tx, final PathArgument routeIdPA) {
+ final DOMDataWriteTransaction tx, final PathArgument routeIdPA) {
if (this.removedBestPath != null) {
- removePathFromDataStore(this.removedBestPath, routeIdPA, locRibTarget, peerPT, localTK, ribSup, discPeers, tx);
+ removePathFromDataStore(this.removedBestPath, routeIdPA, locRibTarget, peerPT, localTK, ribSup, tx);
this.removedBestPath = null;
}
if (this.bestPath != null) {
- addPathToDataStore(this.bestPath, routeIdPA, locRibTarget, ribSup, peerPT, localTK, discPeers, tx);
+ addPathToDataStore(this.bestPath, routeIdPA, locRibTarget, ribSup, peerPT, localTK, tx);
}
}
@Override
public void writeRoute(final PeerId destPeer, final PathArgument routeId, final YangInstanceIdentifier rootPath, final PeerExportGroup peerGroup,
- final TablesKey localTK, final ExportPolicyPeerTracker peerPT, final RIBSupport ribSup, final CacheDisconnectedPeers discPeers,
- final DOMDataWriteTransaction tx) {
+ final TablesKey localTK, final ExportPolicyPeerTracker peerPT, final RIBSupport ribSupport, final DOMDataWriteTransaction tx) {
if (this.bestPath != null) {
final BaseBestPath path = this.bestPath;
final PeerRole destPeerRole = getRoutePeerIdRole(peerPT, destPeer);
- if (filterRoutes(path.getPeerId(), destPeer, peerPT, localTK, discPeers, destPeerRole)) {
+ if (filterRoutes(path.getPeerId(), destPeer, peerPT, localTK, destPeerRole)) {
final ContainerNode effAttrib = peerGroup.effectiveAttributes(getRoutePeerIdRole(peerPT,path.getPeerId()), path.getAttributes());
- writeRoute(destPeer, getAdjRibOutYII(ribSup, rootPath, routeId, localTK), effAttrib, createValue(routeId, path), ribSup, tx);
+ writeRoute(destPeer, getAdjRibOutYII(ribSupport, rootPath, routeId, localTK), effAttrib,
+ createValue(routeId, path), ribSupport, tx);
}
}
}
private void removePathFromDataStore(final BestPath path, final PathArgument routeIdPA, final YangInstanceIdentifier locRibTarget,
- final ExportPolicyPeerTracker peerPT, final TablesKey localTK, final RIBSupport ribSup, final CacheDisconnectedPeers discPeers,
- final DOMDataWriteTransaction tx) {
+ final ExportPolicyPeerTracker peerPT, final TablesKey localTK, final RIBSupport ribSup, final DOMDataWriteTransaction tx) {
LOG.trace("Best Path removed {}", path);
final PathArgument routeIdAddPath = ribSup.getRouteIdAddPath(path.getPathId(), routeIdPA);
final YangInstanceIdentifier pathTarget = ribSup.routePath(locRibTarget.node(ROUTES_IDENTIFIER), routeIdPA);
pathAddPathTarget = ribSup.routePath(locRibTarget.node(ROUTES_IDENTIFIER), routeIdAddPath);
}
fillLocRib(pathAddPathTarget == null ? pathTarget : pathAddPathTarget, null, tx);
- fillAdjRibsOut(null, null, routeIdPA, path.getPeerId(), peerPT, localTK, ribSup, discPeers, tx);
+ fillAdjRibsOut(null, null, routeIdPA, path.getPeerId(), peerPT, localTK, ribSup, tx);
}
private void addPathToDataStore(final BestPath path, final PathArgument routeIdPA, final YangInstanceIdentifier locRibTarget,
- final RIBSupport ribSup, final ExportPolicyPeerTracker peerPT, final TablesKey localTK, final CacheDisconnectedPeers discPeers,
- final DOMDataWriteTransaction tx) {
+ final RIBSupport ribSup, final ExportPolicyPeerTracker peerPT, final TablesKey localTK, final DOMDataWriteTransaction tx) {
final PathArgument routeIdAddPath = ribSup.getRouteIdAddPath(path.getPathId(), routeIdPA);
final YangInstanceIdentifier pathTarget = ribSup.routePath(locRibTarget.node(ROUTES_IDENTIFIER), routeIdPA);
final NormalizedNode<?, ?> value = createValue(routeIdPA, path);
LOG.trace("Selected best value {}", addPathValue);
}
fillLocRib(pathAddPathTarget == null ? pathTarget : pathAddPathTarget, addPathValue == null ? value : addPathValue, tx);
- fillAdjRibsOut(path.getAttributes(), value, routeIdPA, path.getPeerId(), peerPT, localTK, ribSup, discPeers, tx);
+ fillAdjRibsOut(path.getAttributes(), value, routeIdPA, path.getPeerId(), peerPT, localTK, ribSup, tx);
}
final OffsetMap getOffsets() {
@VisibleForTesting
private void fillAdjRibsOut(final ContainerNode attributes, final NormalizedNode<?, ?> value,
final PathArgument routeId, final PeerId routePeerId, final ExportPolicyPeerTracker peerPT, final TablesKey localTK, final RIBSupport ribSup,
- final CacheDisconnectedPeers discPeers, final DOMDataWriteTransaction tx) {
+ final DOMDataWriteTransaction 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 (peerGroup != null) {
final ContainerNode effAttrib = peerGroup.effectiveAttributes(getRoutePeerIdRole(peerPT, routePeerId), attributes);
peerGroup.getPeers().stream()
- .filter(pid -> filterRoutes(routePeerId, pid.getKey(), peerPT, localTK, discPeers, getRoutePeerIdRole(peerPT, pid.getKey())))
+ .filter(pid -> filterRoutes(routePeerId, pid.getKey(), peerPT, localTK, getRoutePeerIdRole(peerPT, pid.getKey())))
.forEach(pid -> update(pid.getKey(), getAdjRibOutYII(ribSup, pid.getValue().getYii(), routeId, localTK), effAttrib, value, ribSup, tx));
}
}
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
import org.opendaylight.protocol.bgp.mode.api.RouteEntry;
-import org.opendaylight.protocol.bgp.rib.spi.CacheDisconnectedPeers;
import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.PeerExportGroup;
import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
return false;
}
- protected final boolean filterRoutes(final PeerId rootPeer, final PeerId destPeer, final ExportPolicyPeerTracker peerPT,
- final TablesKey localTK, final CacheDisconnectedPeers discPeers, final PeerRole destPeerRole) {
- return !rootPeer.equals(destPeer) && isTableSupported(destPeer, peerPT, localTK) && !discPeers.isPeerDisconnected(destPeer) &&
- !PeerRole.Internal.equals(destPeerRole);
+ protected final boolean filterRoutes(final PeerId rootPeer, final PeerId destPeer, final ExportPolicyPeerTracker peerPT, final TablesKey localTK, final PeerRole destPeerRole) {
+ return !rootPeer.equals(destPeer) && isTableSupported(destPeer, peerPT, localTK) && !PeerRole.Internal.equals(destPeerRole);
}
private boolean isTableSupported(final PeerId destPeer, final ExportPolicyPeerTracker peerPT, final TablesKey localTK) {
import org.mockito.stubbing.Answer;
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.CacheDisconnectedPeers;
import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.PeerExportGroup;
import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
protected ExportPolicyPeerTracker peerPT;
@Mock
protected PeerExportGroup peg;
- protected CacheDisconnectedPeers discCache;
protected List<YangInstanceIdentifier> yIIChanges;
protected NormalizedNode<?, ?> attributes;
protected YangInstanceIdentifier routePaYii;
MockitoAnnotations.initMocks(this);
this.yIIChanges = new ArrayList<>();
this.peerPT = Mockito.mock(ExportPolicyPeerTracker.class);
- this.discCache = Mockito.mock(CacheDisconnectedPeers.class);
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);
mockExportPolicies();
mockExportGroup();
mockTransactionChain();
- mockCacheDiscPeers();
- }
-
- private void mockCacheDiscPeers() {
- Mockito.doReturn(false).when(this.discCache).isPeerDisconnected(PEER_ID);
- Mockito.doReturn(true).when(this.discCache).isPeerDisconnected(PEER_DISCONNECTED);
}
private void mockTransactionChain() {
assertFalse(this.testBARE.isEmpty());
assertTrue(this.testBARE.selectBest(AS));
/** Add AddPath Route **/
- this.testBARE.updateRoute(TABLES_KEY, this.peerPT, LOC_RIB_TARGET, this.ribSupport, this.discCache, this.tx, ROUTE_ID_PA_ADD_PATH);
+ this.testBARE.updateRoute(TABLES_KEY, this.peerPT, LOC_RIB_TARGET, this.ribSupport, this.tx, ROUTE_ID_PA_ADD_PATH);
Map<YangInstanceIdentifier, Long> yiiCount = this.yIIChanges.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
assertEquals(3, yiiCount.size());
assertEquals(1, (long) yiiCount.get(this.routePaAddPathYii));
assertEquals(1, (long) yiiCount.get(this.routePaAddPathYii));
assertTrue(this.testBARE.removeRoute(ROUTER_ID, REMOTE_PATH_ID));
assertTrue(this.testBARE.selectBest(AS));
- this.testBARE.updateRoute(TABLES_KEY, this.peerPT, LOC_RIB_TARGET, this.ribSupport, this.discCache, this.tx, ROUTE_ID_PA_ADD_PATH);
+ this.testBARE.updateRoute(TABLES_KEY, this.peerPT, LOC_RIB_TARGET, this.ribSupport, this.tx, ROUTE_ID_PA_ADD_PATH);
yiiCount = this.yIIChanges.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
assertEquals(0, yiiCount.size());
assertFalse(yiiCount.containsKey(this.routePaAddPathYii));
}
private void testWriteEmptyBestPath() {
- this.testBARE.writeRoute(PEER_ID, ROUTE_ID_PA, PEER_YII2, this.peg, TABLES_KEY, this.peerPT, this.ribSupport, this.discCache, this.tx);
+ this.testBARE.writeRoute(PEER_ID, ROUTE_ID_PA, PEER_YII2, this.peg, TABLES_KEY, this.peerPT, this.ribSupport, this.tx);
assertEquals(0, this.yIIChanges.size());
}
assertFalse(this.testBARE.isEmpty());
assertTrue(this.testBARE.selectBest(AS));
/** Add AddPath Route **/
- this.testBARE.updateRoute(TABLES_KEY, this.peerPT, LOC_RIB_TARGET, this.ribSupport, this.discCache, this.tx, ROUTE_ID_PA_ADD_PATH);
+ this.testBARE.updateRoute(TABLES_KEY, this.peerPT, LOC_RIB_TARGET, this.ribSupport, this.tx, ROUTE_ID_PA_ADD_PATH);
Map<YangInstanceIdentifier, Long> yiiCount = this.yIIChanges.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
assertEquals(3, yiiCount.size());
assertEquals(1, (long) yiiCount.get(this.routePaAddPathYii));
private void testInitializePeerWithExistentRoute() {
assertEquals(3, this.yIIChanges.size());
- this.testBARE.writeRoute(PEER_ID, ROUTE_ID_PA_ADD_PATH, PEER_YII2, this.peg, TABLES_KEY, this.peerPT, this.ribSupport, this.discCache, this.tx);
+ this.testBARE.writeRoute(PEER_ID, ROUTE_ID_PA_ADD_PATH, PEER_YII2, this.peg, TABLES_KEY, this.peerPT, this.ribSupport, this.tx);
assertEquals(5, this.yIIChanges.size());
final Map<YangInstanceIdentifier, Long> yiiCount = this.yIIChanges.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
assertEquals(1, (long) yiiCount.get(this.routePaAddPathYii));
assertTrue(this.testBARE.removeRoute(ROUTER_ID, REMOTE_PATH_ID));
assertTrue(this.testBARE.selectBest(AS));
- this.testBARE.updateRoute(TABLES_KEY, this.peerPT, LOC_RIB_TARGET, this.ribSupport, this.discCache, this.tx, ROUTE_ID_PA_ADD_PATH);
+ this.testBARE.updateRoute(TABLES_KEY, this.peerPT, LOC_RIB_TARGET, this.ribSupport, this.tx, ROUTE_ID_PA_ADD_PATH);
yiiCount = this.yIIChanges.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
assertEquals(2, yiiCount.size());
assertFalse(yiiCount.containsKey(this.routePaAddPathYii));
assertEquals(1, (long) yiiCount.get(this.routePaYii));
this.testBARE.removeRoute(ROUTER_ID, REMOTE_PATH_ID);
this.testBARE.selectBest(AS);
- this.testBARE.updateRoute(TABLES_KEY, this.peerPT, LOC_RIB_TARGET, this.ribSupport, this.discCache, this.tx, ROUTE_ID_PA);
+ this.testBARE.updateRoute(TABLES_KEY, this.peerPT, LOC_RIB_TARGET, this.ribSupport, this.tx, ROUTE_ID_PA);
yiiCount = this.yIIChanges.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
assertFalse(yiiCount.containsKey(this.routePaYii));
assertFalse(yiiCount.containsKey(this.routeAddRiboutAttYii));
}
private void testInitializePeerWithExistentRoute() {
- this.testBARE.writeRoute(PEER_ID, ROUTE_ID_PA, PEER_YII2, this.peg, TABLES_KEY, this.peerPT, this.ribSupport, this.discCache, this.tx);
+ this.testBARE.writeRoute(PEER_ID, ROUTE_ID_PA, PEER_YII2, this.peg, TABLES_KEY, this.peerPT, this.ribSupport, this.tx);
assertEquals(8, this.yIIChanges.size());
final Map<YangInstanceIdentifier, Long> yiiCount = this.yIIChanges.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
this.testBARE.addRoute(ROUTER_ID, REMOTE_PATH_ID, this.ribSupport.routeAttributesIdentifier(), this.attributes);
assertFalse(this.testBARE.getOffsets().isEmpty());
this.testBARE.selectBest(AS);
- this.testBARE.updateRoute(TABLES_KEY, this.peerPT, LOC_RIB_TARGET, this.ribSupport, this.discCache, this.tx, ROUTE_ID_PA);
+ this.testBARE.updateRoute(TABLES_KEY, this.peerPT, LOC_RIB_TARGET, this.ribSupport, this.tx, ROUTE_ID_PA);
Map<YangInstanceIdentifier, Long> yiiCount = this.yIIChanges.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
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.updateRoute(TABLES_KEY, this.peerPT, LOC_RIB_TARGET, this.ribSupport, this.discCache, this.tx, ROUTE_ID_PA_ADD_PATH);
+ this.testBARE.updateRoute(TABLES_KEY, this.peerPT, LOC_RIB_TARGET, this.ribSupport, this.tx, ROUTE_ID_PA_ADD_PATH);
yiiCount = this.yIIChanges.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
assertEquals(6, yiiCount.size());
assertEquals(1, (long) yiiCount.get(this.routePaAddPathYii));
}
private void testWriteEmptyBestPath() {
- this.testBARE.writeRoute(PEER_ID, ROUTE_ID_PA, PEER_YII2, this.peg, TABLES_KEY, this.peerPT, this.ribSupport, this.discCache, this.tx);
+ this.testBARE.writeRoute(PEER_ID, ROUTE_ID_PA, PEER_YII2, this.peg, TABLES_KEY, this.peerPT, this.ribSupport, this.tx);
assertEquals(0, this.yIIChanges.size());
}
}
\ No newline at end of file
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import java.util.Collections;
-import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
-import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.NotThreadSafe;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.protocol.bgp.rib.spi.PeerRoleUtil;
import org.opendaylight.protocol.bgp.rib.spi.RibSupportUtils;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.SendReceive;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.mp.capabilities.add.path.capability.AddressFamilies;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlri;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerId;
* @return New writer
*/
AdjRibInWriter transform(final PeerId newPeerId, final RIBSupportContextRegistry registry, final Set<TablesKey> tableTypes,
- final List<AddressFamilies> addPathTablesType) {
+ final Map<TablesKey, SendReceive> addPathTablesType) {
final DOMDataWriteTransaction tx = this.chain.newWriteOnlyTransaction();
final YangInstanceIdentifier newPeerPath;
* @return
*/
private ImmutableMap<TablesKey, TableContext> createNewTableInstances(final YangInstanceIdentifier newPeerPath,
- final RIBSupportContextRegistry registry, final Set<TablesKey> tableTypes, final List<AddressFamilies> addPathTablesType,
+ final RIBSupportContextRegistry registry, final Set<TablesKey> tableTypes, final Map<TablesKey, SendReceive> addPathTablesType,
final DOMDataWriteTransaction tx) {
- final Map<TablesKey, SendReceive> addPathTableMaps = mapTableTypesFamilies(addPathTablesType);
final Builder<TablesKey, TableContext> tb = ImmutableMap.builder();
for (final TablesKey tableKey : tableTypes) {
final RIBSupportContext rs = registry.getRIBSupportContext(tableKey);
LOG.warn("No support for table type {}, skipping it", tableKey);
continue;
}
- installAdjRibsOutTables(newPeerPath, rs, instanceIdentifierKey, tableKey, addPathTableMaps.get(tableKey), tx);
+ installAdjRibsOutTables(newPeerPath, rs, instanceIdentifierKey, tableKey, addPathTablesType.get(tableKey), tx);
installAdjRibInTables(newPeerPath, tableKey, rs, instanceIdentifierKey, tx, tb);
}
return tb.build();
}
- private Map<TablesKey, SendReceive> mapTableTypesFamilies(final List<AddressFamilies> addPathTablesType) {
- return Collections.unmodifiableMap(addPathTablesType.stream().collect(Collectors.toMap(af -> new TablesKey(af.getAfi(), af.getSafi()),
- af -> af.getSendReceive())));
- }
-
private void installAdjRibInTables(final YangInstanceIdentifier newPeerPath, final TablesKey tableKey, final RIBSupportContext rs,
final NodeIdentifierWithPredicates instanceIdentifierKey, final DOMDataWriteTransaction tx, final Builder<TablesKey, TableContext> tb) {
// We will use table keys very often, make sure they are optimized
import java.util.Collection;
import java.util.Collections;
import java.util.Optional;
+import java.util.Set;
import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
+import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
+import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.IdentifierUtils;
import org.opendaylight.protocol.bgp.rib.spi.RouterIds;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.ApplicationRibId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.SimpleRoutingPolicy;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.Peer;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.peer.AdjRibIn;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
private DOMTransactionChain chain;
private DOMTransactionChain writerChain;
private EffectiveRibInWriter effectiveRibInWriter;
- private AdjRibInWriter writer;
+ private AdjRibInWriter adjRibInWriter;
public ApplicationPeer(final ApplicationRibId applicationRibId, final Ipv4Address ipAddress, final RIB rib) {
this.name = applicationRibId.getValue();
public void instantiateServiceInstance() {
this.chain = this.rib.createPeerChain(this);
this.writerChain = this.rib.createPeerChain(this);
- this.writer = AdjRibInWriter.create(this.rib.getYangRibId(), PeerRole.Internal, Optional.of(SimpleRoutingPolicy.AnnounceNone), this.writerChain);
- this.writer = this.writer.transform(RouterIds.createPeerId(this.ipAddress), this.rib.getRibSupportContext(), this.rib.getLocalTablesKeys(),
- Collections.emptyList());
- //TODO need to create effective rib in writer with route counter here
+
+ final Optional<SimpleRoutingPolicy> simpleRoutingPolicy = Optional.of(SimpleRoutingPolicy.AnnounceNone);
+ final PeerId peerId = RouterIds.createPeerId(this.ipAddress);
+ final Set<TablesKey> localTables = this.rib.getLocalTablesKeys();
+ localTables.forEach(tablesKey -> {
+ final ExportPolicyPeerTracker exportTracker = this.rib.getExportPolicyPeerTracker(tablesKey);
+ if (exportTracker != null) {
+ exportTracker.registerPeer(peerId, null, this.peerIId, PeerRole.Internal, simpleRoutingPolicy);
+ }
+ });
+
+ this.adjRibInWriter = AdjRibInWriter.create(this.rib.getYangRibId(), PeerRole.Internal, simpleRoutingPolicy, this.writerChain);
+ final RIBSupportContextRegistry context = this.rib.getRibSupportContext();
+ this.adjRibInWriter = this.adjRibInWriter.transform(peerId, context, localTables, Collections.emptyMap());
+ //TODO need to create effective rib in adjRibInWriter with route counter here
this.effectiveRibInWriter = EffectiveRibInWriter.create(this.rib.getService(), this.rib.createPeerChain(this), this.peerIId,
- this.rib.getImportPolicyPeerTracker(), this.rib.getRibSupportContext(), PeerRole.Internal);
+ this.rib.getImportPolicyPeerTracker(), context, PeerRole.Internal);
}
/**
if(this.effectiveRibInWriter != null) {
this.effectiveRibInWriter.close();
}
- if(this.writer != null) {
- this.writer.removePeer();
+ if(this.adjRibInWriter != null) {
+ this.adjRibInWriter.removePeer();
}
if(this.chain != null) {
this.chain.close();
import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
import com.google.common.net.InetAddresses;
import java.util.ArrayList;
import java.util.Arrays;
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.RouterIds;
+import org.opendaylight.protocol.concepts.AbstractRegistration;
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.rev150305.ipv4.prefixes.DestinationIpv4Builder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.prefixes.destination.ipv4.Ipv4Prefixes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Update;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Attributes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.AttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpAddPathTableType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.RouteRefresh;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.SendReceive;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.mp.capabilities.add.path.capability.AddressFamilies;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlri;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlriBuilder;
private final PeerRole peerRole;
private final Optional<SimpleRoutingPolicy> simpleRoutingPolicy;
private final BGPPeerStats peerStats;
+ private YangInstanceIdentifier peerIId;
+ private final Set<AbstractRegistration> tableRegistration = new HashSet<>();
public BGPPeer(final String name, final RIB rib, final PeerRole role, final SimpleRoutingPolicy peerStatus, final RpcProviderRegistry rpcRegistry) {
this.peerRole = role;
@Override
public synchronized void onSessionUp(final BGPSession session) {
final List<AddressFamilies> addPathTablesType = session.getAdvertisedAddPathTableTypes();
- LOG.info("Session with peer {} went up with tables {} and Add Path tables {}", this.name, addPathTablesType,
- session.getAdvertisedAddPathTableTypes());
+ final Set<BgpTableType> advertizedTableTypes = session.getAdvertisedTableTypes();
+ LOG.info("Session with peer {} went up with tables {} and Add Path tables {}", this.name, advertizedTableTypes, addPathTablesType);
this.session = session;
this.rawIdentifier = InetAddresses.forString(session.getBgpId().getValue()).getAddress();
final PeerId peerId = RouterIds.createPeerId(session.getBgpId());
- this.tables.addAll(this.session.getAdvertisedTableTypes().stream().map(t -> new TablesKey(t.getAfi(), t.getSafi())).collect(Collectors.toList()));
+ this.tables.addAll(advertizedTableTypes.stream().map(t -> new TablesKey(t.getAfi(), t.getSafi())).collect(Collectors.toList()));
final boolean announceNone = isAnnounceNone(this.simpleRoutingPolicy);
+ final Map<TablesKey, SendReceive> addPathTableMaps = mapTableTypesFamilies(addPathTablesType);
+ this.peerIId = this.rib.getYangRibId().node(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.Peer.QNAME)
+ .node(IdentifierUtils.domPeerId(peerId));
+
if(!announceNone) {
createAdjRibOutListener(peerId);
}
+ this.tables.forEach(tablesKey -> {
+ final ExportPolicyPeerTracker exportTracker = this.rib.getExportPolicyPeerTracker(tablesKey);
+ if (exportTracker != null) {
+ this.tableRegistration.add(exportTracker.registerPeer(peerId, addPathTableMaps.get(tablesKey), this.peerIId, this.peerRole,
+ this.simpleRoutingPolicy));
+ }
+ });
addBgp4Support(peerId, announceNone);
if(!isLearnNone(this.simpleRoutingPolicy)) {
- final YangInstanceIdentifier peerIId = this.rib.getYangRibId().node(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.Peer.QNAME).node(IdentifierUtils.domPeerId(peerId));
- this.effRibInWriter = EffectiveRibInWriter.create(this.rib.getService(), this.rib.createPeerChain(this), peerIId, this.rib.getImportPolicyPeerTracker(),
- this.rib.getRibSupportContext(), this.peerRole, this.peerStats.getEffectiveRibInRouteCounters(), this.peerStats.getAdjRibInRouteCounters());
+ this.effRibInWriter = EffectiveRibInWriter.create(this.rib.getService(), this.rib.createPeerChain(this), this.peerIId,
+ this.rib.getImportPolicyPeerTracker(), this.rib.getRibSupportContext(), this.peerRole,
+ this.peerStats.getEffectiveRibInRouteCounters(), this.peerStats.getAdjRibInRouteCounters());
}
- this.ribWriter = this.ribWriter.transform(peerId, this.rib.getRibSupportContext(), this.tables, addPathTablesType);
+ this.ribWriter = this.ribWriter.transform(peerId, this.rib.getRibSupportContext(), this.tables, addPathTableMaps);
// register BGP Peer stats
this.peerStats.getSessionEstablishedCounter().increaseCount();
// not particularly nice
if (context != null && this.session instanceof BGPSessionImpl) {
this.adjRibOutListenerSet.put(key, AdjRibOutListener.create(peerId, key, this.rib.getYangRibId(), this.rib.getCodecsRegistry(),
- context.getRibSupport(), this.rib.getService(), ((BGPSessionImpl) this.session).getLimiter(), mpSupport, this.peerStats.getAdjRibOutRouteCounters().init(key)));
+ context.getRibSupport(), this.rib.getService(), ((BGPSessionImpl) this.session).getLimiter(), mpSupport,
+ this.peerStats.getAdjRibOutRouteCounters().init(key)));
}
}
if (this.rpcRegistration != null) {
this.rpcRegistration.close();
}
- addPeerToDisconnectedSharedList();
+ closeRegistration();
cleanup();
dropConnection();
}
- private void addPeerToDisconnectedSharedList() {
- if(this.session != null) {
- this.rib.getCacheDisconnectedPeers().insertDesconectedPeer(this.session.getBgpId());
+ private void closeRegistration() {
+ for (final AbstractRegistration tableCloseable : this.tableRegistration) {
+ tableCloseable.close();
}
+ this.tableRegistration.clear();
}
private void dropConnection() {
public void markUptodate(final TablesKey tablesKey) {
this.ribWriter.markTableUptodate(tablesKey);
}
+
+ 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)));
+ }
}
+++ /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.impl;
-
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import java.util.concurrent.TimeUnit;
-import org.opendaylight.protocol.bgp.rib.spi.CacheDisconnectedPeers;
-import org.opendaylight.protocol.bgp.rib.spi.RouterIds;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerId;
-
-public final class CacheDisconnectedPeersImpl implements CacheDisconnectedPeers {
- private static Cache<PeerId, Boolean> cache = CacheBuilder.newBuilder().expireAfterAccess(30, TimeUnit.SECONDS).build();
-
- CacheDisconnectedPeersImpl() {
- }
-
- @Override
- public boolean isPeerDisconnected(final PeerId peerId) {
- if (this.cache.getIfPresent(peerId) != null) {
- return true;
- }
- return false;
- }
-
- @Override
- public void reconnected(final PeerId peerId) {
- this.cache.asMap().remove(peerId);
- }
-
- @Override
- public void insertDesconectedPeer(final Ipv4Address peerId) {
- this.cache.put(RouterIds.createPeerId(peerId), true);
- }
-}
import static java.util.function.Function.identity;
import static java.util.stream.Collectors.toMap;
-import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Sets;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
+import javax.annotation.concurrent.GuardedBy;
+import javax.annotation.concurrent.ThreadSafe;
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.PeerExportGroup.PeerExporTuple;
-import org.opendaylight.protocol.bgp.rib.spi.RibSupportUtils;
+import org.opendaylight.protocol.concepts.AbstractRegistration;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.SendReceive;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.peer.SupportedTables;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.SimpleRoutingPolicy;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
-import org.opendaylight.yangtools.yang.binding.BindingMapping;
-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.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+@ThreadSafe
final class ExportPolicyPeerTrackerImpl implements ExportPolicyPeerTracker {
private static final Logger LOG = LoggerFactory.getLogger(ExportPolicyPeerTrackerImpl.class);
- private static final QName SEND_RECEIVE = QName.create(SupportedTables.QNAME, "send-receive").intern();
- private static final NodeIdentifier SEND_RECEIVE_NID = new NodeIdentifier(SEND_RECEIVE);
+ @GuardedBy("this")
private final Map<YangInstanceIdentifier, PeerRole> peerRoles = new HashMap<>();
- private final Set<PeerId> peerTables = Sets.newHashSet();
- private final PolicyDatabase policyDatabase;
+ @GuardedBy("this")
private final Map<PeerId, SendReceive> peerAddPathTables = new HashMap<>();
+ @GuardedBy("this")
+ private final Set<PeerId> peerTables = new HashSet<>();
+ private final PolicyDatabase policyDatabase;
private final TablesKey localTableKey;
private volatile Map<PeerRole, PeerExportGroup> groups = Collections.emptyMap();
this.localTableKey = localTablesKey;
}
- private Map<PeerRole, PeerExportGroup> createGroups(final Map<YangInstanceIdentifier, PeerRole> peerPathRoles) {
- if (peerPathRoles.isEmpty()) {
- return Collections.emptyMap();
- }
-
- final Map<PeerRole, Map<PeerId, PeerExporTuple>> immutablePeers = peerPathRoles.entrySet().stream()
- .collect(Collectors.groupingBy(Map.Entry::getValue, toMap(peer -> IdentifierUtils.peerKeyToPeerId(peer
- .getKey()), peer -> new PeerExporTuple(peer.getKey(), peer.getValue()))));
-
- final Map<PeerRole, PeerExportGroup> ret = peerPathRoles.values().stream().collect(Collectors.toSet()).stream()
- .collect(toMap(identity(), role -> new PeerExportGroupImpl(ImmutableMap.copyOf(immutablePeers.get(role)),
- this.policyDatabase.exportPolicyForRole(role)), (oldKey, newKey) -> oldKey, () -> new EnumMap<>(PeerRole.class)));
+ private synchronized void createGroups(final Map<YangInstanceIdentifier, PeerRole> peerPathRoles) {
+ if (!peerPathRoles.isEmpty()) {
+ final Map<PeerRole, Map<PeerId, PeerExporTuple>> immutablePeers = peerPathRoles.entrySet().stream()
+ .collect(Collectors.groupingBy(Map.Entry::getValue, toMap(peer -> IdentifierUtils.peerKeyToPeerId(peer
+ .getKey()), peer -> new PeerExporTuple(peer.getKey(), peer.getValue()))));
- return ret;
+ this.groups = peerPathRoles.values().stream().collect(Collectors.toSet()).stream()
+ .collect(toMap(identity(), role -> new PeerExportGroupImpl(ImmutableMap.copyOf(immutablePeers.get(role)),
+ this.policyDatabase.exportPolicyForRole(role)), (oldKey, newKey) -> oldKey, () -> new EnumMap<>(PeerRole.class)));
+ }
}
@Override
- public void peerRoleChanged(@Nonnull final YangInstanceIdentifier peerPath, @Nullable final PeerRole role) {
- /*
- * This is a sledgehammer approach to the problem: modify the role map first,
- * then construct the group map from scratch.
- */
- final PeerRole oldRole;
- if (role != null) {
- oldRole = this.peerRoles.put(peerPath, role);
- } else {
- oldRole = this.peerRoles.remove(peerPath);
+ public synchronized AbstractRegistration registerPeer(final PeerId peerId, final SendReceive sendReceive, final YangInstanceIdentifier peerPath,
+ final PeerRole peerRole, final Optional<SimpleRoutingPolicy> optSimpleRoutingPolicy) {
+ if (sendReceive != null) {
+ this.peerAddPathTables.put(peerId, sendReceive);
+ LOG.debug("Supported Add BestPath table {} added to peer {}", sendReceive, peerId);
}
-
- if (role != oldRole) {
- LOG.debug("Peer {} changed role from {} to {}", peerPath, oldRole, role);
- this.groups = createGroups(this.peerRoles);
+ final SimpleRoutingPolicy simpleRoutingPolicy = optSimpleRoutingPolicy.orElse(null);
+ if (SimpleRoutingPolicy.AnnounceNone != simpleRoutingPolicy) {
+ this.peerTables.add(peerId);
}
- }
-
- @Override
- public void onTablesChanged(final PeerId peerId, final DataTreeCandidateNode tablesChange) {
- final NodeIdentifierWithPredicates supTablesKey = RibSupportUtils.toYangKey(SupportedTables.QNAME, this.localTableKey);
- final DataTreeCandidateNode localTableNode = tablesChange.getModifiedChild(supTablesKey);
- if (localTableNode != null) {
- final Optional<NormalizedNode<?, ?>> dataAfter = localTableNode.getDataAfter();
- processSupportedSendReceiveTables(localTableNode.getModifiedChild(SEND_RECEIVE_NID), peerId);
- if (dataAfter.isPresent()) {
- final boolean added = this.peerTables.add(peerId);
- if (added) {
- LOG.debug("Supported table {} added to peer {}", this.localTableKey, peerId);
+ this.peerRoles.put(peerPath, peerRole);
+ LOG.debug("Supported table {} added to peer {} role {}", this.localTableKey, peerId, peerRole);
+ createGroups(this.peerRoles);
+
+ final Object lock = this;
+ return new AbstractRegistration() {
+ @Override
+ protected void removeRegistration() {
+ synchronized (lock) {
+ final SendReceive sendReceiveValue = peerAddPathTables.remove(peerId);
+ if (sendReceiveValue != null) {
+ LOG.debug("Supported Add BestPath table {} removed to peer {}", sendReceiveValue, peerId);
+ }
+ peerTables.remove(peerId);
+ LOG.debug("Removed peer {} from supported table {}", peerId, localTableKey);
+ peerRoles.remove(peerPath);
+ createGroups(peerRoles);
}
- } else {
- final NodeIdentifierWithPredicates value = (NodeIdentifierWithPredicates) localTableNode.getIdentifier();
- this.peerTables.remove(peerId);
- LOG.debug("Removed tables {} from peer {}", value, peerId);
}
- }
+ };
}
@Override
- public PeerExportGroup getPeerGroup(final PeerRole role) {
+ public synchronized PeerExportGroup getPeerGroup(final PeerRole role) {
return this.groups.get(Preconditions.checkNotNull(role));
}
@Override
- public PeerRole getRole(final YangInstanceIdentifier peerId) {
- return this.peerRoles.get(peerId);
- }
-
- private void processSupportedSendReceiveTables(final DataTreeCandidateNode sendReceiveModChild, final PeerId peerId) {
- if (sendReceiveModChild != null) {
- if (sendReceiveModChild.getModificationType().equals(ModificationType.DELETE)) {
- final Optional<NormalizedNode<?, ?>> sendReceiveNode = sendReceiveModChild.getDataBefore();
- if (sendReceiveNode.isPresent()) {
- final SendReceive sendReceiveValue = SendReceive.valueOf(BindingMapping.getClassName((String) sendReceiveNode.get().getValue()));
- this.peerAddPathTables.remove(peerId);
- LOG.debug("Supported Add BestPath table {} removed to peer {}", sendReceiveValue, peerId);
- }
- } else {
- final Optional<NormalizedNode<?, ?>> sendReceiveNode = sendReceiveModChild.getDataAfter();
- if (sendReceiveNode.isPresent()) {
- final SendReceive sendReceiveValue = SendReceive.valueOf(BindingMapping.getClassName((String) sendReceiveNode.get().getValue()));
- this.peerAddPathTables.put(peerId, sendReceiveValue);
- LOG.debug("Supported Add BestPath table {} added to peer {}", sendReceiveValue, peerId);
- }
- }
- }
+ public synchronized boolean isTableSupported(final PeerId peerId) {
+ return this.peerTables.contains(peerId);
}
@Override
- public boolean isTableSupported(final PeerId peerId) {
- return this.peerTables.contains(peerId);
+ public synchronized PeerRole getRole(final YangInstanceIdentifier peerId) {
+ return this.peerRoles.get(peerId);
}
@Override
- public boolean isAddPathSupportedByPeer(final PeerId peerId) {
+ public synchronized boolean isAddPathSupportedByPeer(final PeerId peerId) {
final SendReceive sendReceive = this.peerAddPathTables.get(peerId);
return sendReceive != null && (sendReceive.equals(SendReceive.Both) || sendReceive.equals(SendReceive.Receive));
}
+
}
\ No newline at end of file
*/
package org.opendaylight.protocol.bgp.rib.impl;
-import static org.opendaylight.protocol.bgp.rib.impl.AdjRibInWriter.SIMPLE_ROUTING_POLICY_NID;
-import static org.opendaylight.protocol.bgp.rib.spi.PeerRoleUtil.PEER_ROLE_NID;
-
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.primitives.UnsignedInteger;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.NotThreadSafe;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.protocol.bgp.mode.api.RouteEntry;
import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
import org.opendaylight.protocol.bgp.rib.impl.stats.UnsignedInt32Counter;
-import org.opendaylight.protocol.bgp.rib.spi.CacheDisconnectedPeers;
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.PeerRoleUtil;
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.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.rev130925.PeerId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.SimpleRoutingPolicy;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.LocRib;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.Peer;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.peer.EffectiveRibIn;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.peer.SupportedTables;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Attributes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Routes;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.BindingMapping;
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.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.api.schema.tree.ModificationType;
import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 static final NodeIdentifier EFFRIBIN_NID = new NodeIdentifier(EffectiveRibIn.QNAME);
- private static final NodeIdentifier TABLES_NID = new NodeIdentifier(Tables.QNAME);
- private static final NodeIdentifier PEER_TABLES = new NodeIdentifier(SupportedTables.QNAME);
private final Map<PathArgument, RouteEntry> routeEntries = new HashMap<>();
private final YangInstanceIdentifier locRibTarget;
private final DOMTransactionChain chain;
- private final ExportPolicyPeerTracker peerPolicyTracker;
+ private final ExportPolicyPeerTracker exportPolicyPeerTracker;
private final NodeIdentifier attributesIdentifier;
private final Long ourAs;
private final RIBSupport ribSupport;
- private final NodeIdentifierWithPredicates tableKey;
private final TablesKey localTablesKey;
private final ListenerRegistration<LocRibWriter> reg;
- private final CacheDisconnectedPeers cacheDisconnectedPeers;
private final PathSelectionMode pathSelectionMode;
private final UnsignedInt32Counter routeCounter;
- private LocRibWriter(final RIBSupportContextRegistry registry, final DOMTransactionChain chain, final YangInstanceIdentifier target, final Long ourAs,
- final DOMDataTreeChangeService service, final PolicyDatabase pd, final TablesKey tablesKey, final CacheDisconnectedPeers cacheDisconnectedPeers,
+ private LocRibWriter(final RIBSupportContextRegistry registry, final DOMTransactionChain chain, final YangInstanceIdentifier target,
+ final Long ourAs, final DOMDataTreeChangeService service, final ExportPolicyPeerTracker exportPolicyPeerTracker, final TablesKey tablesKey,
@Nonnull final PathSelectionMode pathSelectionMode, final UnsignedInt32Counter routeCounter) {
this.chain = Preconditions.checkNotNull(chain);
- this.tableKey = RibSupportUtils.toYangTablesKey(tablesKey);
+ final NodeIdentifierWithPredicates tableKey = RibSupportUtils.toYangTablesKey(tablesKey);
this.localTablesKey = tablesKey;
- this.locRibTarget = YangInstanceIdentifier.create(target.node(LocRib.QNAME).node(Tables.QNAME).node(this.tableKey).getPathArguments());
+ this.locRibTarget = YangInstanceIdentifier.create(target.node(LocRib.QNAME).node(Tables.QNAME).node(tableKey).getPathArguments());
this.ourAs = Preconditions.checkNotNull(ourAs);
this.ribSupport = registry.getRIBSupportContext(tablesKey).getRibSupport();
this.attributesIdentifier = this.ribSupport.routeAttributesIdentifier();
- this.peerPolicyTracker = new ExportPolicyPeerTrackerImpl(pd, this.localTablesKey);
- this.cacheDisconnectedPeers = cacheDisconnectedPeers;
+ this.exportPolicyPeerTracker = exportPolicyPeerTracker;
this.pathSelectionMode = pathSelectionMode;
this.routeCounter = routeCounter;
tx.merge(LogicalDatastoreType.OPERATIONAL, this.locRibTarget.node(Attributes.QNAME).node(ATTRIBUTES_UPTODATE_TRUE.getNodeType()), ATTRIBUTES_UPTODATE_TRUE);
tx.submit();
- final YangInstanceIdentifier tableId = target.node(Peer.QNAME).node(Peer.QNAME);
-
- this.reg = service.registerDataTreeChangeListener(new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, tableId), this);
+ final YangInstanceIdentifier tableId = target.node(Peer.QNAME).node(Peer.QNAME).node(EffectiveRibIn.QNAME).node(Tables.QNAME).node(tableKey);
+ final DOMDataTreeIdentifier wildcard = new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, tableId);
+ this.reg = service.registerDataTreeChangeListener(wildcard, this);
}
public static LocRibWriter create(@Nonnull final RIBSupportContextRegistry registry, @Nonnull final TablesKey tablesKey, @Nonnull final DOMTransactionChain chain,
- @Nonnull final YangInstanceIdentifier target, @Nonnull final AsNumber ourAs, @Nonnull final DOMDataTreeChangeService service, @Nonnull final PolicyDatabase pd,
- final CacheDisconnectedPeers cacheDisconnectedPeers, @Nonnull final PathSelectionMode pathSelectionStrategy, @Nonnull final UnsignedInt32Counter routeCounter) {
- return new LocRibWriter(registry, chain, target, ourAs.getValue(), service, pd, tablesKey, cacheDisconnectedPeers, pathSelectionStrategy, routeCounter);
+ @Nonnull final YangInstanceIdentifier target, @Nonnull final AsNumber ourAs, @Nonnull final DOMDataTreeChangeService service, @Nonnull final ExportPolicyPeerTracker ep,
+ @Nonnull final PathSelectionMode pathSelectionStrategy, @Nonnull final UnsignedInt32Counter routeCounter) {
+ return new LocRibWriter(registry, chain, target, ourAs.getValue(), service, ep, tablesKey, pathSelectionStrategy, routeCounter);
}
@Override
return ret;
}
+ /**
+ * We use two-stage processing here in hopes that we avoid duplicate
+ * calculations when multiple peers have changed a particular entry.
+ *
+ * @param changes on supported table
+ */
@Override
public void onDataTreeChanged(final Collection<DataTreeCandidate> changes) {
LOG.trace("Received data change {} to LocRib {}", changes, this);
final DOMDataWriteTransaction tx = this.chain.newWriteOnlyTransaction();
try {
- /*
- * We use two-stage processing here in hopes that we avoid duplicate
- * calculations when multiple peers have changed a particular entry.
- */
final Map<RouteUpdateKey, RouteEntry> toUpdate = update(tx, changes);
- // Now walk all updated entries
- walkThrough(tx, toUpdate);
+ if (!toUpdate.isEmpty()) {
+ walkThrough(tx, toUpdate.entrySet());
+ }
} catch (final Exception e) {
LOG.error("Failed to completely propagate updates {}, state is undefined", changes, e);
} finally {
private Map<RouteUpdateKey, RouteEntry> update(final DOMDataWriteTransaction tx, final Collection<DataTreeCandidate> changes) {
final Map<RouteUpdateKey, RouteEntry> ret = new HashMap<>();
-
- for (final DataTreeCandidate tc : changes) {
+ changes.forEach(tc -> {
+ final DataTreeCandidateNode table = tc.getRootNode();
final YangInstanceIdentifier rootPath = tc.getRootPath();
- final DataTreeCandidateNode rootNode = tc.getRootNode();
final PeerId peerId = IdentifierUtils.peerKeyToPeerId(rootPath);
-
- filterOutPeerRole(peerId, rootNode, rootPath);
- filterOutChangesToSupportedTables(peerId, rootNode);
- filterOutAnyChangeOutsideEffRibsIn(peerId, rootNode, ret, rootPath, tx);
- }
-
+ initializeTableWithExistentRoutes(table, peerId, rootPath, tx);
+ updateNodes(table, peerId, tx, ret);
+ });
return ret;
}
- private void filterOutAnyChangeOutsideEffRibsIn(final PeerId peerId, final DataTreeCandidateNode rootNode,
- final Map<RouteUpdateKey, RouteEntry> ret, final YangInstanceIdentifier rootPath, final DOMDataWriteTransaction tx) {
- final DataTreeCandidateNode ribIn = rootNode.getModifiedChild(EFFRIBIN_NID);
- if (ribIn == null) {
- LOG.trace("Skipping change {}", rootNode.getIdentifier());
- return;
- }
- final DataTreeCandidateNode table = ribIn.getModifiedChild(TABLES_NID).getModifiedChild(this.tableKey);
- if (table == null) {
- LOG.trace("Skipping change {}", rootNode.getIdentifier());
- return;
- }
- initializeTableWithExistentRoutes(table, peerId, rootPath, tx);
- updateNodes(table, peerId, tx, ret);
- }
-
- private void filterOutChangesToSupportedTables(final PeerId peerIdOfNewPeer, final DataTreeCandidateNode rootNode) {
- final DataTreeCandidateNode tablesChange = rootNode.getModifiedChild(PEER_TABLES);
- if (tablesChange != null) {
- this.peerPolicyTracker.onTablesChanged(peerIdOfNewPeer, tablesChange);
- }
- }
-
private void initializeTableWithExistentRoutes(final DataTreeCandidateNode table, final PeerId peerIdOfNewPeer, final YangInstanceIdentifier rootPath,
final DOMDataWriteTransaction tx) {
- if (!table.getDataBefore().isPresent() && this.peerPolicyTracker.isTableSupported(peerIdOfNewPeer)) {
+ if (!table.getDataBefore().isPresent() && this.exportPolicyPeerTracker.isTableSupported(peerIdOfNewPeer)) {
LOG.debug("Peer {} table has been created, inserting existent routes", peerIdOfNewPeer);
- final PeerRole newPeerRole = this.peerPolicyTracker.getRole(IdentifierUtils.peerPath(rootPath));
- final PeerExportGroup peerGroup = this.peerPolicyTracker.getPeerGroup(newPeerRole);
- this.routeEntries.entrySet().forEach(entry -> entry.getValue().writeRoute(peerIdOfNewPeer, entry.getKey(), rootPath, peerGroup,
- this.localTablesKey, this.peerPolicyTracker, this.ribSupport, this.cacheDisconnectedPeers, tx));
- }
- }
-
- private void filterOutPeerRole(final PeerId peerId, final DataTreeCandidateNode rootNode, final YangInstanceIdentifier rootPath) {
- final DataTreeCandidateNode roleChange = rootNode.getModifiedChild(PEER_ROLE_NID);
- if (roleChange != null) {
- if (rootNode.getModificationType() != ModificationType.DELETE) {
- this.cacheDisconnectedPeers.reconnected(peerId);
- }
-
- // Check for removal
- final Optional<NormalizedNode<?, ?>> maybePeerRole = roleChange.getDataAfter();
- final YangInstanceIdentifier peerPath = IdentifierUtils.peerPath(rootPath);
- LOG.debug("Data Changed for Peer role {} path {}, dataBefore {}, dataAfter {}", roleChange.getIdentifier(),
- peerPath , roleChange.getDataBefore(), maybePeerRole);
- final PeerRole role = PeerRoleUtil.roleForChange(maybePeerRole);
- final SimpleRoutingPolicy srp = getSimpleRoutingPolicy(rootNode);
- if(SimpleRoutingPolicy.AnnounceNone == srp) {
- return;
- }
- this.peerPolicyTracker.peerRoleChanged(peerPath, role);
- }
- }
-
- private SimpleRoutingPolicy getSimpleRoutingPolicy(final DataTreeCandidateNode rootNode) {
- final DataTreeCandidateNode statusChange = rootNode.getModifiedChild(SIMPLE_ROUTING_POLICY_NID);
- if (statusChange != null) {
- final Optional<NormalizedNode<?, ?>> maybePeerStatus = statusChange.getDataAfter();
- if (maybePeerStatus.isPresent()) {
- return SimpleRoutingPolicy.valueOf(BindingMapping.getClassName((String) (maybePeerStatus.get()).getValue()));
- }
+ final PeerRole newPeerRole = this.exportPolicyPeerTracker.getRole(IdentifierUtils.peerPath(rootPath));
+ final PeerExportGroup peerGroup = this.exportPolicyPeerTracker.getPeerGroup(newPeerRole);
+ this.routeEntries.entrySet().forEach(entry -> entry.getValue().writeRoute(peerIdOfNewPeer, entry.getKey(),
+ rootPath.getParent().getParent().getParent(), peerGroup, this.localTablesKey, this.exportPolicyPeerTracker, this.ribSupport, tx));
}
- return null;
}
private void updateNodes(final DataTreeCandidateNode table, final PeerId peerId, final DOMDataWriteTransaction tx,
routeCounter.setCount(this.routeEntries.size());
}
- private void walkThrough(final DOMDataWriteTransaction tx, final Map<RouteUpdateKey, RouteEntry> toUpdate) {
- for (final Map.Entry<RouteUpdateKey, RouteEntry> e : toUpdate.entrySet()) {
+ private void walkThrough(final DOMDataWriteTransaction tx, final Set<Map.Entry<RouteUpdateKey, RouteEntry>> toUpdate) {
+ for (final Map.Entry<RouteUpdateKey, RouteEntry> e : toUpdate) {
LOG.trace("Walking through {}", e);
final RouteEntry entry = e.getValue();
LOG.trace("Best path has not changed, continuing");
continue;
}
- entry.updateRoute(this.localTablesKey, this.peerPolicyTracker, this.locRibTarget, this.ribSupport, this.cacheDisconnectedPeers,
- tx, e.getKey().getRouteId());
+ entry.updateRoute(this.localTablesKey, this.exportPolicyPeerTracker, this.locRibTarget, this.ribSupport, tx, e.getKey().getRouteId());
}
}
}
import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Preconditions;
+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 java.util.ArrayList;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
import org.opendaylight.protocol.bgp.rib.impl.stats.rib.impl.BGPRenderStats;
import org.opendaylight.protocol.bgp.rib.impl.stats.rib.impl.RIBImplRuntimeMXBeanImpl;
-import org.opendaylight.protocol.bgp.rib.spi.CacheDisconnectedPeers;
+import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
import org.opendaylight.protocol.bgp.rib.spi.RibSupportUtils;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
private final CodecsRegistryImpl codecsRegistry;
private final ServiceGroupIdentifier serviceGroupIdentifier;
private final ClusterSingletonServiceProvider provider;
- private final PolicyDatabase policyDatabase;
private final BgpDeployer.WriteConfiguration configurationWriter;
private ClusterSingletonServiceRegistration registration;
private final DOMDataBrokerExtension service;
private final List<LocRibWriter> locRibs = new ArrayList<>();
- private final CacheDisconnectedPeers cacheDisconnectedPeers;
private final Map<TablesKey, PathSelectionMode> bestPathSelectionStrategies;
private final ImportPolicyPeerTracker importPolicyPeerTracker;
private final RIBImplRuntimeMXBeanImpl renderStats;
private final RibId ribId;
+ private final Map<TablesKey, ExportPolicyPeerTracker> exportPolicyPeerTrackerMap;
public RIBImpl(final ClusterSingletonServiceProvider provider, final RibId ribId, final AsNumber localAs, final BgpId localBgpId,
final ClusterIdentifier clusterId, final RIBExtensionConsumerContext extensions, final BGPDispatcher dispatcher,
this.ribContextRegistry = RIBSupportContextRegistryImpl.create(extensions, this.codecsRegistry);
final InstanceIdentifierBuilder yangRibIdBuilder = YangInstanceIdentifier.builder().node(BgpRib.QNAME).node(Rib.QNAME);
this.yangRibId = yangRibIdBuilder.nodeWithKey(Rib.QNAME, RIB_ID_QNAME, ribId.getValue()).build();
- this.cacheDisconnectedPeers = new CacheDisconnectedPeersImpl();
this.bestPathSelectionStrategies = Preconditions.checkNotNull(bestPathSelectionStrategies);
final ClusterIdentifier cId = (clusterId == null) ? new ClusterIdentifier(localBgpId) : clusterId;
this.renderStats = new RIBImplRuntimeMXBeanImpl(localBgpId, ribId, localAs, cId);
this.ribId = ribId;
- this.policyDatabase = new PolicyDatabase(this.localAs.getValue(), localBgpId, cId);
- this.importPolicyPeerTracker = new ImportPolicyPeerTrackerImpl( this.policyDatabase);
- this.serviceGroupIdentifier = ServiceGroupIdentifier.create(this.ribId + "-service-group");
+ final PolicyDatabase policyDatabase = new PolicyDatabase(this.localAs.getValue(), localBgpId, cId);
+ this.importPolicyPeerTracker = new ImportPolicyPeerTrackerImpl(policyDatabase);
+ this.serviceGroupIdentifier = ServiceGroupIdentifier.create(this.ribId.getValue() + "-service-group");
Preconditions.checkNotNull(provider, "ClusterSingletonServiceProvider is null");
this.provider = provider;
this.configurationWriter = configurationWriter;
+
+ 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();
+
LOG.info("RIB Singleton Service {} registered", getIdentifier());
//this need to be always the last step
this.registration = registerClusterSingletonService(this);
}
- private void startLocRib(final TablesKey key, final PolicyDatabase pd) {
+ private void startLocRib(final TablesKey key) {
LOG.debug("Creating LocRib table for {}", key);
// create locRibWriter for each table
final DOMDataWriteTransaction tx = this.domChain.newWriteOnlyTransaction();
pathSelectionStrategy = BasePathSelectionModeFactory.createBestPathSelectionStrategy();
}
- this.locRibs.add(LocRibWriter.create(this.ribContextRegistry, key, createPeerChain(this), getYangRibId(), this.localAs, getService(), pd,
- this.cacheDisconnectedPeers, pathSelectionStrategy, this.renderStats.getLocRibRouteCounter().init(key)));
+ this.locRibs.add(LocRibWriter.create(this.ribContextRegistry, key, createPeerChain(this), getYangRibId(), this.localAs, getService(),
+ this.exportPolicyPeerTrackerMap.get(key), pathSelectionStrategy, this.renderStats.getLocRibRouteCounter().init(key)));
}
@Override
public CodecsRegistry getCodecsRegistry() {
return this.codecsRegistry;
}
- @Override
- public CacheDisconnectedPeers getCacheDisconnectedPeers() {
- return this.cacheDisconnectedPeers;
- }
@Override
public ImportPolicyPeerTracker getImportPolicyPeerTracker() {
return this.importPolicyPeerTracker;
}
+ @Override
+ public ExportPolicyPeerTracker getExportPolicyPeerTracker(final TablesKey tablesKey) {
+ return this.exportPolicyPeerTrackerMap.get(tablesKey);
+ }
+
@Override
public void instantiateServiceInstance() {
if(this.configurationWriter != null) {
LOG.debug("Effective RIB created.");
- for (final BgpTableType t : this.localTables) {
- final TablesKey key = new TablesKey(t.getAfi(), t.getSafi());
- this.localTablesKeys.add(key);
- startLocRib(key, this.policyDatabase);
- }
+ this.localTablesKeys.forEach(this::startLocRib);
}
@Override
import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
import org.opendaylight.protocol.bgp.rib.impl.stats.rib.impl.BGPRenderStats;
-import org.opendaylight.protocol.bgp.rib.spi.CacheDisconnectedPeers;
+import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
return this.ribImpl.getCodecsRegistry();
}
- @Override
- public CacheDisconnectedPeers getCacheDisconnectedPeers() {
- return this.ribImpl.getCacheDisconnectedPeers();
- }
-
@Override
public DOMDataTreeChangeService getService() {
return this.ribImpl.getService();
return this.ribImpl.getImportPolicyPeerTracker();
}
+ @Override
+ public ExportPolicyPeerTracker getExportPolicyPeerTracker(final TablesKey tablesKey) {
+ return this.ribImpl.getExportPolicyPeerTracker(tablesKey);
+ }
+
@Override
public Set<TablesKey> getLocalTablesKeys() {
return this.ribImpl.getLocalTablesKeys();
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoop;
import io.netty.util.concurrent.DefaultPromise;
-import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GlobalEventExecutor;
import io.netty.util.concurrent.Promise;
import java.net.InetSocketAddress;
import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
import org.opendaylight.protocol.bgp.rib.RibReference;
import org.opendaylight.protocol.bgp.rib.impl.stats.rib.impl.BGPRenderStats;
-import org.opendaylight.protocol.bgp.rib.spi.CacheDisconnectedPeers;
+import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
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.multiprotocol.rev130919.BgpTableType;
CodecsRegistry getCodecsRegistry();
- /**
- * Return cache disconnected peers which allows us to avoid update
- * DS from a peer already disconnected, when multiple peers are disconnected
- * at the same time and their own exportPolicy has not been updated yet.
- * @return
- */
- CacheDisconnectedPeers getCacheDisconnectedPeers();
-
/**
* Return instance of DOMDataTreeChangeService, where consumer can register to
* listen on DOM data changes.
ImportPolicyPeerTracker getImportPolicyPeerTracker();
+ /**
+ * 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.
+ * @param tablesKey supported table
+ * @return ExportPolicyPeerTracker
+ */
+ ExportPolicyPeerTracker getExportPolicyPeerTracker(TablesKey tablesKey);
+
Set<TablesKey> getLocalTablesKeys();
/**
import static org.opendaylight.protocol.bgp.rib.spi.RouterIds.createPeerId;
import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.net.InetAddresses;
import io.netty.bootstrap.Bootstrap;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.ByteBufUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
-import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.epoll.Epoll;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import org.opendaylight.protocol.bgp.rib.spi.BGPSessionListener;
import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderContext;
import org.opendaylight.protocol.bgp.rib.spi.SimpleRIBExtensionProviderContext;
-import org.opendaylight.protocol.concepts.KeyMapping;
import org.opendaylight.protocol.util.InetSocketAddressUtil;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.attributes.LocalPrefBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.attributes.OriginBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.attributes.OriginatorIdBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.attributes.as.path.SegmentsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.message.WithdrawnRoutesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes1;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes1Builder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.CParameters1;
import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-public class AbstractAddPathTest extends AbstractDataBrokerTest {
-
- protected static final String RIB_ID = "127.0.0.1";
+class AbstractAddPathTest extends AbstractDataBrokerTest {
+ static final String RIB_ID = "127.0.0.1";
+ static final Ipv4Address PEER1 = new Ipv4Address("127.0.0.2");
+ static final Ipv4Address PEER2 = new Ipv4Address("127.0.0.3");
+ static final Ipv4Address PEER3 = new Ipv4Address("127.0.0.4");
+ static final Ipv4Address PEER4 = new Ipv4Address("127.0.0.5");
+ static final Ipv4Address PEER5 = new Ipv4Address("127.0.0.6");
+ static final Ipv4Address PEER6 = new Ipv4Address("127.0.0.7");
+ static final AsNumber AS_NUMBER = new AsNumber(72L);
+ static final int PORT = InetSocketAddressUtil.getRandomPort();
+ static final Ipv4Prefix PREFIX1 = new Ipv4Prefix("1.1.1.1/32");
private static final ClusterIdentifier CLUSTER_ID = new ClusterIdentifier(RIB_ID);
- protected static final Ipv4Address PEER1 = new Ipv4Address("127.0.0.2");
- protected static final Ipv4Address PEER2 = new Ipv4Address("127.0.0.3");
- protected static final Ipv4Address PEER3 = new Ipv4Address("127.0.0.4");
- protected static final Ipv4Address PEER4 = new Ipv4Address("127.0.0.5");
- protected static final Ipv4Address PEER5 = new Ipv4Address("127.0.0.6");
-
- protected static final PeerId PEER1_ID = createPeerId(PEER1);
- protected static final PeerId PEER2_ID = createPeerId(PEER2);
- protected static final PeerId PEER3_ID = createPeerId(PEER3);
- protected static final PeerId PEER4_ID = createPeerId(PEER4);
- protected static final PeerId PEER5_ID = createPeerId(PEER5);
-
- protected static final AsNumber AS_NUMBER = new AsNumber(72L);
- protected static final int HOLDTIMER = 180;
-
- protected static final int PORT = InetSocketAddressUtil.getRandomPort();
-
- protected static final Ipv4Prefix PREFIX1 = new Ipv4Prefix("1.1.1.1/32");
- protected static final Ipv4Address NH1 = new Ipv4Address("2.2.2.2");
- protected static final Update UPD_100 = createSimpleUpdate(PREFIX1, new PathId(1l), CLUSTER_ID, 100);
- protected static final Update UPD_50 = createSimpleUpdate(PREFIX1, new PathId(2l), CLUSTER_ID, 50);
- protected static final Update UPD_200 = createSimpleUpdate(PREFIX1, new PathId(3l), CLUSTER_ID, 200);
- protected static final Update UPD_20 = createSimpleUpdate(PREFIX1, new PathId(1l), CLUSTER_ID, 20);
-
- protected BindingToNormalizedNodeCodec mappingService;
- protected BGPDispatcherImpl dispatcher;
- protected RIBExtensionProviderContext ribExtension;
+ private static final PeerId PEER1_ID = createPeerId(PEER1);
+ private static final PeerId PEER2_ID = createPeerId(PEER2);
+ private static final PeerId PEER3_ID = createPeerId(PEER3);
+ private static final PeerId PEER4_ID = createPeerId(PEER4);
+ private static final PeerId PEER5_ID = createPeerId(PEER5);
+ private static final int HOLDTIMER = 2180;
+ private static final Ipv4Address NH1 = new Ipv4Address("2.2.2.2");
+ static final Update UPD_100 = createSimpleUpdate(PREFIX1, new PathId(1L), CLUSTER_ID, 100);
+ static final Update UPD_50 = createSimpleUpdate(PREFIX1, new PathId(2L), CLUSTER_ID, 50);
+ static final Update UPD_200 = createSimpleUpdate(PREFIX1, new PathId(3L), CLUSTER_ID, 200);
+ static final Update UPD_20 = createSimpleUpdate(PREFIX1, new PathId(1L), CLUSTER_ID, 20);
+ static final Update UPD_NA_100 = createSimpleUpdate(PREFIX1, null, CLUSTER_ID, 100);
+ static final Update UPD_NA_100_EBGP = createSimpleUpdateEbgp(PREFIX1, null);
+ static final Update UPD_NA_200 = createSimpleUpdate(PREFIX1, null, CLUSTER_ID, 200);
+ static final Update UPD_NA_200_EBGP = createSimpleUpdateEbgp(PREFIX1, null);
protected BGPExtensionProviderContext context;
protected SchemaContext schemaContext;
+ protected ClusterSingletonServiceProvider clusterSingletonServiceProvider;
+ BindingToNormalizedNodeCodec mappingService;
+ BGPDispatcherImpl dispatcher;
+ RIBExtensionProviderContext ribExtension;
private RIBActivator ribActivator;
private BGPActivator bgpActivator;
private NioEventLoopGroup worker;
private NioEventLoopGroup boss;
- protected ClusterSingletonServiceProvider clusterSingletonServiceProvider;
private org.opendaylight.protocol.bgp.inet.BGPActivator inetActivator;
@Before
this.inetActivator.start(this.context);
this.mappingService = new BindingToNormalizedNodeCodec(GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy(),
- new BindingNormalizedNodeCodecRegistry(StreamWriterGenerator.create(JavassistUtils.forClassPool(ClassPool.getDefault()))));
+ new BindingNormalizedNodeCodecRegistry(StreamWriterGenerator.create(JavassistUtils.forClassPool(ClassPool.getDefault()))));
final ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create();
moduleInfoBackedContext.registerModuleInfo(BindingReflections.getModuleInfo(BgpParameters.class));
moduleInfoBackedContext.registerModuleInfo(BindingReflections.getModuleInfo(MultiprotocolCapability.class));
this.dispatcher = new BGPDispatcherImpl(this.context.getMessageRegistry(), this.boss, this.worker);
this.clusterSingletonServiceProvider = Mockito.mock(ClusterSingletonServiceProvider.class);
- doReturn(Mockito.mock(ClusterSingletonServiceRegistration.class)).when(this.clusterSingletonServiceProvider).registerClusterSingletonService(any(ClusterSingletonService.class));
+ doReturn(Mockito.mock(ClusterSingletonServiceRegistration.class)).when(this.clusterSingletonServiceProvider)
+ .registerClusterSingletonService(any(ClusterSingletonService.class));
}
@After
}
}
- void sendRouteAndCheckIsOnDS(final Channel session, final Ipv4Prefix prefix, final long localPreference, final int expectedRoutesOnDS)
- throws InterruptedException, ExecutionException {
+ void sendRouteAndCheckIsOnLocRib(final Channel session, final Ipv4Prefix prefix, final long localPreference, final int expectedRoutesOnDS)
+ throws InterruptedException, ExecutionException {
session.writeAndFlush(createSimpleUpdate(prefix, null, null, localPreference));
Thread.sleep(2000);
+ checkLocRib(expectedRoutesOnDS);
+ }
+
+ void sendWithdrawalRouteAndCheckIsOnLocRib(final Channel session, final Ipv4Prefix prefix, final long localPreference, final int expectedRoutesOnDS)
+ throws InterruptedException, ExecutionException {
+ session.writeAndFlush(createSimpleWithdrawalUpdate(prefix, localPreference));
+ Thread.sleep(2000);
+ checkLocRib(expectedRoutesOnDS);
+ }
+
+ private void checkLocRib(final int expectedRoutesOnDS) throws ExecutionException, InterruptedException {
final ReadOnlyTransaction rTx = getDataBroker().newReadOnlyTransaction();
final BgpRib bgpRib = rTx.read(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(BgpRib.class)).get().get();
rTx.close();
}
Channel createPeerSession(final Ipv4Address peer, final PeerRole peerRole, final BgpParameters nonAddPathParams, final RIBImpl ribImpl,
- final BGPHandlerFactory hf, final SimpleSessionListener sessionListsner) throws InterruptedException, ExecutionException {
+ final BGPHandlerFactory hf, final SimpleSessionListener sessionListsner) throws InterruptedException, ExecutionException {
configurePeer(peer, ribImpl, nonAddPathParams, peerRole);
- return connectPeer(peer, ribImpl, nonAddPathParams, this.dispatcher, hf, sessionListsner);
+ return connectPeer(peer, nonAddPathParams, this.dispatcher, hf, sessionListsner);
}
private static int getPeerRibOutSize(final Peer peer) {
}
private static ChannelFuture createClient(final BGPDispatcherImpl dispatcher, final InetSocketAddress remoteAddress,
- final BGPPeerRegistry registry, final InetSocketAddress localAddress, final BGPHandlerFactory hf) throws InterruptedException {
+ final BGPPeerRegistry registry, final InetSocketAddress localAddress, final BGPHandlerFactory hf) throws InterruptedException {
final BGPClientSessionNegotiatorFactory snf = new BGPClientSessionNegotiatorFactory(registry);
- final Bootstrap bootstrap = dispatcher.createClientBootStrap(Optional.<KeyMapping>absent(), Epoll.isAvailable() ? new EpollEventLoopGroup() : new NioEventLoopGroup());
+ final Bootstrap bootstrap = dispatcher.createClientBootStrap(Optional.absent(), Epoll.isAvailable() ? new EpollEventLoopGroup() : new NioEventLoopGroup());
bootstrap.localAddress(localAddress);
bootstrap.option(ChannelOption.SO_REUSEADDR, true);
bootstrap.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(final SocketChannel ch) throws Exception {
ch.pipeline().addLast(hf.getDecoders());
- ch.pipeline().addLast("negotiator", snf.getSessionNegotiator(ch, new DefaultPromise<BGPSessionImpl>(ch.eventLoop())));
+ ch.pipeline().addLast("negotiator", snf.getSessionNegotiator(ch, new DefaultPromise<>(ch.eventLoop())));
ch.pipeline().addLast(hf.getEncoders());
}
});
final BGPPeer bgpPeer = new BGPPeer(inetAddress.getHostAddress(), ribImpl, peerRole, null);
final List<BgpParameters> tlvs = Lists.newArrayList(bgpParameters);
StrictBGPPeerRegistry.GLOBAL.addPeer(new IpAddress(new Ipv4Address(inetAddress.getHostAddress())), bgpPeer,
- new BGPSessionPreferences(AS_NUMBER, HOLDTIMER, new BgpId(RIB_ID),
- AS_NUMBER, tlvs, Optional.<byte[]>absent()));
+ new BGPSessionPreferences(AS_NUMBER, HOLDTIMER, new BgpId(RIB_ID),
+ AS_NUMBER, tlvs, Optional.absent()));
bgpPeer.instantiateServiceInstance();
}
- private static Channel connectPeer(final Ipv4Address localAddress, final RIBImpl ribImpl, final BgpParameters bgpParameters,
- final BGPDispatcherImpl dispatcherImpl, final BGPHandlerFactory hf, final BGPSessionListener sessionListsner) throws InterruptedException, ExecutionException {
+ private static Channel connectPeer(final Ipv4Address localAddress, final BgpParameters bgpParameters,
+ final BGPDispatcherImpl dispatcherImpl, final BGPHandlerFactory hf, final BGPSessionListener sessionListsner) throws InterruptedException {
final BGPPeerRegistry peerRegistry = new StrictBGPPeerRegistry();
peerRegistry.addPeer(new IpAddress(new Ipv4Address(RIB_ID)), sessionListsner,
- new BGPSessionPreferences(AS_NUMBER, HOLDTIMER, new BgpId(localAddress),
- AS_NUMBER, Lists.newArrayList(bgpParameters),Optional.<byte[]>absent()));
+ new BGPSessionPreferences(AS_NUMBER, HOLDTIMER, new BgpId(localAddress),
+ AS_NUMBER, Lists.newArrayList(bgpParameters), Optional.absent()));
final ChannelFuture createClient = createClient(dispatcherImpl, new InetSocketAddress(RIB_ID, PORT), peerRegistry, new InetSocketAddress(localAddress.getValue(), PORT), hf);
Thread.sleep(1000);
protected static BgpParameters createParameter(final boolean addPath) {
final OptionalCapabilities mp = new OptionalCapabilitiesBuilder().setCParameters(
- new CParametersBuilder().addAugmentation(CParameters1.class,
- new CParameters1Builder().setMultiprotocolCapability(
- new MultiprotocolCapabilityBuilder().setAfi(Ipv4AddressFamily.class).setSafi(UnicastSubsequentAddressFamily.class)
- .build()).build()).build()).build();
+ new CParametersBuilder().addAugmentation(CParameters1.class,
+ new CParameters1Builder().setMultiprotocolCapability(
+ new MultiprotocolCapabilityBuilder().setAfi(Ipv4AddressFamily.class).setSafi(UnicastSubsequentAddressFamily.class)
+ .build()).build()).build()).build();
final List<OptionalCapabilities> capabilities = Lists.newArrayList(mp);
if (addPath) {
final OptionalCapabilities addPathCapa = new OptionalCapabilitiesBuilder().setCParameters(
- new CParametersBuilder().addAugmentation(CParameters1.class,
- new CParameters1Builder().setAddPathCapability(
- new AddPathCapabilityBuilder().setAddressFamilies(Lists.newArrayList(
- new AddressFamiliesBuilder()
- .setAfi(Ipv4AddressFamily.class)
- .setSafi(UnicastSubsequentAddressFamily.class)
- .setSendReceive(SendReceive.Both)
- .build()))
- .build()).build()).build()).build();
+ new CParametersBuilder().addAugmentation(CParameters1.class,
+ new CParameters1Builder().setAddPathCapability(
+ new AddPathCapabilityBuilder().setAddressFamilies(Lists.newArrayList(
+ new AddressFamiliesBuilder()
+ .setAfi(Ipv4AddressFamily.class)
+ .setSafi(UnicastSubsequentAddressFamily.class)
+ .setSendReceive(SendReceive.Both)
+ .build()))
+ .build()).build()).build()).build();
capabilities.add(addPathCapa);
}
return new BgpParametersBuilder().setOptionalCapabilities(capabilities).build();
}
private static Update createSimpleUpdate(final Ipv4Prefix prefix, final PathId pathId, final ClusterIdentifier clusterId,
- final long localPreference) {
- final AttributesBuilder attBuilder = new AttributesBuilder();
+ final long localPreference) {
+ final AttributesBuilder attBuilder = new AttributesBuilder();
attBuilder.setLocalPref(new LocalPrefBuilder().setPref(localPreference).build());
attBuilder.setOrigin(new OriginBuilder().setValue(BgpOrigin.Igp).build());
attBuilder.setAsPath(new AsPathBuilder().setSegments(Collections.emptyList()).build());
attBuilder.setClusterId(new ClusterIdBuilder().setCluster(Collections.singletonList(clusterId)).build());
attBuilder.setOriginatorId(new OriginatorIdBuilder().setOriginator(new Ipv4Address(clusterId)).build());
}
+ addAttributeAugmentation(attBuilder, prefix, pathId);
+ return new UpdateBuilder().setAttributes(attBuilder.build()).build();
+ }
+
+ private static Update createSimpleUpdateEbgp(final Ipv4Prefix prefix, final PathId pathId) {
+ final AttributesBuilder attBuilder = new AttributesBuilder();
+ attBuilder.setOrigin(new OriginBuilder().setValue(BgpOrigin.Igp).build());
+ attBuilder.setAsPath(new AsPathBuilder().setSegments(Collections.singletonList(
+ new SegmentsBuilder().setAsSequence(Collections.singletonList(AS_NUMBER)).build())).build());
+ addAttributeAugmentation(attBuilder, prefix, pathId);
+
+ return new UpdateBuilder().setAttributes(attBuilder.build()).build();
+ }
+
+ private static void addAttributeAugmentation(final AttributesBuilder attBuilder, final Ipv4Prefix prefix, final PathId pathId) {
attBuilder.setUnrecognizedAttributes(Collections.emptyList());
attBuilder.addAugmentation(Attributes1.class,
- new Attributes1Builder().setMpReachNlri(
- new MpReachNlriBuilder()
- .setCNextHop(new Ipv4NextHopCaseBuilder().setIpv4NextHop(new Ipv4NextHopBuilder().setGlobal(NH1).build()).build())
- .setAfi(Ipv4AddressFamily.class)
- .setSafi(UnicastSubsequentAddressFamily.class)
- .setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
- new DestinationIpv4CaseBuilder().setDestinationIpv4(
- new DestinationIpv4Builder().setIpv4Prefixes(Collections.singletonList(
- new Ipv4PrefixesBuilder().setPathId(pathId).setPrefix(new Ipv4Prefix(prefix)).build())).build())
- .build()).build())
- .build()).build());
- return new UpdateBuilder().setAttributes(attBuilder.build()).build();
+ new Attributes1Builder().setMpReachNlri(
+ new MpReachNlriBuilder()
+ .setCNextHop(new Ipv4NextHopCaseBuilder().setIpv4NextHop(new Ipv4NextHopBuilder().setGlobal(NH1).build()).build())
+ .setAfi(Ipv4AddressFamily.class)
+ .setSafi(UnicastSubsequentAddressFamily.class)
+ .setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
+ new DestinationIpv4CaseBuilder().setDestinationIpv4(
+ new DestinationIpv4Builder().setIpv4Prefixes(Collections.singletonList(
+ new Ipv4PrefixesBuilder().setPathId(pathId).setPrefix(new Ipv4Prefix(prefix)).build())).build())
+ .build()).build())
+ .build()).build());
+ }
+
+ private static Update createSimpleWithdrawalUpdate(final Ipv4Prefix prefix, final long localPreference) {
+ final AttributesBuilder attBuilder = new AttributesBuilder();
+ attBuilder.setLocalPref(new LocalPrefBuilder().setPref(localPreference).build());
+ attBuilder.setOrigin(new OriginBuilder().setValue(BgpOrigin.Igp).build());
+ attBuilder.setAsPath(new AsPathBuilder().setSegments(Collections.emptyList()).build());
+ attBuilder.setUnrecognizedAttributes(Collections.emptyList());
+ return new UpdateBuilder().setWithdrawnRoutes(new WithdrawnRoutesBuilder().setWithdrawnRoutes(Collections.singletonList(prefix)).build()).build();
}
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpId;
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;
-import org.opendaylight.yangtools.yang.binding.Notification;
public class AddPathAllPathsTest extends AbstractAddPathTest {
/*
checkPeersPresentOnDataStore(5);
//the best route
- sendRouteAndCheckIsOnDS(session1, PREFIX1, 100, 1);
+ sendRouteAndCheckIsOnLocRib(session1, PREFIX1, 100, 1);
assertEquals(1, listener4.getListMsg().size());
assertEquals(1, listener5.getListMsg().size());
assertEquals(UPD_100, listener5.getListMsg().get(0));
+ final SimpleSessionListener listener6 = new SimpleSessionListener();
+ final Channel session6 = createPeerSession(PEER6, PeerRole.RrClient, nonAddPathParams, ribImpl, hf, listener6);
+ Thread.sleep(1000);
+ checkPeersPresentOnDataStore(6);
+ assertEquals(1, listener6.getListMsg().size());
+ assertEquals(UPD_NA_100, listener6.getListMsg().get(0));
+ session6.close();
+ Thread.sleep(1000);
+
//the second best route
- sendRouteAndCheckIsOnDS(session2, PREFIX1, 50, 2);
+ sendRouteAndCheckIsOnLocRib(session2, PREFIX1, 50, 2);
assertEquals(1, listener4.getListMsg().size());
assertEquals(2, listener5.getListMsg().size());
assertEquals(UPD_50, listener5.getListMsg().get(1));
//new best route
- sendRouteAndCheckIsOnDS(session3, PREFIX1, 200, 3);
+ sendRouteAndCheckIsOnLocRib(session3, PREFIX1, 200, 3);
assertEquals(2, listener4.getListMsg().size());
assertEquals(3, listener5.getListMsg().size());
assertEquals(UPD_200, listener5.getListMsg().get(2));
//the worst route
- sendRouteAndCheckIsOnDS(session1, PREFIX1, 20, 3);
+ sendRouteAndCheckIsOnLocRib(session1, PREFIX1, 20, 3);
assertEquals(2, listener4.getListMsg().size());
assertEquals(4, listener5.getListMsg().size());
assertEquals(UPD_200.getAttributes().getLocalPref(), ((Update) listener4.getListMsg().get(1)).getAttributes().getLocalPref());
assertEquals(UPD_20, listener5.getListMsg().get(3));
+ //withdraw second best route, 1 advertisement(1 withdrawal) for add-path supported, none for non add path
+ sendWithdrawalRouteAndCheckIsOnLocRib(session1, PREFIX1, 100, 2);
+ assertEquals(2, listener4.getListMsg().size());
+ assertEquals(5, listener5.getListMsg().size());
+
+ //we advertise again to try new test
+ sendRouteAndCheckIsOnLocRib(session1, PREFIX1, 100, 3);
+ assertEquals(2, listener4.getListMsg().size());
+ assertEquals(6, listener5.getListMsg().size());
+ assertEquals(UPD_200, listener5.getListMsg().get(2));
+
+ //withdraw second best route, 1 advertisement(1 withdrawal) for add-path supported, 1 for non add path (withdrawal)
+ sendWithdrawalRouteAndCheckIsOnLocRib(session3, PREFIX1, 200, 2);
+ assertEquals(3, listener4.getListMsg().size());
+ assertEquals(7, listener5.getListMsg().size());
+
session1.close();
session2.close();
session3.close();
session4.close();
session5.close();
+ Thread.sleep(1000);
}
}
--- /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.impl;
+
+import static org.junit.Assert.assertEquals;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import io.netty.channel.Channel;
+import java.net.InetSocketAddress;
+import java.util.List;
+import java.util.Map;
+import org.junit.Test;
+import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
+import org.opendaylight.protocol.bgp.mode.impl.base.BasePathSelectionModeFactory;
+import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.BgpParameters;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.RibId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpId;
+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 AddPathBasePathsTest extends AbstractAddPathTest {
+ /*
+ * Base-Paths
+ * ___________________
+ * | ODL BGP 127.0.0.1 |
+ * [peer://127.0.0.2; p1, lp100] --(iBGP)--> | | --(RR-client, non add-path) --> [Peer://127.0.0.5; (p1, lp100), (p1, lp1200)]
+ * [peer://127.0.0.3; p1, lp200] --(iBGP)--> | |
+ * [peer://127.0.0.4; p1, lp50] --(iBGP)--> | | --(eBgp, non add-path) --> [Peer://127.0.0.6; (p1, path-id1, lp100), (p1, path-id2, pl50), (p1, path-id3, pl200)]
+ * [peer://127.0.0.2; p1, lp20] --(iBGP)--> |___________________|
+ * p1 = 1.1.1.1/32
+ */
+ @Test
+ public void testUseCase1() throws Exception {
+
+ final List<BgpTableType> tables = ImmutableList.of(new BgpTableTypeImpl(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class));
+ final TablesKey tk = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
+ final Map<TablesKey, PathSelectionMode> pathTables = ImmutableMap.of(tk, BasePathSelectionModeFactory.createBestPathSelectionStrategy());
+
+ final RIBImpl ribImpl = new RIBImpl(this.clusterSingletonServiceProvider, new RibId("test-rib"), AS_NUMBER, new BgpId(RIB_ID), null, this.ribExtension,
+ this.dispatcher, this.mappingService.getCodecFactory(), getDomBroker(), tables, pathTables, this.ribExtension.getClassLoadingStrategy(), null);
+
+ ribImpl.instantiateServiceInstance();
+ ribImpl.onGlobalContextUpdated(this.schemaContext);
+
+ this.dispatcher.createServer(StrictBGPPeerRegistry.GLOBAL, new InetSocketAddress(RIB_ID, PORT)).sync();
+ Thread.sleep(1000);
+
+ final BGPHandlerFactory hf = new BGPHandlerFactory(this.context.getMessageRegistry());
+ final BgpParameters nonAddPathParams = createParameter(false);
+
+ final Channel session1 = createPeerSession(PEER1, PeerRole.Ibgp, nonAddPathParams, ribImpl, hf, new SimpleSessionListener());
+ final Channel session2 = createPeerSession(PEER2, PeerRole.Ibgp, nonAddPathParams, ribImpl, hf, new SimpleSessionListener());
+ final Channel session3 = createPeerSession(PEER3, PeerRole.Ibgp, nonAddPathParams, ribImpl, hf, new SimpleSessionListener());
+ final SimpleSessionListener listener4 = new SimpleSessionListener();
+ final Channel session4 = createPeerSession(PEER4, PeerRole.RrClient, nonAddPathParams, ribImpl, hf, listener4);
+ final SimpleSessionListener listener5 = new SimpleSessionListener();
+ final Channel session5 = createPeerSession(PEER5, PeerRole.Ebgp, nonAddPathParams, ribImpl, hf, listener5);
+ Thread.sleep(1000);
+ checkPeersPresentOnDataStore(5);
+
+ //new best route so far
+ sendRouteAndCheckIsOnLocRib(session1, PREFIX1, 100, 1);
+ assertEquals(1, listener4.getListMsg().size());
+ assertEquals(1, listener5.getListMsg().size());
+ assertEquals(UPD_NA_100, listener4.getListMsg().get(0));
+ assertEquals(UPD_NA_100_EBGP, listener5.getListMsg().get(0));
+
+ //the second best route
+ sendRouteAndCheckIsOnLocRib(session2, PREFIX1, 50, 1);
+ assertEquals(1, listener4.getListMsg().size());
+ assertEquals(1, listener5.getListMsg().size());
+
+ //new best route
+ sendRouteAndCheckIsOnLocRib(session3, PREFIX1, 200, 1);
+ assertEquals(2, listener4.getListMsg().size());
+ assertEquals(2, listener5.getListMsg().size());
+ assertEquals(UPD_NA_200, listener4.getListMsg().get(1));
+ assertEquals(UPD_NA_200_EBGP, listener5.getListMsg().get(1));
+
+ final SimpleSessionListener listener6 = new SimpleSessionListener();
+ final Channel session6 = createPeerSession(PEER6, PeerRole.RrClient, nonAddPathParams, ribImpl, hf, listener6);
+ Thread.sleep(1000);
+ checkPeersPresentOnDataStore(6);
+ assertEquals(1, listener6.getListMsg().size());
+ assertEquals(UPD_NA_200, listener6.getListMsg().get(0));
+ Thread.sleep(1000);
+ session6.close();
+ Thread.sleep(1000);
+
+ //best route updated to be the worse one
+ sendRouteAndCheckIsOnLocRib(session3, PREFIX1, 20, 1);
+ assertEquals(3, listener4.getListMsg().size());
+ assertEquals(3, listener5.getListMsg().size());
+ assertEquals(UPD_NA_100, listener4.getListMsg().get(2));
+ assertEquals(UPD_NA_100_EBGP, listener5.getListMsg().get(2));
+
+ //Remove second best, no advertisement should be done
+ sendWithdrawalRouteAndCheckIsOnLocRib(session2, PREFIX1, 50, 1);
+ assertEquals(3, listener4.getListMsg().size());
+ assertEquals(3, listener5.getListMsg().size());
+
+ //Remove best, 1 advertisement
+ sendWithdrawalRouteAndCheckIsOnLocRib(session1, PREFIX1, 100, 1);
+ assertEquals(4, listener4.getListMsg().size());
+ assertEquals(4, listener5.getListMsg().size());
+
+ //Remove best, 1 withdrawal
+ sendWithdrawalRouteAndCheckIsOnLocRib(session3, PREFIX1, 20, 0);
+ assertEquals(5, listener4.getListMsg().size());
+ assertEquals(5, listener5.getListMsg().size());
+
+ session1.close();
+ session2.close();
+ session3.close();
+ session4.close();
+ session5.close();
+ Thread.sleep(1000);
+ }
+}
checkPeersPresentOnDataStore(5);
//new best route so far
- sendRouteAndCheckIsOnDS(session1, PREFIX1, 100, 1);
+ sendRouteAndCheckIsOnLocRib(session1, PREFIX1, 100, 1);
assertEquals(1, listener4.getListMsg().size());
assertEquals(1, listener5.getListMsg().size());
assertEquals(UPD_100, listener5.getListMsg().get(0));
+ final SimpleSessionListener listener6 = new SimpleSessionListener();
+ final Channel session6 = createPeerSession(PEER6, PeerRole.RrClient, nonAddPathParams, ribImpl, hf, listener6);
+ Thread.sleep(1000);
+ checkPeersPresentOnDataStore(6);
+ assertEquals(1, listener6.getListMsg().size());
+ assertEquals(UPD_NA_100, listener6.getListMsg().get(0));
+ session6.close();
+ Thread.sleep(1000);
+
//the second best route
- sendRouteAndCheckIsOnDS(session2, PREFIX1, 50, 2);
+ sendRouteAndCheckIsOnLocRib(session2, PREFIX1, 50, 2);
assertEquals(1, listener4.getListMsg().size());
assertEquals(2, listener5.getListMsg().size());
assertEquals(UPD_50, listener5.getListMsg().get(1));
//new best route
- sendRouteAndCheckIsOnDS(session3, PREFIX1, 200, 2);
+ sendRouteAndCheckIsOnLocRib(session3, PREFIX1, 200, 2);
assertEquals(2, listener4.getListMsg().size());
assertEquals(3, listener5.getListMsg().size());
assertEquals(UPD_200, listener5.getListMsg().get(2));
//the worst prefix, no changes
- sendRouteAndCheckIsOnDS(session2, PREFIX1, 20, 2);
+ sendRouteAndCheckIsOnLocRib(session2, PREFIX1, 20, 2);
assertEquals(2, listener4.getListMsg().size());
assertEquals(3, listener5.getListMsg().size());
+ //withdraw second best route, 2 advertisement (1 withdrawal) for add-path supported, none for non add path
+ sendWithdrawalRouteAndCheckIsOnLocRib(session1, PREFIX1, 100, 2);
+ assertEquals(2, listener4.getListMsg().size());
+ assertEquals(5, listener5.getListMsg().size());
+
+ //we advertise again to try new test
+ sendRouteAndCheckIsOnLocRib(session1, PREFIX1, 100, 2);
+ assertEquals(2, listener4.getListMsg().size());
+ assertEquals(6, listener5.getListMsg().size());
+
+ //withdraw second best route, 2 advertisement (1 withdrawal) for add-path supported, 1 withdrawal for non add path
+ sendWithdrawalRouteAndCheckIsOnLocRib(session3, PREFIX1, 200, 2);
+ assertEquals(3, listener4.getListMsg().size());
+ assertEquals(8, listener5.getListMsg().size());
+
session1.close();
session2.close();
session3.close();
session4.close();
session5.close();
+ Thread.sleep(1000);
}
}
import com.google.common.util.concurrent.CheckedFuture;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.junit.Before;
private AdjRibInWriter writer;
- private static final TablesKey k4 = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
- private final Set<TablesKey> tableTypes = Sets.newHashSet(k4);
+ private static final TablesKey K4 = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
+ private final Set<TablesKey> tableTypes = Sets.newHashSet(K4);
- private static final AddressFamilies addressFamilies = new AddressFamiliesBuilder().setAfi(Ipv4AddressFamily.class)
+ private static final AddressFamilies ADDRESS_FAMILIES = new AddressFamiliesBuilder().setAfi(Ipv4AddressFamily.class)
.setSafi(UnicastSubsequentAddressFamily.class).setSendReceive(SendReceive.Both).build();
- private final List<AddressFamilies> addPathTablesType = Collections.singletonList(addressFamilies);
+ private final List<AddressFamilies> addPathTablesType = Collections.singletonList(ADDRESS_FAMILIES);
+ private static final Map<TablesKey, SendReceive> ADD_PATH_TABLE_MAPS = Collections.singletonMap(K4, SendReceive.Both);
+
private final String peerIp = "12.34.56.78";
@Before
assertNotNull(this.writer);
final YangInstanceIdentifier peerPath = YangInstanceIdentifier.builder().node(Rib.QNAME).node(Peer.QNAME).nodeWithKey(Peer.QNAME,
AdjRibInWriter.PEER_ID_QNAME, this.peerIp).build();
- this.writer.transform(new PeerId(this.peerIp), this.registry, this.tableTypes, this.addPathTablesType);
+ this.writer.transform(new PeerId(this.peerIp), this.registry, this.tableTypes, ADD_PATH_TABLE_MAPS);
verifyPeerSkeletonInsertedCorrectly(peerPath);
// verify supported tables were inserted for ipv4
- Mockito.verify(this.tx).put(Mockito.eq(LogicalDatastoreType.OPERATIONAL), Mockito.eq(peerPath.node(SupportedTables.QNAME).node(RibSupportUtils.toYangKey(SupportedTables.QNAME, k4))), Mockito.any(NormalizedNode.class));
+ Mockito.verify(this.tx).put(Mockito.eq(LogicalDatastoreType.OPERATIONAL), Mockito.eq(peerPath.node(SupportedTables.QNAME)
+ .node(RibSupportUtils.toYangKey(SupportedTables.QNAME, K4))), Mockito.any(NormalizedNode.class));
verifyUptodateSetToFalse(peerPath);
}
private void verifyUptodateSetToFalse(final YangInstanceIdentifier peerPath) {
- final YangInstanceIdentifier path = peerPath.node(AdjRibIn.QNAME).node(Tables.QNAME).node(RibSupportUtils.toYangTablesKey(k4))
+ final YangInstanceIdentifier path = peerPath.node(AdjRibIn.QNAME).node(Tables.QNAME).node(RibSupportUtils.toYangTablesKey(K4))
.node(Attributes.QNAME).node(AdjRibInWriter.ATTRIBUTES_UPTODATE_FALSE.getNodeType());
Mockito.verify(this.tx).merge(Mockito.eq(LogicalDatastoreType.OPERATIONAL), Mockito.eq(path), Mockito.eq(AdjRibInWriter.ATTRIBUTES_UPTODATE_FALSE));
}
assertNotNull(this.writer);
final YangInstanceIdentifier peerPath = YangInstanceIdentifier.builder().node(Rib.QNAME).node(Peer.QNAME).nodeWithKey(Peer.QNAME,
AdjRibInWriter.PEER_ID_QNAME, this.peerIp).build();
- this.writer.transform(new PeerId(this.peerIp), this.registry, this.tableTypes, this.addPathTablesType);
+ this.writer.transform(new PeerId(this.peerIp), this.registry, this.tableTypes, ADD_PATH_TABLE_MAPS);
verifyPeerSkeletonInsertedCorrectly(peerPath);
// verify supported tables were not inserted for ipv4, AnnounceNone
- Mockito.verify(this.tx, never()).put(Mockito.eq(LogicalDatastoreType.OPERATIONAL), Mockito.eq(peerPath.node(SupportedTables.QNAME).node(RibSupportUtils.toYangKey(SupportedTables.QNAME, k4))), Mockito.any(NormalizedNode.class));
+ Mockito.verify(this.tx, never()).put(Mockito.eq(LogicalDatastoreType.OPERATIONAL), Mockito.eq(peerPath.node(SupportedTables.QNAME)
+ .node(RibSupportUtils.toYangKey(SupportedTables.QNAME, K4))), Mockito.any(NormalizedNode.class));
verifyUptodateSetToFalse(peerPath);
}
--- /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.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.opendaylight.controller.md.sal.binding.impl.BindingDOMMountPointServiceAdapter.LOG;
+import static org.opendaylight.protocol.bgp.rib.impl.AdjRibInWriter.PEER_ID_QNAME;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.SendReceive;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.BgpRib;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.SimpleRoutingPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.Peer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
+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;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+public class ExportPolicyPeerTrackerImplTest {
+ private static final TablesKey TABLE_KEY = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
+ private static final Ipv4Address BGP_ID = new Ipv4Address("127.0.0.1");
+ private static final PolicyDatabase PD = new PolicyDatabase(72L, BGP_ID, new ClusterIdentifier(BGP_ID));
+ private static final PeerId PEER_ID1 = new PeerId("bgp://42.42.42.42");
+ private static final YangInstanceIdentifier YII_PEER1 = YangInstanceIdentifier.builder().node(BgpRib.QNAME).node(Peer.QNAME)
+ .nodeWithKey(Peer.QNAME, PEER_ID_QNAME, PEER_ID1.getValue()).build();
+ private static final PeerId PEER_ID2 = new PeerId("bgp://42.42.42.43");
+ private static final YangInstanceIdentifier YII_PEER2 = YangInstanceIdentifier.builder().node(BgpRib.QNAME).node(Peer.QNAME)
+ .nodeWithKey(Peer.QNAME, PEER_ID_QNAME, PEER_ID2.getValue()).build();
+ private static final PeerId PEER_ID3 = new PeerId("bgp://42.42.42.44");
+ private static final YangInstanceIdentifier YII_PEER3 = YangInstanceIdentifier.builder().node(BgpRib.QNAME).node(Peer.QNAME)
+ .nodeWithKey(Peer.QNAME, PEER_ID_QNAME, PEER_ID3.getValue()).build();
+ private static final PeerId PEER_ID4 = new PeerId("bgp://42.42.42.45");
+ private static final YangInstanceIdentifier YII_PEER4 = YangInstanceIdentifier.builder().node(BgpRib.QNAME).node(Peer.QNAME)
+ .nodeWithKey(Peer.QNAME, PEER_ID_QNAME, PEER_ID4.getValue()).build();
+ private static final PeerId PEER_ID5 = new PeerId("bgp://42.42.42.46");
+ private final static List<AutoCloseable> TABLE_REGISTRATION = new ArrayList<>();
+
+ @Test
+ public void testExportPolicyPeerTrackerImpl() throws Exception {
+ final ExportPolicyPeerTrackerImpl exportPpt = new ExportPolicyPeerTrackerImpl(PD, TABLE_KEY);
+
+ TABLE_REGISTRATION.add(exportPpt.registerPeer(PEER_ID1, SendReceive.Both, YII_PEER1, PeerRole.RrClient, Optional.empty()));
+ TABLE_REGISTRATION.add(exportPpt.registerPeer(PEER_ID2, SendReceive.Receive, YII_PEER2, PeerRole.Ibgp, Optional.of(SimpleRoutingPolicy.AnnounceNone)));
+ TABLE_REGISTRATION.add(exportPpt.registerPeer(PEER_ID3, SendReceive.Send, YII_PEER3, PeerRole.Ebgp, Optional.of(SimpleRoutingPolicy.LearnNone)));
+ TABLE_REGISTRATION.add(exportPpt.registerPeer(PEER_ID4, null, YII_PEER4, PeerRole.Ibgp, Optional.empty()));
+
+ assertEquals(PeerRole.RrClient, exportPpt.getRole(YII_PEER1));
+ assertEquals(PeerRole.Ibgp, exportPpt.getRole(YII_PEER2));
+ assertEquals(PeerRole.Ebgp, exportPpt.getRole(YII_PEER3));
+ assertEquals(PeerRole.Ibgp, exportPpt.getRole(YII_PEER4));
+
+ assertTrue(exportPpt.getPeerGroup(PeerRole.RrClient).containsPeer(PEER_ID1));
+ assertTrue(exportPpt.getPeerGroup(PeerRole.Ibgp).containsPeer(PEER_ID2));
+ assertTrue(exportPpt.getPeerGroup(PeerRole.Ebgp).containsPeer(PEER_ID3));
+ assertTrue(exportPpt.getPeerGroup(PeerRole.Ibgp).containsPeer(PEER_ID4));
+
+ assertTrue(exportPpt.isTableSupported(PEER_ID1));
+ assertFalse(exportPpt.isTableSupported(PEER_ID2));
+ assertTrue(exportPpt.isTableSupported(PEER_ID3));
+ assertTrue(exportPpt.isTableSupported(PEER_ID4));
+ assertFalse(exportPpt.isTableSupported(PEER_ID5));
+
+ assertTrue(exportPpt.isAddPathSupportedByPeer(PEER_ID1));
+ assertTrue(exportPpt.isAddPathSupportedByPeer(PEER_ID2));
+ assertFalse(exportPpt.isAddPathSupportedByPeer(PEER_ID3));
+ assertFalse(exportPpt.isAddPathSupportedByPeer(PEER_ID4));
+ assertFalse(exportPpt.isAddPathSupportedByPeer(PEER_ID5));
+
+ TABLE_REGISTRATION.remove(0).close();
+ assertNull(exportPpt.getRole(YII_PEER1));
+ assertNull(exportPpt.getPeerGroup(PeerRole.RrClient));
+ assertFalse(exportPpt.isTableSupported(PEER_ID1));
+ assertFalse(exportPpt.isAddPathSupportedByPeer(PEER_ID1));
+
+
+ TABLE_REGISTRATION.get(0).close();
+ assertNull(exportPpt.getRole(YII_PEER2));
+ assertFalse(exportPpt.getPeerGroup(PeerRole.Ibgp).containsPeer(PEER_ID2));
+ assertFalse(exportPpt.isTableSupported(PEER_ID2));
+ assertFalse(exportPpt.isAddPathSupportedByPeer(PEER_ID2));
+
+ for (final AutoCloseable tableCloseable : TABLE_REGISTRATION) {
+ try {
+ tableCloseable.close();
+ } catch (final Exception e) {
+ LOG.warn("Failed to close registration", e);
+ }
+ }
+ TABLE_REGISTRATION.clear();
+ }
+
+}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.protocol.bgp.rib.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.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.protocol.bgp.rib.impl.AbstractRIBTestSetup.PREFIX_QNAME;
-import static org.opendaylight.protocol.bgp.rib.spi.PeerRoleUtil.PEER_ROLE_NID;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.CheckedFuture;
-import java.util.ArrayList;
-import java.util.List;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.stubbing.Answer;
-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.inet.RIBActivator;
-import org.opendaylight.protocol.bgp.mode.impl.base.BasePathSelectionModeFactory;
-import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContext;
-import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
-import org.opendaylight.protocol.bgp.rib.impl.stats.UnsignedInt32Counter;
-import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderContext;
-import org.opendaylight.protocol.bgp.rib.spi.RibSupportUtils;
-import org.opendaylight.protocol.bgp.rib.spi.SimpleRIBExtensionProviderContext;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.routes.ipv4.routes.Ipv4Route;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.BgpRib;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.Peer;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.peer.EffectiveRibIn;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.peer.SupportedTables;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
-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;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-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.api.schema.tree.ModificationType;
-
-public class LocRibWriterTest {
-
- @Mock
- DOMDataWriteTransaction domTransWrite;
-
- private final PolicyDatabase pd = new PolicyDatabase((long) 35, new Ipv4Address("10.25.2.9"), new ClusterIdentifier(new Ipv4Address("10.25.2.9")));
-
- @Mock
- private RIBSupportContextRegistry registry;
-
- @Mock
- private DOMTransactionChain chain;
-
- @Mock
- private DOMDataTreeChangeService service;
-
- @Mock
- private RIBSupportContext context;
-
- @Mock
- CheckedFuture<?, ?> future;
-
- private LocRibWriter locRibWriter;
-
- private final List<YangInstanceIdentifier> routes = new ArrayList<>();
- private final TablesKey tablesKey = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
- private final UnsignedInt32Counter routeCounter = new UnsignedInt32Counter("loc-rib");
-
- private RIBActivator ribActivator;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
-
- this.ribActivator = new RIBActivator();
- final RIBExtensionProviderContext ribExtension = new SimpleRIBExtensionProviderContext();
- this.ribActivator.startRIBExtensionProvider(ribExtension);
-
- final Answer<Object> answer = invocation -> {
- final Object[] args = invocation.getArguments();
- final NormalizedNode<?, ?> node = (NormalizedNode<?, ?>) args[2];
- if (node.getNodeType().equals(Ipv4Route.QNAME) || node.getNodeType().equals(PREFIX_QNAME)) {
- LocRibWriterTest.this.routes.add((YangInstanceIdentifier) args[1]);
- }
- return args[1];
- };
- doAnswer(answer).when(this.domTransWrite).put(eq(LogicalDatastoreType.OPERATIONAL), any(YangInstanceIdentifier.class), any(NormalizedNode.class));
- doAnswer(answer).when(this.domTransWrite).merge(eq(LogicalDatastoreType.OPERATIONAL), any(YangInstanceIdentifier.class), any(NormalizedNode.class));
- doAnswer(invocation -> {
- final Object[] args = invocation.getArguments();
- LocRibWriterTest.this.routes.remove(args[1]);
- return args[1];
- }).when(this.domTransWrite).delete(eq(LogicalDatastoreType.OPERATIONAL), any(YangInstanceIdentifier.class));
- doReturn(this.context).when(this.registry).getRIBSupportContext(any(TablesKey.class));
- doReturn(ribExtension.getRIBSupport(this.tablesKey)).when(this.context).getRibSupport();
- doReturn(this.domTransWrite).when(this.chain).newWriteOnlyTransaction();
- doReturn(this.future).when(this.domTransWrite).submit();
- doReturn(null).when(this.service).registerDataTreeChangeListener(any(DOMDataTreeIdentifier.class), any(ClusteredDOMDataTreeChangeListener.class));
- this.locRibWriter = LocRibWriter.create(this.registry, this.tablesKey, this.chain, YangInstanceIdentifier.of(BgpRib.QNAME),
- new AsNumber((long) 35), this.service, this.pd, new CacheDisconnectedPeersImpl(), BasePathSelectionModeFactory.createBestPathSelectionStrategy(),
- this.routeCounter);
- }
-
- private DataTreeCandidate prepareUpdate() {
- final DataTreeCandidate candidate = mock(DataTreeCandidate.class);
- doReturn("candidate").when(candidate).toString();
- final YangInstanceIdentifier rootPath = YangInstanceIdentifier.builder().node(BgpRib.QNAME).node(Peer.QNAME).nodeWithKey(Peer.QNAME, AdjRibInWriter.PEER_ID_QNAME, "12.12.12.12").build();
- doReturn(rootPath).when(candidate).getRootPath();
- return candidate;
- }
-
- @Test
- public void testUpdateSupportedTables() {
- final DataTreeCandidate candidate = prepareUpdate();
- final DataTreeCandidateNode node = mock(DataTreeCandidateNode.class);
- doReturn("node").when(node).toString();
- final DataTreeCandidateNode tableChange = mock(DataTreeCandidateNode.class);
- // add
- final DataTreeCandidateNode table = mock(DataTreeCandidateNode.class);
- final NormalizedNode<?, ?> dataAfter = mock(NormalizedNode.class);
- doReturn(RibSupportUtils.toYangTablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class)).when(dataAfter).getIdentifier();
- doReturn(Optional.of(dataAfter)).when(table).getDataAfter();
- doReturn(Lists.newArrayList(table)).when(tableChange).getChildNodes();
- doReturn("table change").when(tableChange).toString();
- doReturn(tableChange).when(node).getModifiedChild(YangInstanceIdentifier.of(SupportedTables.QNAME).getLastPathArgument());
- doReturn(null).when(node).getModifiedChild(PEER_ROLE_NID);
- doReturn(null).when(node).getModifiedChild(YangInstanceIdentifier.of(EffectiveRibIn.QNAME).getLastPathArgument());
- doReturn(node).when(candidate).getRootNode();
- doReturn(ModificationType.SUBTREE_MODIFIED).when(node).getModificationType();
- this.locRibWriter.onDataTreeChanged(Lists.newArrayList(candidate));
- // delete
- final DataTreeCandidateNode tableDelete = mock(DataTreeCandidateNode.class);
- doReturn(Optional.absent()).when(tableDelete).getDataAfter();
- doReturn(Lists.newArrayList(tableDelete)).when(tableChange).getChildNodes();
- doReturn("table change").when(tableChange).toString();
- doReturn(node).when(candidate).getRootNode();
- this.locRibWriter.onDataTreeChanged(Lists.newArrayList(candidate));
- verify(node, times(2)).getModifiedChild(YangInstanceIdentifier.of(SupportedTables.QNAME).getLastPathArgument());
- }
-}
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
+
import com.google.common.collect.Lists;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
private BGPSessionImpl session;
- private Map<YangInstanceIdentifier, NormalizedNode<?,?>> routes;
+ private Map<YangInstanceIdentifier, NormalizedNode<?, ?>> routes;
private BGPPeer classic;
@Override
public Object answer(final InvocationOnMock invocation) throws Throwable {
final Object[] args = invocation.getArguments();
- final NormalizedNode<?,?>node = (NormalizedNode<?,?>)args[2];
+ final NormalizedNode<?, ?> node = (NormalizedNode<?, ?>) args[2];
if (node.getIdentifier().getNodeType().equals(Ipv4Route.QNAME) || node.getNodeType().equals(PREFIX_QNAME)) {
PeerTest.this.routes.put((YangInstanceIdentifier) args[1], node);
}
}).when(getTransaction()).delete(Mockito.eq(LogicalDatastoreType.OPERATIONAL), Mockito.any(YangInstanceIdentifier.class));
}
-
@Test
public void testAppPeer() {
final Ipv4Prefix first = new Ipv4Prefix("127.0.0.2/32");
assertEquals("testPeer", this.classic.getName());
this.classic.onSessionUp(this.session);
assertEquals(1, this.classic.getBgpPeerState().getSessionEstablishedCount().getValue().intValue());
- Assert.assertArrayEquals(new byte[] {1, 1, 1, 1}, this.classic.getRawIdentifier());
+ Assert.assertArrayEquals(new byte[]{1, 1, 1, 1}, this.classic.getRawIdentifier());
assertEquals("BGPPeer{name=testPeer, tables=[TablesKey [_afi=class org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily, _safi=class org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily]]}", this.classic.toString());
final List<Ipv4Prefix> prefs = Lists.newArrayList(new Ipv4Prefix("8.0.1.0/28"), new Ipv4Prefix("127.0.0.1/32"), new Ipv4Prefix("2.2.2.2/24"));
assertEquals(BGPError.MANDATORY_ATTR_MISSING_MSG + "LOCAL_PREF", e.getMessage());
assertEquals(BGPError.WELL_KNOWN_ATTR_MISSING.getCode(), e.getError().getCode());
assertEquals(BGPError.WELL_KNOWN_ATTR_MISSING.getSubcode(), e.getError().getSubcode());
- assertArrayEquals(new byte[] { LocalPreferenceAttributeParser.TYPE }, e.getData());
+ assertArrayEquals(new byte[]{LocalPreferenceAttributeParser.TYPE}, e.getData());
}
assertEquals(0, this.routes.size());
- final LocalPref localPref = new LocalPrefBuilder().setPref((long)100).build();
+ final LocalPref localPref = new LocalPrefBuilder().setPref((long) 100).build();
ub.setAttributes(ab.setLocalPref(localPref).build());
this.classic.onMessage(this.session, ub.build());
assertEquals(3, this.routes.size());
this.classic.onMessage(this.session, new KeepaliveBuilder().build());
this.classic.onMessage(this.session, new UpdateBuilder().setAttributes(
new AttributesBuilder().addAugmentation(
- Attributes2.class,
- new Attributes2Builder().setMpUnreachNlri(
- new MpUnreachNlriBuilder().setAfi(AFI).setSafi(SAFI).build()).build()).build()).build());
+ Attributes2.class,
+ new Attributes2Builder().setMpUnreachNlri(
+ new MpUnreachNlriBuilder().setAfi(AFI).setSafi(SAFI).build()).build()).build()).build());
this.classic.onMessage(this.session, new RouteRefreshBuilder().setAfi(AFI).setSafi(SAFI).build());
this.classic.onMessage(this.session, new RouteRefreshBuilder().setAfi(Ipv6AddressFamily.class).setSafi(SAFI).build());
assertEquals(2, this.routes.size());
this.singletonService.instantiateServiceInstance();
Mockito.verify(this.configurationWriter).apply();
- Mockito.verify(this.rib, times(2)).getRibSupportContext();
+ Mockito.verify(this.rib).getRibSupportContext();
Mockito.verify(this.rib).getLocalTablesKeys();
Mockito.verify(this.domTx).newWriteOnlyTransaction();
import com.google.common.collect.ImmutableList;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.annotation.Nonnull;
import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
import org.opendaylight.protocol.bgp.rib.impl.stats.rib.impl.BGPRenderStats;
-import org.opendaylight.protocol.bgp.rib.spi.CacheDisconnectedPeers;
+import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafiBuilder;
}
@Override
- public CacheDisconnectedPeers getCacheDisconnectedPeers() {
+ public DOMDataTreeChangeService getService() {
return null;
}
@Override
- public DOMDataTreeChangeService getService() {
+ public BGPRenderStats getRenderStats() {
return null;
}
@Override
- public BGPRenderStats getRenderStats() {
+ public ImportPolicyPeerTracker getImportPolicyPeerTracker() {
return null;
}
@Override
- public ImportPolicyPeerTracker getImportPolicyPeerTracker() {
+ public ExportPolicyPeerTracker getExportPolicyPeerTracker(final TablesKey tablesKey) {
return null;
}
this.singletonService.instantiateServiceInstance();
Mockito.verify(this.configurationWriter).apply();
assertEquals("RIBImpl{}", ribImpl.toString());
- assertEquals(ServiceGroupIdentifier.create(new RibId("rib-test") + "-service-group"), ribImpl.getRibIServiceGroupIdentifier());
+ assertEquals(ServiceGroupIdentifier.create("rib-test-service-group"), ribImpl.getRibIServiceGroupIdentifier());
assertEquals(Collections.singleton(new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class)), ribImpl.getLocalTablesKeys());
assertNotNull(ribImpl.getImportPolicyPeerTracker());
assertNotNull(ribImpl.getService());
- assertNotNull(ribImpl.getCacheDisconnectedPeers());
assertNotNull(ribImpl.getInstanceIdentifier());
assertEquals(AS, ribImpl.getLocalAs());
assertEquals(BGP_ID, ribImpl.getBgpIdentifier());
+++ /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 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerId;
-
-public interface CacheDisconnectedPeers {
-
- /**
- * Check whether Peer is inside the cache List
- *
- * @param peerId of destination peer
- * @return True if peer is contained on CacheList
- */
- boolean isPeerDisconnected(PeerId peerId);
-
- /**
- * Remove Peer from cache in case of reconnection
- *
- * @param peerId of reconnected peer
- */
- void reconnected(PeerId peerId);
-
- /**
- * Add to cache list disconnected peer
- *
- * @param peerId of disconnected peer
- */
- void insertDesconectedPeer(Ipv4Address peerId);
-}
package org.opendaylight.protocol.bgp.rib.spi;
+import java.util.Optional;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import org.opendaylight.protocol.concepts.AbstractRegistration;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.SendReceive;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.SimpleRoutingPolicy;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
* @param peerId which receveid the change
* @param node data change
*/
- void onTablesChanged(PeerId peerId, DataTreeCandidateNode node);
+ @Deprecated
+ default void onTablesChanged(PeerId peerId, DataTreeCandidateNode node) {}
+
+ /**
+ * Register Peer
+ * @param peerId Peer Id
+ * @param sendReceive send receive add ath configuration of the peer
+ * @param peerPath Yii of the peer
+ * @param peerRole Role of the peer
+ * @param simpleRoutingPolicy
+ */
+ AbstractRegistration registerPeer(@Nonnull PeerId peerId, @Nullable SendReceive sendReceive, @Nonnull YangInstanceIdentifier peerPath, @Nonnull PeerRole peerRole,
+ @Nonnull Optional<SimpleRoutingPolicy> simpleRoutingPolicy);
/**
* returns PeerExportGroup per role
* @param role of desired PeerExportGroup
* @return PeerExportGroup
*/
- PeerExportGroup getPeerGroup(PeerRole role);
+ PeerExportGroup getPeerGroup(@Nonnull PeerRole role);
/**
* check whether the peer supports the table
* @param peerId of peer
* @return true if peer supports table
*/
- boolean isTableSupported(PeerId peerId);
+ boolean isTableSupported(@Nonnull PeerId peerId);
/**
* @param peerId of peer
* @return Role of peer
*/
- PeerRole getRole(YangInstanceIdentifier peerId);
+ PeerRole getRole(@Nonnull YangInstanceIdentifier peerId);
/**
* Check whether Peer supports Add Path
* @param peerId
* @return true if add-path is supported
*/
- boolean isAddPathSupportedByPeer(PeerId peerId);
+ boolean isAddPathSupportedByPeer(@Nonnull PeerId peerId);
/**
* Invoked whenever a peer role changes.
* @param peerPath Peer's path
* @param role Peer's new role, null indicates the peer has disappeared.
*/
- void peerRoleChanged(@Nonnull YangInstanceIdentifier peerPath, @Nullable PeerRole role);
+ @Deprecated
+ default void peerRoleChanged(@Nonnull YangInstanceIdentifier peerPath, @Nullable PeerRole role) {
+ }
}