BUG-6747: Race condition on peer connection 54/46054/6
authorClaudio D. Gasparini <cgaspari@cisco.com>
Tue, 20 Sep 2016 09:23:38 +0000 (11:23 +0200)
committerClaudio D. Gasparini <cgaspari@cisco.com>
Mon, 26 Sep 2016 13:58:03 +0000 (15:58 +0200)
Race condition is observed under Loc rib when new peer is connected.
There is a chance that Eff-rib-in changes are notified before
than changes under supported tables, therefore none existing route
is announced to the  peer.
Fix by implement a unique ExportPolicyPeerTrackee per TableType and
per Rib.
On session stablished, peer will register itself to supported tables,
and remove himself when session down. This allow us to remove
CacheDisconnected peer, since it wont be longer required.
Also LocRib will be exclusively updated only related routes.

-Implement Base Path selection test
-Implement ExportPolicyPeerTrackerImpl test

Change-Id: I38b72f0ac9db09c64c4acdfeeb8eabade6ed046c
Signed-off-by: Claudio D. Gasparini <cgaspari@cisco.com>
31 files changed:
bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/api/RouteEntry.java
bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/impl/add/AddPathAbstractRouteEntry.java
bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/impl/base/BaseAbstractRouteEntry.java
bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/spi/AbstractRouteEntry.java
bgp/path-selection-mode/src/test/java/org/opendaylight/protocol/bgp/mode/impl/AbstractRouteEntryTest.java
bgp/path-selection-mode/src/test/java/org/opendaylight/protocol/bgp/mode/impl/add/all/paths/SimpleRouteEntryTest.java
bgp/path-selection-mode/src/test/java/org/opendaylight/protocol/bgp/mode/impl/add/n/paths/SimpleRouteEntryTest.java
bgp/path-selection-mode/src/test/java/org/opendaylight/protocol/bgp/mode/impl/base/BaseRouteEntryTest.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/AdjRibInWriter.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ApplicationPeer.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPPeer.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/CacheDisconnectedPeersImpl.java [deleted file]
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ExportPolicyPeerTrackerImpl.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/LocRibWriter.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/RIBImpl.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/RibImpl.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/protocol/BGPProtocolSessionPromise.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/RIB.java
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AbstractAddPathTest.java
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AddPathAllPathsTest.java
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AddPathBasePathsTest.java [new file with mode: 0644]
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AddPathNPathsTest.java
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AdjRibsInWriterTest.java
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/ExportPolicyPeerTrackerImplTest.java [new file with mode: 0644]
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/LocRibWriterTest.java [deleted file]
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/PeerTest.java
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/AppPeerTest.java
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/OpenConfigMappingUtilTest.java
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/RibImplTest.java
bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/CacheDisconnectedPeers.java [deleted file]
bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/ExportPolicyPeerTracker.java

index a0a3c4e6b44f4cfce782f48c238465dd8ca6eb4a..a5902c0e8477184661d29d8f0445646d4b76c3c2 100644 (file)
@@ -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
index cc664dc64740c350796ee3d9c0a37679f5fcc55d..b16feb38a0c9afc0c2071c88da1923ed1b2a1f85 100644 (file)
@@ -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<PeerId, PeerExporTuple> pid : peerGroup.getPeers()) {
                     final PeerId destPeer = pid.getKey();
                     final boolean destPeerSupAddPath = peerPT.isAddPathSupportedByPeer(destPeer);
-                    if (filterRoutes(routePeerId, destPeer, peerPT, localTK, discPeers, getRoutePeerIdRole(peerPT, destPeer))
+                    if (filterRoutes(routePeerId, destPeer, peerPT, localTK, getRoutePeerIdRole(peerPT, destPeer))
                         && peersSupportsAddPathOrIsFirstBestPath(destPeerSupAddPath, isFirstBestPath)) {
                         if (destPeerSupAddPath) {
                             update(destPeer, getAdjRibOutYII(ribSup, pid.getValue().getYii(), routeIdAddPath, localTK), effectiveAttributes,
index 7c2b8b8cc67b41efec6c044b88218395a97bc3c3..62a02f3db43ea6903558051727184c11750f8e39 100644 (file)
@@ -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));
             }
         }
index 1a58a0df190bacb32de6a53c8d5ed877a48ca6c8..4add989b692b5264826313c2b810f39ea2637c1f 100644 (file)
@@ -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) {
index 85fe15e6d47f0f2319ddeb39b310e9ad2e0a4c85..cffac05f5caf29e79ddcd374db75b2bb6fa05a29 100644 (file)
@@ -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<YangInstanceIdentifier> 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() {
index dbf03d79e3b0c8e7760db6c389cb1419314e8899..1680f268bbeae1830fa0c0a308eb226fbb6243f7 100644 (file)
@@ -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<YangInstanceIdentifier, Long> 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));
index 092bb4a16aa3d0c5eaf787256a2f9f442bf73ed0..eec2d48c7c42d67f7164bf5ff3d13948bc107a72 100644 (file)
@@ -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<YangInstanceIdentifier, Long> 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<YangInstanceIdentifier, Long> 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));
index a297a4dc455a7eef03211998773518501654c592..9df001c705d7dc53af739b4399c7343fa5a65f9a 100644 (file)
@@ -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<YangInstanceIdentifier, Long> 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<YangInstanceIdentifier, Long> yiiCount = this.yIIChanges.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
         assertEquals(3, yiiCount.size());
         assertEquals(1, (long) yiiCount.get(this.routePaYii));
         assertEquals(1, (long) yiiCount.get(this.routeRiboutYii));
         assertEquals(1, (long) yiiCount.get(this.routeRiboutAttYii));
-        this.testBARE.updateRoute(TABLES_KEY, this.peerPT, LOC_RIB_TARGET, this.ribSupport, this.discCache, this.tx, ROUTE_ID_PA_ADD_PATH);
+        this.testBARE.updateRoute(TABLES_KEY, this.peerPT, LOC_RIB_TARGET, this.ribSupport, this.tx, ROUTE_ID_PA_ADD_PATH);
         yiiCount = this.yIIChanges.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
         assertEquals(6, yiiCount.size());
         assertEquals(1, (long) yiiCount.get(this.routePaAddPathYii));
