[Goldeneye] [ONOS-4161] BGP L3 Topology

Change-Id: I81ae4e88f6ab75202b98ed03cbe1597d0f6ddd1e
diff --git a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpControllerImpl.java b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpControllerImpl.java
old mode 100755
new mode 100644
index 4e1b7fb..f270cf3
--- a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpControllerImpl.java
+++ b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpControllerImpl.java
@@ -23,6 +23,7 @@
 import org.onosproject.bgp.controller.BgpCfg;
 import org.onosproject.bgp.controller.BgpController;
 import org.onosproject.bgp.controller.BgpId;
+import org.onosproject.bgp.controller.BgpLinkListener;
 import org.onosproject.bgp.controller.BgpLocalRib;
 import org.onosproject.bgp.controller.BgpNodeListener;
 import org.onosproject.bgp.controller.BgpPeer;
@@ -58,6 +59,7 @@
     private BgpLocalRib bgplocalRibVpn = new BgpLocalRibImpl(this);
 
     protected Set<BgpNodeListener> bgpNodeListener = new CopyOnWriteArraySet<>();
+    protected Set<BgpLinkListener> bgpLinkListener = new CopyOnWriteArraySet<>();
 
     final Controller ctrl = new Controller(this);
 
@@ -278,4 +280,19 @@
     public BgpLocalRib bgpLocalRibVpn() {
         return bgplocalRibVpn;
     }
+
+    @Override
+    public void addLinkListener(BgpLinkListener listener) {
+        this.bgpLinkListener.add(listener);
+    }
+
+    @Override
+    public void removeLinkListener(BgpLinkListener listener) {
+        this.bgpLinkListener.remove(listener);
+    }
+
+    @Override
+    public Set<BgpLinkListener> linkListener() {
+        return bgpLinkListener;
+    }
 }
diff --git a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpLocalRibImpl.java b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpLocalRibImpl.java
index c4773ff..54daefc 100755
--- a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpLocalRibImpl.java
+++ b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpLocalRibImpl.java
@@ -14,11 +14,14 @@
 package org.onosproject.bgp.controller.impl;
 
 import com.google.common.base.MoreObjects;
+
 import org.onosproject.bgp.controller.BgpController;
 import org.onosproject.bgp.controller.BgpId;
+import org.onosproject.bgp.controller.BgpLinkListener;
 import org.onosproject.bgp.controller.BgpLocalRib;
 import org.onosproject.bgp.controller.BgpNodeListener;
 import org.onosproject.bgp.controller.BgpSessionInfo;
+import org.onosproject.bgpio.exceptions.BgpParseException;
 import org.onosproject.bgpio.protocol.BgpLSNlri;
 import org.onosproject.bgpio.protocol.linkstate.BgpLinkLSIdentifier;
 import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
@@ -116,7 +119,7 @@
     }
 
     @Override
-    public void add(BgpSessionInfo sessionInfo, BgpLSNlri nlri, PathAttrNlriDetails details) {
+    public void add(BgpSessionInfo sessionInfo, BgpLSNlri nlri, PathAttrNlriDetails details) throws BgpParseException {
         int decisionResult;
 
         log.debug("Add to local RIB {}", details.toString());
@@ -133,13 +136,16 @@
                 // Compare local RIB entry with the current attribute
                 decisionResult = selectionAlgo.compare(nodeTree.get(nodeLsIdentifier), detailsLocRib);
                 if (decisionResult < 0) {
+                    for (BgpNodeListener l : bgpController.listener()) {
+                        l.addNode((BgpNodeLSNlriVer4) nlri, details);
+                    }
                     nodeTree.replace(nodeLsIdentifier, detailsLocRib);
                     log.debug("Local RIB update node: {}", detailsLocRib.toString());
                 }
             } else {
                 nodeTree.put(nodeLsIdentifier, detailsLocRib);
                 for (BgpNodeListener l : bgpController.listener()) {
-                    l.addNode((BgpNodeLSNlriVer4) nlri);
+                    l.addNode((BgpNodeLSNlriVer4) nlri, details);
                 }
                 log.debug("Local RIB ad node: {}", detailsLocRib.toString());
             }
@@ -151,10 +157,16 @@
                 decisionResult = selectionAlgo.compare(linkTree.get(linkLsIdentifier), detailsLocRib);
                 if (decisionResult < 0) {
                     linkTree.replace(linkLsIdentifier, detailsLocRib);
+                    for (BgpLinkListener l : bgpController.linkListener()) {
+                        l.addLink((BgpLinkLsNlriVer4) nlri, details);
+                    }
                     log.debug("Local RIB update link: {}", detailsLocRib.toString());
                 }
             } else {
                 linkTree.put(linkLsIdentifier, detailsLocRib);
+                for (BgpLinkListener l : bgpController.linkListener()) {
+                    l.addLink((BgpLinkLsNlriVer4) nlri, details);
+                }
                 log.debug("Local RIB add link: {}", detailsLocRib.toString());
             }
         } else if (nlri instanceof BgpPrefixIPv4LSNlriVer4) {
@@ -175,7 +187,7 @@
     }
 
     @Override
