Bug 4827 - BGP add-path unit tests
[bgpcep.git] / bgp / rib-impl / src / main / java / org / opendaylight / protocol / bgp / rib / impl / BGPSynchronization.java
index e335d413f815b70f6546b5418d29042c8ccc8f36..279b91dbc68d24e81e6bc32e00a51c2b138926e5 100644 (file)
@@ -7,20 +7,16 @@
  */
 package org.opendaylight.protocol.bgp.rib.impl;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Maps;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
-import org.opendaylight.protocol.bgp.parser.BGPSession;
-import org.opendaylight.protocol.bgp.parser.BGPSessionListener;
+import org.opendaylight.protocol.bgp.rib.spi.BGPSessionListener;
 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.UpdateBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes1;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes1Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes2;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpReachNlriBuilder;
+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.Attributes2;
 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.Ipv4AddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
@@ -36,7 +32,8 @@ public class BGPSynchronization {
 
     private static final Logger LOG = LoggerFactory.getLogger(BGPSynchronization.class);
 
-    private static class SyncVariables {
+    @VisibleForTesting
+    static class SyncVariables {
 
         private boolean upd = false;
         private boolean eor = false;
@@ -58,15 +55,13 @@ public class BGPSynchronization {
         }
     }
 
-    private final Map<TablesKey, SyncVariables> syncStorage = Maps.newHashMap();
+    @VisibleForTesting
+    public final Map<TablesKey, SyncVariables> syncStorage = Maps.newHashMap();
 
     private final BGPSessionListener listener;
 
-    private final BGPSession session;
-
-    public BGPSynchronization(final BGPSession bgpSession, final BGPSessionListener listener, final Set<TablesKey> types) {
+    public BGPSynchronization(final BGPSessionListener listener, final Set<TablesKey> types) {
         this.listener = Preconditions.checkNotNull(listener);
-        this.session = Preconditions.checkNotNull(bgpSession);
 
         for (final TablesKey type : types) {
             this.syncStorage.put(type, new SyncVariables());
@@ -76,7 +71,7 @@ public class BGPSynchronization {
     /**
      * For each received Update message, the upd sync variable needs to be updated to true, for particular AFI/SAFI
      * combination. Currently we only assume Unicast SAFI. From the Update message we have to extract the AFI. Each
-     * Update message can contain BGP Object with one type of AFI. If the object is BGP Link, BGP Node or BGPPrefix<?>
+     * Update message can contain BGP Object with one type of AFI. If the object is BGP Link, BGP Node or a BGPPrefix
      * the AFI is Linkstate. In case of BGPRoute, the AFI depends on the IP Address of the prefix.
      *
      * @param msg received Update message
@@ -85,22 +80,31 @@ public class BGPSynchronization {
         TablesKey type = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
         boolean isEOR = false;
         if (msg.getNlri() == null && msg.getWithdrawnRoutes() == null) {
-            if (msg.getPathAttributes() != null) {
-                if (msg.getPathAttributes().getAugmentation(PathAttributes1.class) != null) {
-                    final PathAttributes1 pa = msg.getPathAttributes().getAugmentation(PathAttributes1.class);
+            if (msg.getAttributes() != null) {
+                if (msg.getAttributes().getAugmentation(Attributes1.class) != null) {
+                    final Attributes1 pa = msg.getAttributes().getAugmentation(Attributes1.class);
                     if (pa.getMpReachNlri() != null) {
                         type = new TablesKey(pa.getMpReachNlri().getAfi(), pa.getMpReachNlri().getSafi());
                     }
-                } else if (msg.getPathAttributes().getAugmentation(PathAttributes2.class) != null) {
-                    final PathAttributes2 pa = msg.getPathAttributes().getAugmentation(PathAttributes2.class);
+                } else if (msg.getAttributes().getAugmentation(Attributes2.class) != null) {
+                    final Attributes2 pa = msg.getAttributes().getAugmentation(Attributes2.class);
                     if (pa.getMpUnreachNlri() != null) {
                         type = new TablesKey(pa.getMpUnreachNlri().getAfi(), pa.getMpUnreachNlri().getSafi());
                     }
+                    if (pa.getMpUnreachNlri().getWithdrawnRoutes() == null) {
+                        // EOR message contains only MPUnreach attribute and no NLRI
+                        isEOR = true;
+                    }
                 }
             } else {
+                // true for empty Update Message
                 isEOR = true;
             }
         }
+        syncType(type, isEOR);
+    }
+
+    private void syncType(final TablesKey type, final boolean isEOR) {
         final SyncVariables s = this.syncStorage.get(type);
         if (s == null) {
             LOG.warn("BGPTableType was not present in open message : {}", type);
@@ -109,6 +113,8 @@ public class BGPSynchronization {
         s.setUpd(true);
         if (isEOR) {
             s.setEorTrue();
+            this.listener.markUptodate(type);
+            LOG.info("BGP Synchronization finished for table {} ", type);
         }
     }
 
@@ -124,23 +130,10 @@ public class BGPSynchronization {
                 if (!s.getUpd()) {
                     s.setEorTrue();
                     LOG.info("BGP Synchronization finished for table {} ", entry.getKey());
-                    final Update up = generateEOR(entry.getKey());
-                    LOG.debug("Sending synchronization message: {}", up);
-                    this.listener.onMessage(this.session, up);
+                    this.listener.markUptodate(entry.getKey());
                 }
                 s.setUpd(false);
             }
         }
     }
-
-    private Update generateEOR(final TablesKey type) {
-        if (type.getAfi().equals(Ipv4AddressFamily.class) && type.getSafi().equals(UnicastSubsequentAddressFamily.class)) {
-            return new UpdateBuilder().build();
-        }
-        return new UpdateBuilder().setPathAttributes(
-                new PathAttributesBuilder().addAugmentation(
-                        PathAttributes1.class,
-                        new PathAttributes1Builder().setMpReachNlri(
-                                new MpReachNlriBuilder().setAfi(type.getAfi()).setSafi(type.getSafi()).build()).build()).build()).build();
-    }
 }