@@ -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
index 85ba578f354df65a3ac5e801696ee52f6f05498a..0f778f62f65b82cc0a90e30d4dff0e8adcfa8fe4 100644 (file)
@@ -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<TablesKey> tableTypes,
-        final List<AddressFamilies> addPathTablesType) {
+        final Map<TablesKey, SendReceive> addPathTablesType) {
         final DOMDataWriteTransaction tx = this.chain.newWriteOnlyTransaction();
 
         final YangInstanceIdentifier newPeerPath;
@@ -150,10 +147,9 @@ final class AdjRibInWriter {
      * @return
      */
     private ImmutableMap<TablesKey, TableContext> createNewTableInstances(final YangInstanceIdentifier newPeerPath,
-        final RIBSupportContextRegistry registry, final Set<TablesKey> tableTypes, final List<AddressFamilies> addPathTablesType,
+        final RIBSupportContextRegistry registry, final Set<TablesKey> tableTypes, final Map<TablesKey, SendReceive> addPathTablesType,
         final DOMDataWriteTransaction tx) {
 
-        final Map<TablesKey, SendReceive> addPathTableMaps = mapTableTypesFamilies(addPathTablesType);
         final Builder<TablesKey, TableContext> tb = ImmutableMap.builder();
         for (final TablesKey tableKey : tableTypes) {
             final RIBSupportContext rs = registry.getRIBSupportContext(tableKey);
@@ -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<TablesKey, SendReceive> mapTableTypesFamilies(final List<AddressFamilies> addPathTablesType) {
-        return Collections.unmodifiableMap(addPathTablesType.stream().collect(Collectors.toMap(af -> new TablesKey(af.getAfi(), af.getSafi()),
-            af -> af.getSendReceive())));
-    }
-
     private void installAdjRibInTables(final YangInstanceIdentifier newPeerPath, final TablesKey tableKey, final RIBSupportContext rs,
         final NodeIdentifierWithPredicates instanceIdentifierKey, final DOMDataWriteTransaction tx, final Builder<TablesKey, TableContext> tb) {
         // We will use table keys very often, make sure they are optimized
index 7ed275f93f3d227b3654db04be7e063101e7b342..ae6e3dc6292b8a57d49e91c646b4fe33999a4b26 100644 (file)
@@ -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> simpleRoutingPolicy = Optional.of(SimpleRoutingPolicy.AnnounceNone);
+        final PeerId peerId = RouterIds.createPeerId(this.ipAddress);
+        final Set<TablesKey> localTables = this.rib.getLocalTablesKeys();
+        localTables.forEach(tablesKey -> {
+            final ExportPolicyPeerTracker exportTracker = this.rib.getExportPolicyPeerTracker(tablesKey);
+            if (exportTracker != null) {
+                exportTracker.registerPeer(peerId, null, this.peerIId, PeerRole.Internal, simpleRoutingPolicy);
+            }
+        });
+
+        this.adjRibInWriter = AdjRibInWriter.create(this.rib.getYangRibId(), PeerRole.Internal, simpleRoutingPolicy, this.writerChain);
+        final RIBSupportContextRegistry context = this.rib.getRibSupportContext();
+        this.adjRibInWriter = this.adjRibInWriter.transform(peerId, context, localTables, Collections.emptyMap());
+        //TODO need to create effective rib in adjRibInWriter with route counter here
         this.effectiveRibInWriter = EffectiveRibInWriter.create(this.rib.getService(), this.rib.createPeerChain(this), this.peerIId,
-            this.rib.getImportPolicyPeerTracker(), this.rib.getRibSupportContext(), PeerRole.Internal);
+            this.rib.getImportPolicyPeerTracker(), context, PeerRole.Internal);
     }
 
     /**
@@ -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();
index da0c276682e14b2d458277fb39e18ceca89ccacd..42995e6985560a7c55b42ae37a74eecd4532d105 100644 (file)
@@ -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> simpleRoutingPolicy;
     private final BGPPeerStats peerStats;
+    private YangInstanceIdentifier peerIId;
+    private final Set<AbstractRegistration> tableRegistration = new HashSet<>();
 
     public BGPPeer(final String name, final RIB rib, final PeerRole role, final SimpleRoutingPolicy peerStatus, final RpcProviderRegistry rpcRegistry) {
         this.peerRole = role;
@@ -279,26 +287,37 @@ public class BGPPeer implements BGPSessionListener, Peer, AutoCloseable, BGPPeer
     @Override
     public synchronized void onSessionUp(final BGPSession session) {
         final List<AddressFamilies> addPathTablesType = session.getAdvertisedAddPathTableTypes();
-        LOG.info("Session with peer {} went up with tables {} and Add Path tables {}", this.name, addPathTablesType,
-                session.getAdvertisedAddPathTableTypes());
+        final Set<BgpTableType> advertizedTableTypes = session.getAdvertisedTableTypes();
+        LOG.info("Session with peer {} went up with tables {} and Add Path tables {}", this.name, advertizedTableTypes, addPathTablesType);
         this.session = session;
 
         this.rawIdentifier = InetAddresses.forString(session.getBgpId().getValue()).getAddress();
         final PeerId peerId = RouterIds.createPeerId(session.getBgpId());
 
-        this.tables.addAll(this.session.getAdvertisedTableTypes().stream().map(t -> new TablesKey(t.getAfi(), t.getSafi())).collect(Collectors.toList()));
+        this.tables.addAll(advertizedTableTypes.stream().map(t -> new TablesKey(t.getAfi(), t.getSafi())).collect(Collectors.toList()));
         final boolean announceNone = isAnnounceNone(this.simpleRoutingPolicy);
+        final Map<TablesKey, SendReceive> addPathTableMaps = mapTableTypesFamilies(addPathTablesType);
+        this.peerIId = this.rib.getYangRibId().node(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.Peer.QNAME)
+            .node(IdentifierUtils.domPeerId(peerId));
+
         if(!announceNone) {
             createAdjRibOutListener(peerId);
         }
+        this.tables.forEach(tablesKey -> {
+            final ExportPolicyPeerTracker exportTracker = this.rib.getExportPolicyPeerTracker(tablesKey);
+            if (exportTracker != null) {
+                this.tableRegistration.add(exportTracker.registerPeer(peerId, addPathTableMaps.get(tablesKey), this.peerIId, this.peerRole,
+                    this.simpleRoutingPolicy));
+            }
+        });
         addBgp4Support(peerId, announceNone);
 
         if(!isLearnNone(this.simpleRoutingPolicy)) {
-            final YangInstanceIdentifier peerIId = this.rib.getYangRibId().node(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.Peer.QNAME).node(IdentifierUtils.domPeerId(peerId));
-            this.effRibInWriter = EffectiveRibInWriter.create(this.rib.getService(), this.rib.createPeerChain(this), peerIId, this.rib.getImportPolicyPeerTracker(),
-                    this.rib.getRibSupportContext(), this.peerRole, this.peerStats.getEffectiveRibInRouteCounters(), this.peerStats.getAdjRibInRouteCounters());
+            this.effRibInWriter = EffectiveRibInWriter.create(this.rib.getService(), this.rib.createPeerChain(this), this.peerIId,
+                this.rib.getImportPolicyPeerTracker(), this.rib.getRibSupportContext(), this.peerRole,
+                this.peerStats.getEffectiveRibInRouteCounters(), this.peerStats.getAdjRibInRouteCounters());
         }
-        this.ribWriter = this.ribWriter.transform(peerId, this.rib.getRibSupportContext(), this.tables, addPathTablesType);
+        this.ribWriter = this.ribWriter.transform(peerId, this.rib.getRibSupportContext(), this.tables, addPathTableMaps);
 
         // register BGP Peer stats
         this.peerStats.getSessionEstablishedCounter().increaseCount();
@@ -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<TablesKey, SendReceive> mapTableTypesFamilies(final List<AddressFamilies> 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 (file)
index 39c523a..0000000
+++ /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<PeerId, Boolean> cache = CacheBuilder.newBuilder().expireAfterAccess(30, TimeUnit.SECONDS).build();
-
-    CacheDisconnectedPeersImpl() {
-    }
-
-    @Override
-    public boolean isPeerDisconnected(final PeerId peerId) {
-        if (this.cache.getIfPresent(peerId) != null) {
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void reconnected(final PeerId peerId) {
-        this.cache.asMap().remove(peerId);
-    }
-
-    @Override
-    public void insertDesconectedPeer(final Ipv4Address peerId) {
-        this.cache.put(RouterIds.createPeerId(peerId), true);
-    }
-}
index ec61de5ea182b3f8d82cda2030e9210e9b65299a..4d5bbdbbb8d73e56f72d5c1d80c4a5437d515d50 100644 (file)
@@ -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<YangInstanceIdentifier, PeerRole> peerRoles = new HashMap<>();
-    private final Set<PeerId> peerTables = Sets.newHashSet();
-    private final PolicyDatabase policyDatabase;
+    @GuardedBy("this")
     private final Map<PeerId, SendReceive> peerAddPathTables = new HashMap<>();
+    @GuardedBy("this")
+    private final Set<PeerId> peerTables = new HashSet<>();
+    private final PolicyDatabase policyDatabase;
     private final TablesKey localTableKey;
     private volatile Map<PeerRole, PeerExportGroup> groups = Collections.emptyMap();
 
@@ -59,99 +54,70 @@ final class ExportPolicyPeerTrackerImpl implements ExportPolicyPeerTracker {
         this.localTableKey = localTablesKey;
     }
 
-    private Map<PeerRole, PeerExportGroup> createGroups(final Map<YangInstanceIdentifier, PeerRole> peerPathRoles) {
-        if (peerPathRoles.isEmpty()) {
-            return Collections.emptyMap();
-        }
-
-        final Map<PeerRole, Map<PeerId, PeerExporTuple>> immutablePeers = peerPathRoles.entrySet().stream()
-            .collect(Collectors.groupingBy(Map.Entry::getValue, toMap(peer -> IdentifierUtils.peerKeyToPeerId(peer
-            .getKey()), peer -> new PeerExporTuple(peer.getKey(), peer.getValue()))));
-
-        final Map<PeerRole, PeerExportGroup> ret = peerPathRoles.values().stream().collect(Collectors.toSet()).stream()
-            .collect(toMap(identity(), role -> new PeerExportGroupImpl(ImmutableMap.copyOf(immutablePeers.get(role)),
-                this.policyDatabase.exportPolicyForRole(role)), (oldKey, newKey) -> oldKey, () -> new EnumMap<>(PeerRole.class)));
+    private synchronized void createGroups(final Map<YangInstanceIdentifier, PeerRole> peerPathRoles) {
+        if (!peerPathRoles.isEmpty()) {
+            final Map<PeerRole, Map<PeerId, PeerExporTuple>> immutablePeers = peerPathRoles.entrySet().stream()
+                .collect(Collectors.groupingBy(Map.Entry::getValue, toMap(peer -> IdentifierUtils.peerKeyToPeerId(peer
+                    .getKey()), peer -> new PeerExporTuple(peer.getKey(), peer.getValue()))));
 
-        return ret;
+            this.groups = peerPathRoles.values().stream().collect(Collectors.toSet()).stream()
+                .collect(toMap(identity(), role -> new PeerExportGroupImpl(ImmutableMap.copyOf(immutablePeers.get(role)),
+                    this.policyDatabase.exportPolicyForRole(role)), (oldKey, newKey) -> oldKey, () -> new EnumMap<>(PeerRole.class)));
+        }
     }
 
     @Override
-    public void peerRoleChanged(@Nonnull final YangInstanceIdentifier peerPath, @Nullable final PeerRole role) {
-        /*
-         * This is a sledgehammer approach to the problem: modify the role map first,
-         * then construct the group map from scratch.
-         */
-        final PeerRole oldRole;
-        if (role != null) {
-            oldRole = this.peerRoles.put(peerPath, role);
-        } else {
-            oldRole = this.peerRoles.remove(peerPath);
+    public synchronized AbstractRegistration registerPeer(final PeerId peerId, final SendReceive sendReceive, final YangInstanceIdentifier peerPath,
+        final PeerRole peerRole, final Optional<SimpleRoutingPolicy> optSimpleRoutingPolicy) {
+        if (sendReceive != null) {
+            this.peerAddPathTables.put(peerId, sendReceive);
+            LOG.debug("Supported Add BestPath table {} added to peer {}", sendReceive, peerId);
         }
-
-        if (role != oldRole) {
-            LOG.debug("Peer {} changed role from {} to {}", peerPath, oldRole, role);
-            this.groups = createGroups(this.peerRoles);
+        final SimpleRoutingPolicy simpleRoutingPolicy = optSimpleRoutingPolicy.orElse(null);
+        if (SimpleRoutingPolicy.AnnounceNone != simpleRoutingPolicy) {
+            this.peerTables.add(peerId);
         }
-    }
-
-    @Override
-    public void onTablesChanged(final PeerId peerId, final DataTreeCandidateNode tablesChange) {
-        final NodeIdentifierWithPredicates supTablesKey = RibSupportUtils.toYangKey(SupportedTables.QNAME, this.localTableKey);
-        final DataTreeCandidateNode localTableNode = tablesChange.getModifiedChild(supTablesKey);
-        if (localTableNode != null) {
-            final Optional<NormalizedNode<?, ?>> dataAfter = localTableNode.getDataAfter();
-            processSupportedSendReceiveTables(localTableNode.getModifiedChild(SEND_RECEIVE_NID), peerId);
-            if (dataAfter.isPresent()) {
-                final boolean added = this.peerTables.add(peerId);
-                if (added) {
-                    LOG.debug("Supported table {} added to peer {}", this.localTableKey, peerId);
+        this.peerRoles.put(peerPath, peerRole);
+        LOG.debug("Supported table {} added to peer {} role {}", this.localTableKey, peerId, peerRole);
+        createGroups(this.peerRoles);
+
+        final Object lock = this;
+        return new AbstractRegistration() {
+            @Override
+            protected void removeRegistration() {
+                synchronized (lock) {
+                    final SendReceive sendReceiveValue = peerAddPathTables.remove(peerId);
+                    if (sendReceiveValue != null) {
+                        LOG.debug("Supported Add BestPath table {} removed to peer {}", sendReceiveValue, peerId);
+                    }
+                    peerTables.remove(peerId);
+                    LOG.debug("Removed peer {} from supported table {}", peerId, localTableKey);
+                    peerRoles.remove(peerPath);
+                    createGroups(peerRoles);
                 }
-            } else {
-                final NodeIdentifierWithPredicates value = (NodeIdentifierWithPredicates) localTableNode.getIdentifier();
-                this.peerTables.remove(peerId);
-                LOG.debug("Removed tables {} from peer {}", value, peerId);
             }
-        }
+        };
     }
 
     @Override
-    public PeerExportGroup getPeerGroup(final PeerRole role) {
+    public synchronized PeerExportGroup getPeerGroup(final PeerRole role) {
         return this.groups.get(Preconditions.checkNotNull(role));
     }
 
     @Override
-    public PeerRole getRole(final YangInstanceIdentifier peerId) {
-        return this.peerRoles.get(peerId);
-    }
-
-    private void processSupportedSendReceiveTables(final DataTreeCandidateNode sendReceiveModChild, final PeerId peerId) {
-        if (sendReceiveModChild != null) {
-            if (sendReceiveModChild.getModificationType().equals(ModificationType.DELETE)) {
-                final Optional<NormalizedNode<?, ?>> sendReceiveNode = sendReceiveModChild.getDataBefore();
-                if (sendReceiveNode.isPresent()) {
-                    final SendReceive sendReceiveValue = SendReceive.valueOf(BindingMapping.getClassName((String) sendReceiveNode.get().getValue()));
-                    this.peerAddPathTables.remove(peerId);
-                    LOG.debug("Supported Add BestPath table {} removed to peer {}", sendReceiveValue, peerId);
-                }
-            } else {
-                final Optional<NormalizedNode<?, ?>> sendReceiveNode = sendReceiveModChild.getDataAfter();
-                if (sendReceiveNode.isPresent()) {
-                    final SendReceive sendReceiveValue = SendReceive.valueOf(BindingMapping.getClassName((String) sendReceiveNode.get().getValue()));
-                    this.peerAddPathTables.put(peerId, sendReceiveValue);
-                    LOG.debug("Supported Add BestPath table {} added to peer {}", sendReceiveValue, peerId);
-                }
-            }
-        }
+    public synchronized boolean isTableSupported(final PeerId peerId) {
+        return this.peerTables.contains(peerId);
     }
 
     @Override
-    public boolean isTableSupported(final PeerId peerId) {
-        return this.peerTables.contains(peerId);
+    public synchronized PeerRole getRole(final YangInstanceIdentifier peerId) {
+        return this.peerRoles.get(peerId);
     }
 
     @Override
-    public boolean isAddPathSupportedByPeer(final PeerId peerId) {
+    public synchronized boolean isAddPathSupportedByPeer(final PeerId peerId) {
         final SendReceive sendReceive = this.peerAddPathTables.get(peerId);
         return sendReceive != null && (sendReceive.equals(SendReceive.Both) || sendReceive.equals(SendReceive.Receive));
     }
+
 }
\ No newline at end of file
index 08ca796877ddadf64d6efdb2f4af31b74c31a486..3cbd173c11b78eaa91231ea076e590824f3bb973 100644 (file)
@@ -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<Boolean> ATTRIBUTES_UPTODATE_TRUE = ImmutableNodes.leafNode(QName.create(Attributes.QNAME, "uptodate"), Boolean.TRUE);
-    private static final NodeIdentifier EFFRIBIN_NID = new NodeIdentifier(EffectiveRibIn.QNAME);
-    private static final NodeIdentifier TABLES_NID = new NodeIdentifier(Tables.QNAME);
-    private static final NodeIdentifier PEER_TABLES = new NodeIdentifier(SupportedTables.QNAME);
 
     private final Map<PathArgument, RouteEntry> routeEntries = new HashMap<>();
     private final YangInstanceIdentifier locRibTarget;
     private final DOMTransactionChain chain;
-    private final ExportPolicyPeerTracker peerPolicyTracker;
+    private final ExportPolicyPeerTracker exportPolicyPeerTracker;
     private final NodeIdentifier attributesIdentifier;
     private final Long ourAs;
     private final RIBSupport ribSupport;
-    private final NodeIdentifierWithPredicates tableKey;
     private final TablesKey localTablesKey;
     private final ListenerRegistration<LocRibWriter> reg;
-    private final CacheDisconnectedPeers cacheDisconnectedPeers;
     private final PathSelectionMode pathSelectionMode;
     private final UnsignedInt32Counter routeCounter;
 
-    private LocRibWriter(final RIBSupportContextRegistry registry, final DOMTransactionChain chain, final YangInstanceIdentifier target, final Long ourAs,
-        final DOMDataTreeChangeService service, final PolicyDatabase pd, final TablesKey tablesKey, final CacheDisconnectedPeers cacheDisconnectedPeers,
+    private LocRibWriter(final RIBSupportContextRegistry registry, final DOMTransactionChain chain, final YangInstanceIdentifier target,
+        final Long ourAs, final DOMDataTreeChangeService service, final ExportPolicyPeerTracker exportPolicyPeerTracker, final TablesKey tablesKey,
         @Nonnull final PathSelectionMode pathSelectionMode, final UnsignedInt32Counter routeCounter) {
         this.chain = Preconditions.checkNotNull(chain);
-        this.tableKey = RibSupportUtils.toYangTablesKey(tablesKey);
+        final NodeIdentifierWithPredicates tableKey = RibSupportUtils.toYangTablesKey(tablesKey);
         this.localTablesKey = tablesKey;
-        this.locRibTarget = YangInstanceIdentifier.create(target.node(LocRib.QNAME).node(Tables.QNAME).node(this.tableKey).getPathArguments());
+        this.locRibTarget = YangInstanceIdentifier.create(target.node(LocRib.QNAME).node(Tables.QNAME).node(tableKey).getPathArguments());
         this.ourAs = Preconditions.checkNotNull(ourAs);
         this.ribSupport = registry.getRIBSupportContext(tablesKey).getRibSupport();
         this.attributesIdentifier = this.ribSupport.routeAttributesIdentifier();
-        this.peerPolicyTracker = new ExportPolicyPeerTrackerImpl(pd, this.localTablesKey);
-        this.cacheDisconnectedPeers = cacheDisconnectedPeers;
+        this.exportPolicyPeerTracker = exportPolicyPeerTracker;
         this.pathSelectionMode = pathSelectionMode;
         this.routeCounter = routeCounter;
 
@@ -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<DataTreeCandidate> changes) {
         LOG.trace("Received data change {} to LocRib {}", changes, this);
 
         final DOMDataWriteTransaction tx = this.chain.newWriteOnlyTransaction();
         try {
-            /*
-             * We use two-stage processing here in hopes that we avoid duplicate
-             * calculations when multiple peers have changed a particular entry.
-             */
             final Map<RouteUpdateKey, RouteEntry> toUpdate = update(tx, changes);
 
-            // Now walk all updated entries
-            walkThrough(tx, toUpdate);
+            if (!toUpdate.isEmpty()) {
+                walkThrough(tx, toUpdate.entrySet());
+            }
         } catch (final Exception e) {
             LOG.error("Failed to completely propagate updates {}, state is undefined", changes, e);
         } finally {
@@ -157,84 +146,25 @@ final class LocRibWriter implements AutoCloseable, ClusteredDOMDataTreeChangeLis
 
     private Map<RouteUpdateKey, RouteEntry> update(final DOMDataWriteTransaction tx, final Collection<DataTreeCandidate> changes) {
         final Map<RouteUpdateKey, RouteEntry> ret = new HashMap<>();
-
-        for (final DataTreeCandidate tc : changes) {
+        changes.forEach(tc -> {
+            final DataTreeCandidateNode table = tc.getRootNode();
             final YangInstanceIdentifier rootPath = tc.getRootPath();
-            final DataTreeCandidateNode rootNode = tc.getRootNode();
             final PeerId peerId = IdentifierUtils.peerKeyToPeerId(rootPath);
-
-            filterOutPeerRole(peerId, rootNode, rootPath);
-            filterOutChangesToSupportedTables(peerId, rootNode);
-            filterOutAnyChangeOutsideEffRibsIn(peerId, rootNode, ret, rootPath, tx);
-        }
-
+            initializeTableWithExistentRoutes(table, peerId, rootPath, tx);
+            updateNodes(table, peerId, tx, ret);
+        });
         return ret;
     }
 
-    private void filterOutAnyChangeOutsideEffRibsIn(final PeerId peerId, final DataTreeCandidateNode rootNode,
-        final Map<RouteUpdateKey, RouteEntry> ret, final YangInstanceIdentifier rootPath, final DOMDataWriteTransaction tx) {
-        final DataTreeCandidateNode ribIn = rootNode.getModifiedChild(EFFRIBIN_NID);
-        if (ribIn == null) {
-            LOG.trace("Skipping change {}", rootNode.getIdentifier());
-            return;
-        }
-        final DataTreeCandidateNode table = ribIn.getModifiedChild(TABLES_NID).getModifiedChild(this.tableKey);
-        if (table == null) {
-            LOG.trace("Skipping change {}", rootNode.getIdentifier());
-            return;
-        }
-        initializeTableWithExistentRoutes(table, peerId, rootPath, tx);
-        updateNodes(table, peerId, tx, ret);
-    }
-
-    private void filterOutChangesToSupportedTables(final PeerId peerIdOfNewPeer, final DataTreeCandidateNode rootNode) {
-        final DataTreeCandidateNode tablesChange = rootNode.getModifiedChild(PEER_TABLES);
-        if (tablesChange != null) {
-            this.peerPolicyTracker.onTablesChanged(peerIdOfNewPeer, tablesChange);
-        }
-    }
-
     private void initializeTableWithExistentRoutes(final DataTreeCandidateNode table, final PeerId peerIdOfNewPeer, final YangInstanceIdentifier rootPath,
         final DOMDataWriteTransaction tx) {
-        if (!table.getDataBefore().isPresent() && this.peerPolicyTracker.isTableSupported(peerIdOfNewPeer)) {
+        if (!table.getDataBefore().isPresent() && this.exportPolicyPeerTracker.isTableSupported(peerIdOfNewPeer)) {
             LOG.debug("Peer {} table has been created, inserting existent routes", peerIdOfNewPeer);
-            final PeerRole newPeerRole = this.peerPolicyTracker.getRole(IdentifierUtils.peerPath(rootPath));
-            final PeerExportGroup peerGroup = this.peerPolicyTracker.getPeerGroup(newPeerRole);
-            this.routeEntries.entrySet().forEach(entry -> entry.getValue().writeRoute(peerIdOfNewPeer, entry.getKey(), rootPath, peerGroup,
-                this.localTablesKey, this.peerPolicyTracker, this.ribSupport, this.cacheDisconnectedPeers, tx));
-        }
-    }
-
-    private void filterOutPeerRole(final PeerId peerId, final DataTreeCandidateNode rootNode, final YangInstanceIdentifier rootPath) {
-        final DataTreeCandidateNode roleChange = rootNode.getModifiedChild(PEER_ROLE_NID);
-        if (roleChange != null) {
-            if (rootNode.getModificationType() != ModificationType.DELETE) {
-                this.cacheDisconnectedPeers.reconnected(peerId);
-            }
-
-            // Check for removal
-            final Optional<NormalizedNode<?, ?>> maybePeerRole = roleChange.getDataAfter();
-            final YangInstanceIdentifier peerPath = IdentifierUtils.peerPath(rootPath);
-            LOG.debug("Data Changed for Peer role {} path {}, dataBefore {}, dataAfter {}", roleChange.getIdentifier(),
-                peerPath , roleChange.getDataBefore(), maybePeerRole);
-            final PeerRole role = PeerRoleUtil.roleForChange(maybePeerRole);
-            final SimpleRoutingPolicy srp = getSimpleRoutingPolicy(rootNode);
-            if(SimpleRoutingPolicy.AnnounceNone == srp) {
-                return;
-            }
-            this.peerPolicyTracker.peerRoleChanged(peerPath, role);
-        }
-    }
-
-    private SimpleRoutingPolicy getSimpleRoutingPolicy(final DataTreeCandidateNode rootNode) {
-        final DataTreeCandidateNode statusChange = rootNode.getModifiedChild(SIMPLE_ROUTING_POLICY_NID);
-        if (statusChange != null) {
-            final Optional<NormalizedNode<?, ?>> maybePeerStatus = statusChange.getDataAfter();
-            if (maybePeerStatus.isPresent()) {
-                return SimpleRoutingPolicy.valueOf(BindingMapping.getClassName((String) (maybePeerStatus.get()).getValue()));
-            }
+            final PeerRole newPeerRole = this.exportPolicyPeerTracker.getRole(IdentifierUtils.peerPath(rootPath));
+            final PeerExportGroup peerGroup = this.exportPolicyPeerTracker.getPeerGroup(newPeerRole);
+            this.routeEntries.entrySet().forEach(entry -> entry.getValue().writeRoute(peerIdOfNewPeer, entry.getKey(),
+                rootPath.getParent().getParent().getParent(), peerGroup, this.localTablesKey, this.exportPolicyPeerTracker, this.ribSupport, tx));
         }
-        return null;
     }
 
     private void updateNodes(final DataTreeCandidateNode table, final PeerId peerId, final DOMDataWriteTransaction tx,
@@ -284,8 +214,8 @@ final class LocRibWriter implements AutoCloseable, ClusteredDOMDataTreeChangeLis
         routeCounter.setCount(this.routeEntries.size());
     }
 
-    private void walkThrough(final DOMDataWriteTransaction tx, final Map<RouteUpdateKey, RouteEntry> toUpdate) {
-        for (final Map.Entry<RouteUpdateKey, RouteEntry> e : toUpdate.entrySet()) {
+    private void walkThrough(final DOMDataWriteTransaction tx, final Set<Map.Entry<RouteUpdateKey, RouteEntry>> toUpdate) {
+        for (final Map.Entry<RouteUpdateKey, RouteEntry> e : toUpdate) {
             LOG.trace("Walking through {}", e);
             final RouteEntry entry = e.getValue();
 
@@ -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());
         }
     }
 }
index 842e92c4b49d35d5da5bba8de41fab34839d1514..c35d0e8b1e556649cd3ed22b04a76ee2328ca33d 100755 (executable)
@@ -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<LocRibWriter> locRibs = new ArrayList<>();
-    private final CacheDisconnectedPeers cacheDisconnectedPeers;
     private final Map<TablesKey, PathSelectionMode> bestPathSelectionStrategies;
     private final ImportPolicyPeerTracker importPolicyPeerTracker;
     private final RIBImplRuntimeMXBeanImpl renderStats;
     private final RibId ribId;
+    private final Map<TablesKey, ExportPolicyPeerTracker> exportPolicyPeerTrackerMap;
 
     public RIBImpl(final ClusterSingletonServiceProvider provider, final RibId ribId, final AsNumber localAs, final BgpId localBgpId,
         final ClusterIdentifier clusterId, final RIBExtensionConsumerContext extensions, final BGPDispatcher dispatcher,
@@ -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<TablesKey, ExportPolicyPeerTracker> exportPolicies = new ImmutableMap.Builder<>();
+        for (final BgpTableType t : this.localTables) {
+            final TablesKey key = new TablesKey(t.getAfi(), t.getSafi());
+            this.localTablesKeys.add(key);
+            exportPolicies.put(key, new ExportPolicyPeerTrackerImpl(policyDatabase, key));
+        }
+        this.exportPolicyPeerTrackerMap = exportPolicies.build();
+
         LOG.info("RIB Singleton Service {} registered", getIdentifier());
         //this need to be always the last step
         this.registration = registerClusterSingletonService(this);
     }
 
-    private void startLocRib(final TablesKey key, final PolicyDatabase pd) {
+    private void startLocRib(final TablesKey key) {
         LOG.debug("Creating LocRib table for {}", key);
         // create locRibWriter for each table
         final DOMDataWriteTransaction tx = this.domChain.newWriteOnlyTransaction();
@@ -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
index 9c93fcf1a706375e9fb5f1d7aa2752493af28bdc..b025939d74c9507cd73dfde0b9777ddb99b15d02 100644 (file)
@@ -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<TablesKey> getLocalTablesKeys() {
         return this.ribImpl.getLocalTablesKeys();
index 64c943c88cd594702315cf1c41af6c9de251d3e9..b3e5bba736f7cad8280f3046cdbda8f3ebb02c32 100644 (file)
@@ -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;
index f2070c64f2e78c748693b64efaba7e0cb79ca5a1..1bd93d33abb25738267d9417df1d3145565b7a77 100755 (executable)
@@ -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<TablesKey> getLocalTablesKeys();
 
     /**
index d082574606bb17ac65d039d3d30df86e941034cb..adf18c3b4db910bdb2241683ae68a64489502230 100644 (file)
@@ -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.<KeyMapping>absent(), Epoll.isAvailable() ? new EpollEventLoopGroup() : new NioEventLoopGroup());
+        final Bootstrap bootstrap = dispatcher.createClientBootStrap(Optional.absent(), Epoll.isAvailable() ? new EpollEventLoopGroup() : new NioEventLoopGroup());
         bootstrap.localAddress(localAddress);
         bootstrap.option(ChannelOption.SO_REUSEADDR, true);
         bootstrap.handler(new ChannelInitializer<SocketChannel>() {
             @Override
             protected void initChannel(final SocketChannel ch) throws Exception {
                 ch.pipeline().addLast(hf.getDecoders());
-                ch.pipeline().addLast("negotiator", snf.getSessionNegotiator(ch, new DefaultPromise<BGPSessionImpl>(ch.eventLoop())));
+                ch.pipeline().addLast("negotiator", snf.getSessionNegotiator(ch, new DefaultPromise<>(ch.eventLoop())));
                 ch.pipeline().addLast(hf.getEncoders());
             }
         });
@@ -280,17 +287,17 @@ public class AbstractAddPathTest extends AbstractDataBrokerTest {
         final BGPPeer bgpPeer = new BGPPeer(inetAddress.getHostAddress(), ribImpl, peerRole, null);
         final List<BgpParameters> tlvs = Lists.newArrayList(bgpParameters);
         StrictBGPPeerRegistry.GLOBAL.addPeer(new IpAddress(new Ipv4Address(inetAddress.getHostAddress())), bgpPeer,
-                new BGPSessionPreferences(AS_NUMBER, HOLDTIMER, new BgpId(RIB_ID),
-                        AS_NUMBER,  tlvs, Optional.<byte[]>absent()));
+            new BGPSessionPreferences(AS_NUMBER, HOLDTIMER, new BgpId(RIB_ID),
+                AS_NUMBER, tlvs, Optional.absent()));
         bgpPeer.instantiateServiceInstance();
     }
 
-    private static Channel connectPeer(final Ipv4Address localAddress, final RIBImpl ribImpl, final BgpParameters bgpParameters,
-            final BGPDispatcherImpl dispatcherImpl, final BGPHandlerFactory hf, final BGPSessionListener sessionListsner) throws InterruptedException, ExecutionException {
+    private static Channel connectPeer(final Ipv4Address localAddress, final BgpParameters bgpParameters,
+        final BGPDispatcherImpl dispatcherImpl, final BGPHandlerFactory hf, final BGPSessionListener sessionListsner) throws InterruptedException {
         final BGPPeerRegistry peerRegistry = new StrictBGPPeerRegistry();
         peerRegistry.addPeer(new IpAddress(new Ipv4Address(RIB_ID)), sessionListsner,
-                new BGPSessionPreferences(AS_NUMBER, HOLDTIMER, new BgpId(localAddress),
-                        AS_NUMBER, Lists.newArrayList(bgpParameters),Optional.<byte[]>absent()));
+            new BGPSessionPreferences(AS_NUMBER, HOLDTIMER, new BgpId(localAddress),
+                AS_NUMBER, Lists.newArrayList(bgpParameters), Optional.absent()));
 
         final ChannelFuture createClient = createClient(dispatcherImpl, new InetSocketAddress(RIB_ID, PORT), peerRegistry, new InetSocketAddress(localAddress.getValue(), PORT), hf);
         Thread.sleep(1000);
@@ -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<OptionalCapabilities> capabilities = Lists.newArrayList(mp);
         if (addPath) {
             final OptionalCapabilities addPathCapa = new OptionalCapabilitiesBuilder().setCParameters(
-                    new CParametersBuilder().addAugmentation(CParameters1.class,
-                            new CParameters1Builder().setAddPathCapability(
-                                    new AddPathCapabilityBuilder().setAddressFamilies(Lists.newArrayList(
-                                            new AddressFamiliesBuilder()
-                                            .setAfi(Ipv4AddressFamily.class)
-                                            .setSafi(UnicastSubsequentAddressFamily.class)
-                                            .setSendReceive(SendReceive.Both)
-                                            .build()))
-                                            .build()).build()).build()).build();
+                new CParametersBuilder().addAugmentation(CParameters1.class,
+                    new CParameters1Builder().setAddPathCapability(
+                        new AddPathCapabilityBuilder().setAddressFamilies(Lists.newArrayList(
+                            new AddressFamiliesBuilder()
+                                .setAfi(Ipv4AddressFamily.class)
+                                .setSafi(UnicastSubsequentAddressFamily.class)
+                                .setSendReceive(SendReceive.Both)
+                                .build()))
+                            .build()).build()).build()).build();
             capabilities.add(addPathCapa);
         }
         return new BgpParametersBuilder().setOptionalCapabilities(capabilities).build();
     }
 
     private static Update createSimpleUpdate(final Ipv4Prefix prefix, final PathId pathId, final ClusterIdentifier clusterId,
-            final long localPreference) {
-     final AttributesBuilder attBuilder = new AttributesBuilder();
+        final long localPreference) {
+        final AttributesBuilder attBuilder = new AttributesBuilder();
         attBuilder.setLocalPref(new LocalPrefBuilder().setPref(localPreference).build());
         attBuilder.setOrigin(new OriginBuilder().setValue(BgpOrigin.Igp).build());
         attBuilder.setAsPath(new AsPathBuilder().setSegments(Collections.emptyList()).build());
@@ -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();
     }
 }
index 0a3c3a1e7c3759ebad9edfcfffc60d470a111aea..293904b9e95a88833bc72a22218a78e60a77714f 100644 (file)
@@ -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 (file)
index 0000000..9b98513
--- /dev/null
@@ -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<BgpTableType> tables = ImmutableList.of(new BgpTableTypeImpl(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class));
+        final TablesKey tk = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
+        final Map<TablesKey, PathSelectionMode> pathTables = ImmutableMap.of(tk, BasePathSelectionModeFactory.createBestPathSelectionStrategy());
+
+        final RIBImpl ribImpl = new RIBImpl(this.clusterSingletonServiceProvider, new RibId("test-rib"), AS_NUMBER, new BgpId(RIB_ID), null, this.ribExtension,
+            this.dispatcher, this.mappingService.getCodecFactory(), getDomBroker(), tables, pathTables, this.ribExtension.getClassLoadingStrategy(), null);
+
+        ribImpl.instantiateServiceInstance();
+        ribImpl.onGlobalContextUpdated(this.schemaContext);
+
+        this.dispatcher.createServer(StrictBGPPeerRegistry.GLOBAL, new InetSocketAddress(RIB_ID, PORT)).sync();
+        Thread.sleep(1000);
+
+        final BGPHandlerFactory hf = new BGPHandlerFactory(this.context.getMessageRegistry());
+        final BgpParameters nonAddPathParams = createParameter(false);
+
+        final Channel session1 = createPeerSession(PEER1, PeerRole.Ibgp, nonAddPathParams, ribImpl, hf, new SimpleSessionListener());
+        final Channel session2 = createPeerSession(PEER2, PeerRole.Ibgp, nonAddPathParams, ribImpl, hf, new SimpleSessionListener());
+        final Channel session3 = createPeerSession(PEER3, PeerRole.Ibgp, nonAddPathParams, ribImpl, hf, new SimpleSessionListener());
+        final SimpleSessionListener listener4 = new SimpleSessionListener();
+        final Channel session4 = createPeerSession(PEER4, PeerRole.RrClient, nonAddPathParams, ribImpl, hf, listener4);
+        final SimpleSessionListener listener5 = new SimpleSessionListener();
+        final Channel session5 = createPeerSession(PEER5, PeerRole.Ebgp, nonAddPathParams, ribImpl, hf, listener5);
+        Thread.sleep(1000);
+        checkPeersPresentOnDataStore(5);
+
+        //new best route so far
+        sendRouteAndCheckIsOnLocRib(session1, PREFIX1, 100, 1);
+        assertEquals(1, listener4.getListMsg().size());
+        assertEquals(1, listener5.getListMsg().size());
+        assertEquals(UPD_NA_100, listener4.getListMsg().get(0));
+        assertEquals(UPD_NA_100_EBGP, listener5.getListMsg().get(0));
+
+        //the second best route
+        sendRouteAndCheckIsOnLocRib(session2, PREFIX1, 50, 1);
+        assertEquals(1, listener4.getListMsg().size());
+        assertEquals(1, listener5.getListMsg().size());
+
+        //new best route
+        sendRouteAndCheckIsOnLocRib(session3, PREFIX1, 200, 1);
+        assertEquals(2, listener4.getListMsg().size());
+        assertEquals(2, listener5.getListMsg().size());
+        assertEquals(UPD_NA_200, listener4.getListMsg().get(1));
+        assertEquals(UPD_NA_200_EBGP, listener5.getListMsg().get(1));
+
+        final SimpleSessionListener listener6 = new SimpleSessionListener();
+        final Channel session6 = createPeerSession(PEER6, PeerRole.RrClient, nonAddPathParams, ribImpl, hf, listener6);
+        Thread.sleep(1000);
+        checkPeersPresentOnDataStore(6);
+        assertEquals(1, listener6.getListMsg().size());
+        assertEquals(UPD_NA_200, listener6.getListMsg().get(0));
+        Thread.sleep(1000);
+        session6.close();
+        Thread.sleep(1000);
+
+        //best route updated to be the worse one
+        sendRouteAndCheckIsOnLocRib(session3, PREFIX1, 20, 1);
+        assertEquals(3, listener4.getListMsg().size());
+        assertEquals(3, listener5.getListMsg().size());
+        assertEquals(UPD_NA_100, listener4.getListMsg().get(2));
+        assertEquals(UPD_NA_100_EBGP, listener5.getListMsg().get(2));
+
+        //Remove second best, no advertisement should be done
+        sendWithdrawalRouteAndCheckIsOnLocRib(session2, PREFIX1, 50, 1);
+        assertEquals(3, listener4.getListMsg().size());
+        assertEquals(3, listener5.getListMsg().size());
+
+        //Remove best, 1 advertisement
+        sendWithdrawalRouteAndCheckIsOnLocRib(session1, PREFIX1, 100, 1);
+        assertEquals(4, listener4.getListMsg().size());
+        assertEquals(4, listener5.getListMsg().size());
+
+        //Remove best, 1 withdrawal
+        sendWithdrawalRouteAndCheckIsOnLocRib(session3, PREFIX1, 20, 0);
+        assertEquals(5, listener4.getListMsg().size());
+        assertEquals(5, listener5.getListMsg().size());
+
+        session1.close();
+        session2.close();
+        session3.close();
+        session4.close();
+        session5.close();
+        Thread.sleep(1000);
+    }
+}
index cdee8ab20f3fbbb2223269eb4ab08ff6145fcd7b..e154e463e84f7d55615ad0cfe2a3d00e72f3ec5a 100644 (file)
@@ -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);
     }
 }
index 420cbe4221bb550a211ed92a6cacb37f9dd88096..bb7cf2287e26335cf2903d1cde41487f5b41e61d 100644 (file)
@@ -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<TablesKey> tableTypes = Sets.newHashSet(k4);
+    private static final TablesKey K4 = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
+    private final Set<TablesKey> tableTypes = Sets.newHashSet(K4);
 
-    private static final AddressFamilies addressFamilies = new AddressFamiliesBuilder().setAfi(Ipv4AddressFamily.class)
+    private static final AddressFamilies ADDRESS_FAMILIES = new AddressFamiliesBuilder().setAfi(Ipv4AddressFamily.class)
         .setSafi(UnicastSubsequentAddressFamily.class).setSendReceive(SendReceive.Both).build();
-    private final List<AddressFamilies> addPathTablesType = Collections.singletonList(addressFamilies);
+    private final List<AddressFamilies> addPathTablesType = Collections.singletonList(ADDRESS_FAMILIES);
+    private static final Map<TablesKey, SendReceive> ADD_PATH_TABLE_MAPS = Collections.singletonMap(K4, SendReceive.Both);
+
     private final String peerIp = "12.34.56.78";
 
     @Before
@@ -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 (file)
index 0000000..878bc8a
--- /dev/null
@@ -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<AutoCloseable> TABLE_REGISTRATION = new ArrayList<>();
+
+    @Test
+    public void testExportPolicyPeerTrackerImpl() throws Exception {
+        final ExportPolicyPeerTrackerImpl exportPpt = new ExportPolicyPeerTrackerImpl(PD, TABLE_KEY);
+
+        TABLE_REGISTRATION.add(exportPpt.registerPeer(PEER_ID1, SendReceive.Both, YII_PEER1, PeerRole.RrClient, Optional.empty()));
+        TABLE_REGISTRATION.add(exportPpt.registerPeer(PEER_ID2, SendReceive.Receive, YII_PEER2, PeerRole.Ibgp, Optional.of(SimpleRoutingPolicy.AnnounceNone)));
+        TABLE_REGISTRATION.add(exportPpt.registerPeer(PEER_ID3, SendReceive.Send, YII_PEER3, PeerRole.Ebgp, Optional.of(SimpleRoutingPolicy.LearnNone)));
+        TABLE_REGISTRATION.add(exportPpt.registerPeer(PEER_ID4, null, YII_PEER4, PeerRole.Ibgp, Optional.empty()));
+
+        assertEquals(PeerRole.RrClient, exportPpt.getRole(YII_PEER1));
+        assertEquals(PeerRole.Ibgp, exportPpt.getRole(YII_PEER2));
+        assertEquals(PeerRole.Ebgp, exportPpt.getRole(YII_PEER3));
+        assertEquals(PeerRole.Ibgp, exportPpt.getRole(YII_PEER4));
+
+        assertTrue(exportPpt.getPeerGroup(PeerRole.RrClient).containsPeer(PEER_ID1));
+        assertTrue(exportPpt.getPeerGroup(PeerRole.Ibgp).containsPeer(PEER_ID2));
+        assertTrue(exportPpt.getPeerGroup(PeerRole.Ebgp).containsPeer(PEER_ID3));
+        assertTrue(exportPpt.getPeerGroup(PeerRole.Ibgp).containsPeer(PEER_ID4));
+
+        assertTrue(exportPpt.isTableSupported(PEER_ID1));
+        assertFalse(exportPpt.isTableSupported(PEER_ID2));
+        assertTrue(exportPpt.isTableSupported(PEER_ID3));
+        assertTrue(exportPpt.isTableSupported(PEER_ID4));
+        assertFalse(exportPpt.isTableSupported(PEER_ID5));
+
+        assertTrue(exportPpt.isAddPathSupportedByPeer(PEER_ID1));
+        assertTrue(exportPpt.isAddPathSupportedByPeer(PEER_ID2));
+        assertFalse(exportPpt.isAddPathSupportedByPeer(PEER_ID3));
+        assertFalse(exportPpt.isAddPathSupportedByPeer(PEER_ID4));
+        assertFalse(exportPpt.isAddPathSupportedByPeer(PEER_ID5));
+
+        TABLE_REGISTRATION.remove(0).close();
+        assertNull(exportPpt.getRole(YII_PEER1));
+        assertNull(exportPpt.getPeerGroup(PeerRole.RrClient));
+        assertFalse(exportPpt.isTableSupported(PEER_ID1));
+        assertFalse(exportPpt.isAddPathSupportedByPeer(PEER_ID1));
+
+
+        TABLE_REGISTRATION.get(0).close();
+        assertNull(exportPpt.getRole(YII_PEER2));
+        assertFalse(exportPpt.getPeerGroup(PeerRole.Ibgp).containsPeer(PEER_ID2));
+        assertFalse(exportPpt.isTableSupported(PEER_ID2));
+        assertFalse(exportPpt.isAddPathSupportedByPeer(PEER_ID2));
+
+        for (final AutoCloseable tableCloseable : TABLE_REGISTRATION) {
+            try {
+                tableCloseable.close();
+            } catch (final Exception e) {
+                LOG.warn("Failed to close registration", e);
+            }
+        }
+        TABLE_REGISTRATION.clear();
+    }
+
+}
\ No newline at end of file
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 (file)
index a1d4805..0000000
+++ /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<YangInstanceIdentifier> routes = new ArrayList<>();
-    private final TablesKey tablesKey = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
-    private final UnsignedInt32Counter routeCounter = new UnsignedInt32Counter("loc-rib");
-
-    private RIBActivator ribActivator;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        this.ribActivator = new RIBActivator();
-        final RIBExtensionProviderContext ribExtension = new SimpleRIBExtensionProviderContext();
-        this.ribActivator.startRIBExtensionProvider(ribExtension);
-
-        final Answer<Object> answer = invocation -> {
-            final Object[] args = invocation.getArguments();
-            final NormalizedNode<?, ?> node = (NormalizedNode<?, ?>) args[2];
-            if (node.getNodeType().equals(Ipv4Route.QNAME) || node.getNodeType().equals(PREFIX_QNAME)) {
-                LocRibWriterTest.this.routes.add((YangInstanceIdentifier) args[1]);
-            }
-            return args[1];
-        };
-        doAnswer(answer).when(this.domTransWrite).put(eq(LogicalDatastoreType.OPERATIONAL), any(YangInstanceIdentifier.class), any(NormalizedNode.class));
-        doAnswer(answer).when(this.domTransWrite).merge(eq(LogicalDatastoreType.OPERATIONAL), any(YangInstanceIdentifier.class), any(NormalizedNode.class));
-        doAnswer(invocation -> {
-            final Object[] args = invocation.getArguments();
-            LocRibWriterTest.this.routes.remove(args[1]);
-            return args[1];
-        }).when(this.domTransWrite).delete(eq(LogicalDatastoreType.OPERATIONAL), any(YangInstanceIdentifier.class));
-        doReturn(this.context).when(this.registry).getRIBSupportContext(any(TablesKey.class));
-        doReturn(ribExtension.getRIBSupport(this.tablesKey)).when(this.context).getRibSupport();
-        doReturn(this.domTransWrite).when(this.chain).newWriteOnlyTransaction();
-        doReturn(this.future).when(this.domTransWrite).submit();
-        doReturn(null).when(this.service).registerDataTreeChangeListener(any(DOMDataTreeIdentifier.class), any(ClusteredDOMDataTreeChangeListener.class));
-        this.locRibWriter = LocRibWriter.create(this.registry, this.tablesKey, this.chain, YangInstanceIdentifier.of(BgpRib.QNAME),
-                new AsNumber((long) 35), this.service, this.pd, new CacheDisconnectedPeersImpl(), BasePathSelectionModeFactory.createBestPathSelectionStrategy(),
-                this.routeCounter);
-    }
-
-    private DataTreeCandidate prepareUpdate() {
-        final DataTreeCandidate candidate = mock(DataTreeCandidate.class);
-        doReturn("candidate").when(candidate).toString();
-        final YangInstanceIdentifier rootPath = YangInstanceIdentifier.builder().node(BgpRib.QNAME).node(Peer.QNAME).nodeWithKey(Peer.QNAME, AdjRibInWriter.PEER_ID_QNAME, "12.12.12.12").build();
-        doReturn(rootPath).when(candidate).getRootPath();
-        return candidate;
-    }
-
-    @Test
-    public void testUpdateSupportedTables() {
-        final DataTreeCandidate candidate = prepareUpdate();
-        final DataTreeCandidateNode node = mock(DataTreeCandidateNode.class);
-        doReturn("node").when(node).toString();
-        final DataTreeCandidateNode tableChange = mock(DataTreeCandidateNode.class);
-        // add
-        final DataTreeCandidateNode table = mock(DataTreeCandidateNode.class);
-        final NormalizedNode<?, ?> dataAfter = mock(NormalizedNode.class);
-        doReturn(RibSupportUtils.toYangTablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class)).when(dataAfter).getIdentifier();
-        doReturn(Optional.of(dataAfter)).when(table).getDataAfter();
-        doReturn(Lists.newArrayList(table)).when(tableChange).getChildNodes();
-        doReturn("table change").when(tableChange).toString();
-        doReturn(tableChange).when(node).getModifiedChild(YangInstanceIdentifier.of(SupportedTables.QNAME).getLastPathArgument());
-        doReturn(null).when(node).getModifiedChild(PEER_ROLE_NID);
-        doReturn(null).when(node).getModifiedChild(YangInstanceIdentifier.of(EffectiveRibIn.QNAME).getLastPathArgument());
-        doReturn(node).when(candidate).getRootNode();
-        doReturn(ModificationType.SUBTREE_MODIFIED).when(node).getModificationType();
-        this.locRibWriter.onDataTreeChanged(Lists.newArrayList(candidate));
-        // delete
-        final DataTreeCandidateNode tableDelete = mock(DataTreeCandidateNode.class);
-        doReturn(Optional.absent()).when(tableDelete).getDataAfter();
-        doReturn(Lists.newArrayList(tableDelete)).when(tableChange).getChildNodes();
-        doReturn("table change").when(tableChange).toString();
-        doReturn(node).when(candidate).getRootNode();
-        this.locRibWriter.onDataTreeChanged(Lists.newArrayList(candidate));
-        verify(node, times(2)).getModifiedChild(YangInstanceIdentifier.of(SupportedTables.QNAME).getLastPathArgument());
-    }
-}
index 33fcd60f49d4c01e4bdc1c250a5f1bd7db229e31..3eba3ddad7a90f72edffe3ce524ed940ae79fa02 100644 (file)
@@ -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<YangInstanceIdentifier, NormalizedNode<?,?>> routes;
+    private Map<YangInstanceIdentifier, NormalizedNode<?, ?>> 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 NormalizedNode<?,?>node = (NormalizedNode<?,?>)args[2];
+                final NormalizedNode<?, ?> node = (NormalizedNode<?, ?>) args[2];
                 if (node.getIdentifier().getNodeType().equals(Ipv4Route.QNAME) || node.getNodeType().equals(PREFIX_QNAME)) {
                     PeerTest.this.routes.put((YangInstanceIdentifier) args[1], node);
                 }
@@ -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<Ipv4Prefix> prefs = Lists.newArrayList(new Ipv4Prefix("8.0.1.0/28"), new Ipv4Prefix("127.0.0.1/32"), new Ipv4Prefix("2.2.2.2/24"));
@@ -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());
index 91325e1a21c54e2dd148d07556f103e0f35546fc..666481a53567ad1d6c113d0f17aabd13a8c5df24 100644 (file)
@@ -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();
 
index 18bcf6a40738f39ef9d24779c4bec830568f3500..6f0b028d3492eb70db3643f1482a54d4dea0656f 100644 (file)
@@ -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;
         }
 
index 7b3b4a2d802eeab24b48f2760a36eb8c6325c5e0..61384aac9576bfbacef6f29f9c7b0958dd25d6a5 100644 (file)
@@ -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 (file)
index 06d2207..0000000
+++ /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);
-}
index dc4cc019511bc68327575c0630b563a2f213416b..182353573c4641f151d68ef53987ca25c7765e6a 100644 (file)
@@ -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> 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) {
+    }
 }