-    public void delete(BgpLSNlri nlri) {
+    public void delete(BgpLSNlri nlri) throws BgpParseException {
         log.debug("Delete from local RIB.");
 
         // Update local RIB
@@ -186,8 +198,9 @@
      * Update local RIB based on selection algorithm.
      *
      * @param nlri NLRI to update
+     * @throws BgpParseException while updating to local RIB
      */
-    public void decisionProcess(BgpLSNlri nlri) {
+    public void decisionProcess(BgpLSNlri nlri) throws BgpParseException {
         checkNotNull(nlri);
         if (nlri instanceof BgpNodeLSNlriVer4) {
             selectionProcessNode(nlri, false);
@@ -203,8 +216,9 @@
      *
      * @param nlri NLRI to update
      * @param routeDistinguisher VPN id to update
+     * @throws BgpParseException BGP parse exception
      */
-    public void decisionProcess(BgpLSNlri nlri, RouteDistinguisher routeDistinguisher) {
+    public void decisionProcess(BgpLSNlri nlri, RouteDistinguisher routeDistinguisher) throws BgpParseException {
         checkNotNull(nlri);
         if (nlri instanceof BgpNodeLSNlriVer4) {
             if (vpnNodeTree.containsKey(routeDistinguisher)) {
@@ -235,8 +249,9 @@
      *
      * @param nlri NLRI to update
      * @param isVpnRib true if VPN  local RIB, otherwise false
+     * @throws BgpParseException throws BGP parse exception
      */
-    public void selectionProcessNode(BgpLSNlri nlri, boolean isVpnRib) {
+    public void selectionProcessNode(BgpLSNlri nlri, boolean isVpnRib) throws BgpParseException {
         BgpPeerImpl peer;
         BgpSessionInfo sessionInfo;
         int decisionResult;
@@ -298,8 +313,9 @@
      *
      * @param nlri NLRI to update
      * @param isVpnRib true if VPN local RIB, otherwise false
+     * @throws BgpParseException BGP parse exception
      */
-    public void selectionProcessLink(BgpLSNlri nlri, boolean isVpnRib) {
+    public void selectionProcessLink(BgpLSNlri nlri, boolean isVpnRib) throws BgpParseException {
         BgpPeerImpl peer;
         BgpSessionInfo sessionInfo;
         int decisionResult;
@@ -309,6 +325,9 @@
 
         if (linkTree.containsKey(linkLsIdentifier)) {
             log.debug("Local RIB remove link: {}", linkLsIdentifier.toString());
+            for (BgpLinkListener l : bgpController.linkListener()) {
+                l.deleteLink((BgpLinkLsNlriVer4) nlri);
+            }
             linkTree.remove(linkLsIdentifier);
         }
 
@@ -361,8 +380,9 @@
      *
      * @param nlri NLRI to update
      * @param isVpnRib true if VPN local RIB, otherwise false
+     * @throws BgpParseException BGP parse exception
      */
-    public void selectionProcessPrefix(BgpLSNlri nlri, boolean isVpnRib) {
+    public void selectionProcessPrefix(BgpLSNlri nlri, boolean isVpnRib) throws BgpParseException {
         BgpPeerImpl peer;
         BgpSessionInfo sessionInfo;
         int decisionResult;
@@ -419,7 +439,7 @@
 
     @Override
     public void add(BgpSessionInfo sessionInfo, BgpLSNlri nlri, PathAttrNlriDetails details,
-                    RouteDistinguisher routeDistinguisher) {
+                    RouteDistinguisher routeDistinguisher) throws BgpParseException {
         add(sessionInfo, nlri, details);
         if (nlri instanceof BgpNodeLSNlriVer4) {
             if (!vpnNodeTree.containsKey(routeDistinguisher)) {
@@ -437,7 +457,7 @@
     }
 
     @Override
-    public void delete(BgpLSNlri nlri, RouteDistinguisher routeDistinguisher) {
+    public void delete(BgpLSNlri nlri, RouteDistinguisher routeDistinguisher) throws BgpParseException {
         // Update local RIB
         decisionProcess(nlri, routeDistinguisher);
     }
@@ -446,8 +466,9 @@
      * Update local RIB node based on avaliable peer adjacency RIB.
      *
      * @param o adjacency-in/VPN adjacency-in
+     * @throws BgpParseException BGP parse exception
      */
-    public void localRibUpdateNode(Object o) {
+    public void localRibUpdateNode(Object o) throws BgpParseException {
 
         if (o instanceof AdjRibIn) {
             AdjRibIn adjRib = (AdjRibIn) o;
@@ -487,8 +508,9 @@
      * Update localRIB link based on avaliable peer adjacency RIB.
      *
      * @param o adjacency-in/VPN adjacency-in
+     * @throws BgpParseException BGP parse exceptions
      */
-    public void localRibUpdateLink(Object o) {
+    public void localRibUpdateLink(Object o) throws BgpParseException {
 
         if (o instanceof AdjRibIn) {
             AdjRibIn adjRib = (AdjRibIn) o;
@@ -528,8 +550,9 @@
      * Update localRIB prefix based on avaliable peer adjacency RIB.
      *
      * @param o instance of adjacency-in/VPN adjacency-in
+     * @throws BgpParseException BGP parse exception
      */
-    public void localRibUpdatePrefix(Object o) {
+    public void localRibUpdatePrefix(Object o) throws BgpParseException {
 
         if (o instanceof AdjRibIn) {
             AdjRibIn adjRib = (AdjRibIn) o;
@@ -572,8 +595,9 @@
      * Update localRIB.
      *
      * @param adjRibIn adjacency RIB-in
+     * @throws BgpParseException BGP parse exception
      */
-    public void localRibUpdate(AdjRibIn adjRibIn) {
+    public void localRibUpdate(AdjRibIn adjRibIn) throws BgpParseException {
         log.debug("Update local RIB.");
 
         localRibUpdateNode(adjRibIn);
@@ -585,8 +609,9 @@
      * Update localRIB.
      *
      * @param vpnAdjRibIn VPN adjacency RIB-in
+     * @throws BgpParseException BGP parse exception
      */
-    public void localRibUpdate(VpnAdjRibIn vpnAdjRibIn) {
+    public void localRibUpdate(VpnAdjRibIn vpnAdjRibIn) throws BgpParseException {
         log.debug("Update VPN local RIB.");
 
         localRibUpdateNode(vpnAdjRibIn);
diff --git a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java
index aa02f2c..7ee6aa1 100644
--- a/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java
+++ b/protocols/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java
@@ -425,8 +425,9 @@
      *
      * @param peerImpl BGP peer instance
      * @param nlri NLRI information
+     * @throws BgpParseException BGP parse exception
      */
-    public void callRemove(BgpPeerImpl peerImpl, List<BgpLSNlri> nlri) {
+    public void callRemove(BgpPeerImpl peerImpl, List<BgpLSNlri> nlri) throws BgpParseException {
         ListIterator<BgpLSNlri> listIterator = nlri.listIterator();
         while (listIterator.hasNext()) {
             BgpLSNlri nlriInfo = listIterator.next();
@@ -479,8 +480,9 @@
     /**
      * Update localRIB on peer disconnect.
      *
+     * @throws BgpParseException while updating local RIB
      */
-    public void updateLocalRibOnPeerDisconnect() {
+    public void updateLocalRibOnPeerDisconnect() throws BgpParseException {
         BgpLocalRibImpl localRib = (BgpLocalRibImpl) bgplocalRib;
         BgpLocalRibImpl localRibVpn = (BgpLocalRibImpl) bgplocalRibVpn;
 
@@ -490,7 +492,6 @@
 
     /**
      * Update peer flow specification RIB on peer disconnect.
-     *
      */
     public void updateFlowSpecOnPeerDisconnect() {