From d7a1cb6b14d397b673bbff9183e51178388b7423 Mon Sep 17 00:00:00 2001 From: "Claudio D. Gasparini" Date: Tue, 20 Sep 2016 11:23:38 +0200 Subject: [PATCH] BUG-6747: Race condition on peer connection 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 --- .../protocol/bgp/mode/api/RouteEntry.java | 6 +- .../impl/add/AddPathAbstractRouteEntry.java | 31 ++- .../impl/base/BaseAbstractRouteEntry.java | 29 ++- .../bgp/mode/spi/AbstractRouteEntry.java | 7 +- .../bgp/mode/impl/AbstractRouteEntryTest.java | 9 - .../add/all/paths/SimpleRouteEntryTest.java | 4 +- .../add/n/paths/SimpleRouteEntryTest.java | 8 +- .../mode/impl/base/BaseRouteEntryTest.java | 10 +- .../protocol/bgp/rib/impl/AdjRibInWriter.java | 15 +- .../bgp/rib/impl/ApplicationPeer.java | 32 ++- .../protocol/bgp/rib/impl/BGPPeer.java | 50 +++-- .../rib/impl/CacheDisconnectedPeersImpl.java | 41 ---- .../rib/impl/ExportPolicyPeerTrackerImpl.java | 142 +++++-------- .../protocol/bgp/rib/impl/LocRibWriter.java | 141 ++++--------- .../protocol/bgp/rib/impl/RIBImpl.java | 44 ++-- .../protocol/bgp/rib/impl/config/RibImpl.java | 12 +- .../protocol/BGPProtocolSessionPromise.java | 1 - .../protocol/bgp/rib/impl/spi/RIB.java | 19 +- .../bgp/rib/impl/AbstractAddPathTest.java | 188 ++++++++++-------- .../bgp/rib/impl/AddPathAllPathsTest.java | 35 +++- .../bgp/rib/impl/AddPathBasePathsTest.java | 130 ++++++++++++ .../bgp/rib/impl/AddPathNPathsTest.java | 33 ++- .../bgp/rib/impl/AdjRibsInWriterTest.java | 23 ++- .../impl/ExportPolicyPeerTrackerImplTest.java | 110 ++++++++++ .../bgp/rib/impl/LocRibWriterTest.java | 160 --------------- .../protocol/bgp/rib/impl/PeerTest.java | 18 +- .../bgp/rib/impl/config/AppPeerTest.java | 2 +- .../config/OpenConfigMappingUtilTest.java | 11 +- .../bgp/rib/impl/config/RibImplTest.java | 3 +- .../bgp/rib/spi/CacheDisconnectedPeers.java | 36 ---- .../bgp/rib/spi/ExportPolicyPeerTracker.java | 30 ++- 31 files changed, 698 insertions(+), 682 deletions(-) delete mode 100644 bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/CacheDisconnectedPeersImpl.java create mode 100644 bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AddPathBasePathsTest.java create mode 100644 bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/ExportPolicyPeerTrackerImplTest.java delete mode 100644 bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/LocRibWriterTest.java delete mode 100644 bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/CacheDisconnectedPeers.java diff --git a/bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/api/RouteEntry.java b/bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/api/RouteEntry.java index a0a3c4e6b4..a5902c0e84 100644 --- a/bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/api/RouteEntry.java +++ b/bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/api/RouteEntry.java @@ -10,7 +10,6 @@ package org.opendaylight.protocol.bgp.mode.api; 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; @@ -72,12 +71,11 @@ public interface RouteEntry { * @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 @@ -90,5 +88,5 @@ public interface RouteEntry { * @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 diff --git a/bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/impl/add/AddPathAbstractRouteEntry.java b/bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/impl/add/AddPathAbstractRouteEntry.java index cc664dc647..b16feb38a0 100644 --- a/bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/impl/add/AddPathAbstractRouteEntry.java +++ b/bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/impl/add/AddPathAbstractRouteEntry.java @@ -18,7 +18,6 @@ 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.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; @@ -119,42 +118,39 @@ public abstract class AddPathAbstractRouteEntry extends AbstractRouteEntry { } @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)); } @@ -173,8 +169,7 @@ public abstract class AddPathAbstractRouteEntry extends AbstractRouteEntry { } 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); @@ -182,12 +177,12 @@ public abstract class AddPathAbstractRouteEntry extends AbstractRouteEntry { 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 @@ -204,7 +199,7 @@ public abstract class AddPathAbstractRouteEntry extends AbstractRouteEntry { for (final Map.Entry 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, diff --git a/bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/impl/base/BaseAbstractRouteEntry.java b/bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/impl/base/BaseAbstractRouteEntry.java index 7c2b8b8cc6..62a02f3db4 100644 --- a/bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/impl/base/BaseAbstractRouteEntry.java +++ b/bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/impl/base/BaseAbstractRouteEntry.java @@ -14,7 +14,6 @@ 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.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; @@ -104,33 +103,32 @@ abstract class BaseAbstractRouteEntry extends AbstractRouteEntry { @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); @@ -139,12 +137,11 @@ abstract class BaseAbstractRouteEntry extends AbstractRouteEntry { 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); @@ -158,7 +155,7 @@ abstract class BaseAbstractRouteEntry extends AbstractRouteEntry { 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() { @@ -168,7 +165,7 @@ abstract class BaseAbstractRouteEntry extends AbstractRouteEntry { @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 @@ -183,7 +180,7 @@ abstract class BaseAbstractRouteEntry extends AbstractRouteEntry { 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)); } } diff --git a/bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/spi/AbstractRouteEntry.java b/bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/spi/AbstractRouteEntry.java index 1a58a0df19..4add989b69 100644 --- a/bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/spi/AbstractRouteEntry.java +++ b/bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/spi/AbstractRouteEntry.java @@ -11,7 +11,6 @@ package org.opendaylight.protocol.bgp.mode.spi; 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; @@ -55,10 +54,8 @@ public abstract class AbstractRouteEntry implements RouteEntry { 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) { diff --git a/bgp/path-selection-mode/src/test/java/org/opendaylight/protocol/bgp/mode/impl/AbstractRouteEntryTest.java b/bgp/path-selection-mode/src/test/java/org/opendaylight/protocol/bgp/mode/impl/AbstractRouteEntryTest.java index 85fe15e6d4..cffac05f5c 100644 --- a/bgp/path-selection-mode/src/test/java/org/opendaylight/protocol/bgp/mode/impl/AbstractRouteEntryTest.java +++ b/bgp/path-selection-mode/src/test/java/org/opendaylight/protocol/bgp/mode/impl/AbstractRouteEntryTest.java @@ -25,7 +25,6 @@ import org.mockito.invocation.InvocationOnMock; 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; @@ -91,7 +90,6 @@ public class AbstractRouteEntryTest { protected ExportPolicyPeerTracker peerPT; @Mock protected PeerExportGroup peg; - protected CacheDisconnectedPeers discCache; protected List yIIChanges; protected NormalizedNode attributes; protected YangInstanceIdentifier routePaYii; @@ -113,7 +111,6 @@ public class AbstractRouteEntryTest { 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); @@ -131,12 +128,6 @@ public class AbstractRouteEntryTest { 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() { diff --git a/bgp/path-selection-mode/src/test/java/org/opendaylight/protocol/bgp/mode/impl/add/all/paths/SimpleRouteEntryTest.java b/bgp/path-selection-mode/src/test/java/org/opendaylight/protocol/bgp/mode/impl/add/all/paths/SimpleRouteEntryTest.java index dbf03d79e3..1680f268bb 100644 --- a/bgp/path-selection-mode/src/test/java/org/opendaylight/protocol/bgp/mode/impl/add/all/paths/SimpleRouteEntryTest.java +++ b/bgp/path-selection-mode/src/test/java/org/opendaylight/protocol/bgp/mode/impl/add/all/paths/SimpleRouteEntryTest.java @@ -39,7 +39,7 @@ public final class SimpleRouteEntryTest extends AbstractRouteEntryTest { 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 yiiCount = this.yIIChanges.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); assertEquals(3, yiiCount.size()); assertEquals(1, (long) yiiCount.get(this.routePaAddPathYii)); @@ -53,7 +53,7 @@ public final class SimpleRouteEntryTest extends AbstractRouteEntryTest { 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)); diff --git a/bgp/path-selection-mode/src/test/java/org/opendaylight/protocol/bgp/mode/impl/add/n/paths/SimpleRouteEntryTest.java b/bgp/path-selection-mode/src/test/java/org/opendaylight/protocol/bgp/mode/impl/add/n/paths/SimpleRouteEntryTest.java index 092bb4a16a..eec2d48c7c 100644 --- a/bgp/path-selection-mode/src/test/java/org/opendaylight/protocol/bgp/mode/impl/add/n/paths/SimpleRouteEntryTest.java +++ b/bgp/path-selection-mode/src/test/java/org/opendaylight/protocol/bgp/mode/impl/add/n/paths/SimpleRouteEntryTest.java @@ -45,7 +45,7 @@ public final class SimpleRouteEntryTest extends AbstractRouteEntryTest { } 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()); } @@ -54,7 +54,7 @@ public final class SimpleRouteEntryTest extends AbstractRouteEntryTest { 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 yiiCount = this.yIIChanges.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); assertEquals(3, yiiCount.size()); assertEquals(1, (long) yiiCount.get(this.routePaAddPathYii)); @@ -69,7 +69,7 @@ public final class SimpleRouteEntryTest extends AbstractRouteEntryTest { 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 yiiCount = this.yIIChanges.stream() .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); @@ -83,7 +83,7 @@ public final class SimpleRouteEntryTest extends AbstractRouteEntryTest { 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)); diff --git a/bgp/path-selection-mode/src/test/java/org/opendaylight/protocol/bgp/mode/impl/base/BaseRouteEntryTest.java b/bgp/path-selection-mode/src/test/java/org/opendaylight/protocol/bgp/mode/impl/base/BaseRouteEntryTest.java index a297a4dc45..9df001c705 100644 --- a/bgp/path-selection-mode/src/test/java/org/opendaylight/protocol/bgp/mode/impl/base/BaseRouteEntryTest.java +++ b/bgp/path-selection-mode/src/test/java/org/opendaylight/protocol/bgp/mode/impl/base/BaseRouteEntryTest.java @@ -44,14 +44,14 @@ public class BaseRouteEntryTest extends AbstractRouteEntryTest { 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 yiiCount = this.yIIChanges.stream() .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); @@ -69,13 +69,13 @@ public class BaseRouteEntryTest extends AbstractRouteEntryTest { 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 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)); @@ -84,7 +84,7 @@ public class BaseRouteEntryTest extends AbstractRouteEntryTest { } 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 diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/AdjRibInWriter.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/AdjRibInWriter.java index 85ba578f35..0f778f62f6 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/AdjRibInWriter.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/AdjRibInWriter.java @@ -12,12 +12,10 @@ import com.google.common.base.Preconditions; 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; @@ -30,7 +28,6 @@ import org.opendaylight.protocol.bgp.rib.spi.IdentifierUtils; 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; @@ -129,7 +126,7 @@ final class AdjRibInWriter { * @return New writer */ AdjRibInWriter transform(final PeerId newPeerId, final RIBSupportContextRegistry registry, final Set tableTypes, - final List addPathTablesType) { + final Map addPathTablesType) { final DOMDataWriteTransaction tx = this.chain.newWriteOnlyTransaction(); final YangInstanceIdentifier newPeerPath; @@ -150,10 +147,9 @@ final class AdjRibInWriter { * @return */ private ImmutableMap createNewTableInstances(final YangInstanceIdentifier newPeerPath, - final RIBSupportContextRegistry registry, final Set tableTypes, final List addPathTablesType, + final RIBSupportContextRegistry registry, final Set tableTypes, final Map addPathTablesType, final DOMDataWriteTransaction tx) { - final Map addPathTableMaps = mapTableTypesFamilies(addPathTablesType); final Builder tb = ImmutableMap.builder(); for (final TablesKey tableKey : tableTypes) { final RIBSupportContext rs = registry.getRIBSupportContext(tableKey); @@ -163,17 +159,12 @@ final class AdjRibInWriter { 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 mapTableTypesFamilies(final List 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 tb) { // We will use table keys very often, make sure they are optimized diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ApplicationPeer.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ApplicationPeer.java index 7ed275f93f..ae6e3dc629 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ApplicationPeer.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ApplicationPeer.java @@ -14,6 +14,7 @@ import java.util.Arrays; 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; @@ -22,15 +23,19 @@ import org.opendaylight.controller.md.sal.dom.api.ClusteredDOMDataTreeChangeList 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; @@ -66,7 +71,7 @@ public class ApplicationPeer implements AutoCloseable, org.opendaylight.protocol 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(); @@ -82,12 +87,23 @@ public class ApplicationPeer implements AutoCloseable, org.opendaylight.protocol 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 = Optional.of(SimpleRoutingPolicy.AnnounceNone); + final PeerId peerId = RouterIds.createPeerId(this.ipAddress); + final Set 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); } /** @@ -188,8 +204,8 @@ public class ApplicationPeer implements AutoCloseable, org.opendaylight.protocol 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(); diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPPeer.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPPeer.java index da0c276682..42995e6985 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPPeer.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPPeer.java @@ -13,6 +13,7 @@ import static org.opendaylight.protocol.bgp.rib.impl.AdjRibInWriter.isLearnNone; 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; @@ -47,9 +48,11 @@ import org.opendaylight.protocol.bgp.rib.impl.stats.peer.BGPSessionStats; 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; @@ -58,7 +61,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet 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; @@ -114,6 +120,8 @@ public class BGPPeer implements BGPSessionListener, Peer, AutoCloseable, BGPPeer private final PeerRole peerRole; private final Optional simpleRoutingPolicy; private final BGPPeerStats peerStats; + private YangInstanceIdentifier peerIId; + private final Set tableRegistration = new HashSet<>(); public BGPPeer(final String name, final RIB rib, final PeerRole role, final SimpleRoutingPolicy peerStatus, final RpcProviderRegistry rpcRegistry) { this.peerRole = role; @@ -279,26 +287,37 @@ public class BGPPeer implements BGPSessionListener, Peer, AutoCloseable, BGPPeer @Override public synchronized void onSessionUp(final BGPSession session) { final List addPathTablesType = session.getAdvertisedAddPathTableTypes(); - LOG.info("Session with peer {} went up with tables {} and Add Path tables {}", this.name, addPathTablesType, - session.getAdvertisedAddPathTableTypes()); + final Set 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 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(); @@ -334,7 +353,8 @@ public class BGPPeer implements BGPSessionListener, Peer, AutoCloseable, BGPPeer // 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))); } } @@ -389,15 +409,16 @@ public class BGPPeer implements BGPSessionListener, Peer, AutoCloseable, BGPPeer 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() { @@ -465,4 +486,9 @@ public class BGPPeer implements BGPSessionListener, Peer, AutoCloseable, BGPPeer public void markUptodate(final TablesKey tablesKey) { this.ribWriter.markTableUptodate(tablesKey); } + + private static Map mapTableTypesFamilies(final List addPathTablesType) { + return ImmutableMap.copyOf(addPathTablesType.stream().collect(Collectors.toMap(af -> new TablesKey(af.getAfi(), af.getSafi()), + BgpAddPathTableType::getSendReceive))); + } } diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/CacheDisconnectedPeersImpl.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/CacheDisconnectedPeersImpl.java deleted file mode 100644 index 39c523ac3e..0000000000 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/CacheDisconnectedPeersImpl.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 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); - } -} diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ExportPolicyPeerTrackerImpl.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ExportPolicyPeerTrackerImpl.java index ec61de5ea1..4d5bbdbbb8 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ExportPolicyPeerTrackerImpl.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ExportPolicyPeerTrackerImpl.java @@ -10,47 +10,42 @@ package org.opendaylight.protocol.bgp.rib.impl; 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 peerRoles = new HashMap<>(); - private final Set peerTables = Sets.newHashSet(); - private final PolicyDatabase policyDatabase; + @GuardedBy("this") private final Map peerAddPathTables = new HashMap<>(); + @GuardedBy("this") + private final Set peerTables = new HashSet<>(); + private final PolicyDatabase policyDatabase; private final TablesKey localTableKey; private volatile Map groups = Collections.emptyMap(); @@ -59,99 +54,70 @@ final class ExportPolicyPeerTrackerImpl implements ExportPolicyPeerTracker { this.localTableKey = localTablesKey; } - private Map createGroups(final Map peerPathRoles) { - if (peerPathRoles.isEmpty()) { - return Collections.emptyMap(); - } - - final Map> 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 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 peerPathRoles) { + if (!peerPathRoles.isEmpty()) { + final Map> 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 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> 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> 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> 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 diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/LocRibWriter.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/LocRibWriter.java index 08ca796877..3cbd173c11 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/LocRibWriter.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/LocRibWriter.java @@ -7,15 +7,13 @@ */ 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; @@ -28,28 +26,23 @@ import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode; import org.opendaylight.protocol.bgp.mode.api.RouteEntry; import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry; import org.opendaylight.protocol.bgp.rib.impl.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; @@ -59,7 +52,6 @@ import org.opendaylight.yangtools.yang.data.api.schema.LeafNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate; import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode; -import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType; import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -70,36 +62,30 @@ final class LocRibWriter implements AutoCloseable, ClusteredDOMDataTreeChangeLis private static final Logger LOG = LoggerFactory.getLogger(LocRibWriter.class); private static final LeafNode 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 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 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; @@ -108,15 +94,15 @@ final class LocRibWriter implements AutoCloseable, ClusteredDOMDataTreeChangeLis 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 @@ -134,20 +120,23 @@ final class LocRibWriter implements AutoCloseable, ClusteredDOMDataTreeChangeLis 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 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 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 { @@ -157,84 +146,25 @@ final class LocRibWriter implements AutoCloseable, ClusteredDOMDataTreeChangeLis private Map update(final DOMDataWriteTransaction tx, final Collection changes) { final Map 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 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> 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> 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, @@ -284,8 +214,8 @@ final class LocRibWriter implements AutoCloseable, ClusteredDOMDataTreeChangeLis routeCounter.setCount(this.routeEntries.size()); } - private void walkThrough(final DOMDataWriteTransaction tx, final Map toUpdate) { - for (final Map.Entry e : toUpdate.entrySet()) { + private void walkThrough(final DOMDataWriteTransaction tx, final Set> toUpdate) { + for (final Map.Entry e : toUpdate) { LOG.trace("Walking through {}", e); final RouteEntry entry = e.getValue(); @@ -293,8 +223,7 @@ final class LocRibWriter implements AutoCloseable, ClusteredDOMDataTreeChangeLis 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()); } } } diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/RIBImpl.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/RIBImpl.java index 842e92c4b4..c35d0e8b1e 100755 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/RIBImpl.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/RIBImpl.java @@ -10,10 +10,12 @@ package org.opendaylight.protocol.bgp.rib.impl; 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; @@ -47,7 +49,7 @@ 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.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; @@ -99,16 +101,15 @@ public final class RIBImpl extends DefaultRibReference implements ClusterSinglet 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 locRibs = new ArrayList<>(); - private final CacheDisconnectedPeers cacheDisconnectedPeers; private final Map bestPathSelectionStrategies; private final ImportPolicyPeerTracker importPolicyPeerTracker; private final RIBImplRuntimeMXBeanImpl renderStats; private final RibId ribId; + private final Map exportPolicyPeerTrackerMap; public RIBImpl(final ClusterSingletonServiceProvider provider, final RibId ribId, final AsNumber localAs, final BgpId localBgpId, final ClusterIdentifier clusterId, final RIBExtensionConsumerContext extensions, final BGPDispatcher dispatcher, @@ -130,23 +131,31 @@ public final class RIBImpl extends DefaultRibReference implements ClusterSinglet 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 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(); @@ -177,8 +186,8 @@ public final class RIBImpl extends DefaultRibReference implements ClusterSinglet 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 @@ -276,16 +285,17 @@ public final class RIBImpl extends DefaultRibReference implements ClusterSinglet 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) { @@ -320,11 +330,7 @@ public final class RIBImpl extends DefaultRibReference implements ClusterSinglet 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 diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/RibImpl.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/RibImpl.java index 9c93fcf1a7..b025939d74 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/RibImpl.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/RibImpl.java @@ -35,7 +35,7 @@ import org.opendaylight.protocol.bgp.rib.impl.spi.ImportPolicyPeerTracker; 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; @@ -148,11 +148,6 @@ public final class RibImpl implements RIB, AutoCloseable { return this.ribImpl.getCodecsRegistry(); } - @Override - public CacheDisconnectedPeers getCacheDisconnectedPeers() { - return this.ribImpl.getCacheDisconnectedPeers(); - } - @Override public DOMDataTreeChangeService getService() { return this.ribImpl.getService(); @@ -196,6 +191,11 @@ public final class RibImpl implements RIB, AutoCloseable { return this.ribImpl.getImportPolicyPeerTracker(); } + @Override + public ExportPolicyPeerTracker getExportPolicyPeerTracker(final TablesKey tablesKey) { + return this.ribImpl.getExportPolicyPeerTracker(tablesKey); + } + @Override public Set getLocalTablesKeys() { return this.ribImpl.getLocalTablesKeys(); diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/protocol/BGPProtocolSessionPromise.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/protocol/BGPProtocolSessionPromise.java index 64c943c88c..b3e5bba736 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/protocol/BGPProtocolSessionPromise.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/protocol/BGPProtocolSessionPromise.java @@ -14,7 +14,6 @@ import io.netty.channel.ChannelFutureListener; 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; diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/RIB.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/RIB.java index f2070c64f2..1bd93d33ab 100755 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/RIB.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/RIB.java @@ -16,7 +16,7 @@ import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvid 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; @@ -75,14 +75,6 @@ public interface RIB extends RibReference, ClusterSingletonServiceProvider { 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. @@ -94,6 +86,15 @@ public interface RIB extends RibReference, ClusterSingletonServiceProvider { 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 getLocalTablesKeys(); /** diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AbstractAddPathTest.java b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AbstractAddPathTest.java index d082574606..adf18c3b4d 100644 --- a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AbstractAddPathTest.java +++ b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AbstractAddPathTest.java @@ -12,18 +12,13 @@ import static org.mockito.Mockito.doReturn; 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; @@ -55,7 +50,6 @@ import org.opendaylight.protocol.bgp.rib.impl.spi.BGPSessionPreferences; 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; @@ -81,6 +75,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mess 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; @@ -114,44 +110,43 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; 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 @@ -168,7 +163,7 @@ public class AbstractAddPathTest extends AbstractDataBrokerTest { 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)); @@ -185,7 +180,8 @@ public class AbstractAddPathTest extends AbstractDataBrokerTest { 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 @@ -223,11 +219,22 @@ public class AbstractAddPathTest extends AbstractDataBrokerTest { } } - 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(); @@ -247,9 +254,9 @@ public class AbstractAddPathTest extends AbstractDataBrokerTest { } 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) { @@ -257,17 +264,17 @@ public class AbstractAddPathTest extends AbstractDataBrokerTest { } 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.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() { @Override protected void initChannel(final SocketChannel ch) throws Exception { ch.pipeline().addLast(hf.getDecoders()); - ch.pipeline().addLast("negotiator", snf.getSessionNegotiator(ch, new DefaultPromise(ch.eventLoop()))); + ch.pipeline().addLast("negotiator", snf.getSessionNegotiator(ch, new DefaultPromise<>(ch.eventLoop()))); ch.pipeline().addLast(hf.getEncoders()); } }); @@ -280,17 +287,17 @@ public class AbstractAddPathTest extends AbstractDataBrokerTest { final BGPPeer bgpPeer = new BGPPeer(inetAddress.getHostAddress(), ribImpl, peerRole, null); final List 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.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.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); @@ -299,30 +306,30 @@ public class AbstractAddPathTest extends AbstractDataBrokerTest { 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 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()); @@ -330,19 +337,42 @@ public class AbstractAddPathTest extends AbstractDataBrokerTest { 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(); } } diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AddPathAllPathsTest.java b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AddPathAllPathsTest.java index 0a3c3a1e7c..293904b9e9 100644 --- a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AddPathAllPathsTest.java +++ b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AddPathAllPathsTest.java @@ -28,7 +28,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib. import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.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 { /* @@ -74,34 +73,60 @@ 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); } } diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AddPathBasePathsTest.java b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AddPathBasePathsTest.java new file mode 100644 index 0000000000..9b98513912 --- /dev/null +++ b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AddPathBasePathsTest.java @@ -0,0 +1,130 @@ +/* + * 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 tables = ImmutableList.of(new BgpTableTypeImpl(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class)); + final TablesKey tk = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class); + final Map 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); + } +} diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AddPathNPathsTest.java b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AddPathNPathsTest.java index cdee8ab20f..e154e463e8 100644 --- a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AddPathNPathsTest.java +++ b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AddPathNPathsTest.java @@ -72,32 +72,57 @@ public class AddPathNPathsTest extends AbstractAddPathTest { 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); } } diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AdjRibsInWriterTest.java b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AdjRibsInWriterTest.java index 420cbe4221..bb7cf2287e 100644 --- a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AdjRibsInWriterTest.java +++ b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AdjRibsInWriterTest.java @@ -14,6 +14,7 @@ import com.google.common.collect.Sets; 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; @@ -62,12 +63,14 @@ public class AdjRibsInWriterTest { private AdjRibInWriter writer; - private static final TablesKey k4 = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class); - private final Set tableTypes = Sets.newHashSet(k4); + private static final TablesKey K4 = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class); + private final Set 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 addPathTablesType = Collections.singletonList(addressFamilies); + private final List addPathTablesType = Collections.singletonList(ADDRESS_FAMILIES); + private static final Map ADD_PATH_TABLE_MAPS = Collections.singletonMap(K4, SendReceive.Both); + private final String peerIp = "12.34.56.78"; @Before @@ -88,15 +91,16 @@ public class AdjRibsInWriterTest { 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)); } @@ -112,10 +116,11 @@ public class AdjRibsInWriterTest { 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); } diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/ExportPolicyPeerTrackerImplTest.java b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/ExportPolicyPeerTrackerImplTest.java new file mode 100644 index 0000000000..878bc8ae76 --- /dev/null +++ b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/ExportPolicyPeerTrackerImplTest.java @@ -0,0 +1,110 @@ +/* + * 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 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 diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/LocRibWriterTest.java b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/LocRibWriterTest.java deleted file mode 100644 index a1d4805597..0000000000 --- a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/LocRibWriterTest.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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 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 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()); - } -} diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/PeerTest.java b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/PeerTest.java index 33fcd60f49..3eba3ddad7 100644 --- a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/PeerTest.java +++ b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/PeerTest.java @@ -12,6 +12,7 @@ import static org.junit.Assert.assertEquals; 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; @@ -85,7 +86,7 @@ public class PeerTest extends AbstractRIBTestSetup { private BGPSessionImpl session; - private Map> routes; + private Map> routes; private BGPPeer classic; @@ -102,7 +103,7 @@ public class PeerTest extends AbstractRIBTestSetup { @Override public Object answer(final InvocationOnMock invocation) throws Throwable { final Object[] args = invocation.getArguments(); - final NormalizedNodenode = (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); } @@ -120,7 +121,6 @@ public class PeerTest extends AbstractRIBTestSetup { }).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"); @@ -144,7 +144,7 @@ public class PeerTest extends AbstractRIBTestSetup { 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 prefs = Lists.newArrayList(new Ipv4Prefix("8.0.1.0/28"), new Ipv4Prefix("127.0.0.1/32"), new Ipv4Prefix("2.2.2.2/24")); @@ -162,11 +162,11 @@ public class PeerTest extends AbstractRIBTestSetup { 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()); @@ -193,9 +193,9 @@ public class PeerTest extends AbstractRIBTestSetup { 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()); diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/AppPeerTest.java b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/AppPeerTest.java index 91325e1a21..666481a535 100644 --- a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/AppPeerTest.java +++ b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/AppPeerTest.java @@ -43,7 +43,7 @@ public class AppPeerTest extends AbstractConfig { 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(); diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/OpenConfigMappingUtilTest.java b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/OpenConfigMappingUtilTest.java index 18bcf6a407..6f0b028d34 100644 --- a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/OpenConfigMappingUtilTest.java +++ b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/OpenConfigMappingUtilTest.java @@ -28,7 +28,6 @@ import static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet 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; @@ -45,7 +44,7 @@ import org.opendaylight.protocol.bgp.rib.impl.spi.ImportPolicyPeerTracker; 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; @@ -140,22 +139,22 @@ public class OpenConfigMappingUtilTest { } @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; } diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/RibImplTest.java b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/RibImplTest.java index 7b3b4a2d80..61384aac95 100644 --- a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/RibImplTest.java +++ b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/RibImplTest.java @@ -150,11 +150,10 @@ public class RibImplTest extends AbstractConfig { 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()); diff --git a/bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/CacheDisconnectedPeers.java b/bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/CacheDisconnectedPeers.java deleted file mode 100644 index 06d220755e..0000000000 --- a/bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/CacheDisconnectedPeers.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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); -} diff --git a/bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/ExportPolicyPeerTracker.java b/bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/ExportPolicyPeerTracker.java index dc4cc01951..182353573c 100644 --- a/bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/ExportPolicyPeerTracker.java +++ b/bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/ExportPolicyPeerTracker.java @@ -8,10 +8,14 @@ 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; @@ -24,34 +28,46 @@ public interface ExportPolicyPeerTracker { * @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); /** * 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. @@ -59,5 +75,7 @@ public interface ExportPolicyPeerTracker { * @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) { + } } -- 2.36.6