Merge "added feature topology manager shell"
[controller.git] / opendaylight / hosttracker / implementation / src / main / java / org / opendaylight / controller / hosttracker / internal / HostTracker.java
index e1a8ef806a0f9ad9225392db87c3b656c0a6dbb8..f728b35bbfa7f492c3937b87616e4b655ba3f16f 100644 (file)
@@ -39,6 +39,7 @@ import org.opendaylight.controller.clustering.services.IClusterContainerServices
 import org.opendaylight.controller.clustering.services.IClusterServices;
 import org.opendaylight.controller.hosttracker.HostIdFactory;
 import org.opendaylight.controller.hosttracker.IHostId;
+import org.opendaylight.controller.hosttracker.IHostTrackerShell;
 import org.opendaylight.controller.hosttracker.IPHostId;
 import org.opendaylight.controller.hosttracker.IPMacHostId;
 import org.opendaylight.controller.hosttracker.IfHostListener;
@@ -100,12 +101,12 @@ import org.slf4j.LoggerFactory;
  *
  */
 
-public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAware, IInventoryListener,
+public class HostTracker implements IfIptoHost, IfHostListener, IHostTrackerShell, ISwitchManagerAware, IInventoryListener,
         ITopologyManagerAware, ICacheUpdateAware<IHostId, HostNodeConnector>, CommandProvider {
     static final String ACTIVE_HOST_CACHE = "hosttracker.ActiveHosts";
     static final String INACTIVE_HOST_CACHE = "hosttracker.InactiveHosts";
     private static final Logger logger = LoggerFactory.getLogger(HostTracker.class);
-    protected final Set<IHostFinder> hostFinder = new CopyOnWriteArraySet<IHostFinder>();;
+    protected final Set<IHostFinder> hostFinders = new CopyOnWriteArraySet<IHostFinder>();
     protected ConcurrentMap<IHostId, HostNodeConnector> hostsDB;
     /*
      * Following is a list of hosts which have been requested by NB APIs to be
@@ -256,16 +257,12 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
     }
 
     public void setArpHandler(IHostFinder hostFinder) {
-        if (this.hostFinder != null) {
-            this.hostFinder.add(hostFinder);
-        }
+        this.hostFinders.add(hostFinder);
     }
 
     public void unsetArpHandler(IHostFinder hostFinder) {
-        if (this.hostFinder != null) {
-            logger.debug("Arp Handler Service removed!");
-            this.hostFinder.remove(hostFinder);
-        }
+        logger.debug("Arp Handler Service removed!");
+        this.hostFinders.remove(hostFinder);
     }
 
     public void setTopologyManager(ITopologyManager s) {
@@ -352,8 +349,8 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
          * already handles the null return
          */
 
-        if (hostFinder == null) {
-            logger.debug("Exiting hostFind, null hostFinder");
+        if (hostFinders.isEmpty()) {
+            logger.debug("No available host finders, exiting hostFind()");
             return null;
         }
 
@@ -369,7 +366,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
         logger.debug("hostFind(): Host Not Found for IP: {}, Inititated Host Discovery ...", id);
 
         /* host is not found, initiate a discovery */
-        for (IHostFinder hf : hostFinder) {
+        for (IHostFinder hf : hostFinders) {
             InetAddress addr = decodeIPFromId(id);
             hf.find(addr);
         }
@@ -480,7 +477,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
              * Host replacement has failed, do the recovery
              */
             hostsDB.put(id, newHost);
-            logger.error("Host replacement failed. Overwrite the host. Repalced Host: {}, New Host: {}", removedHost,
+            logger.error("Host replacement failed. Overwrite the host. Replaced Host: {}, New Host: {}", removedHost,
                     newHost);
         }
         notifyHostLearnedOrRemoved(removedHost, false);
@@ -936,18 +933,22 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
             for (Entry<IHostId, ARPPending> entry : failedARPReqList.entrySet()) {
                 ARPPending arphost;
                 arphost = entry.getValue();
-                if (hostFinder == null) {
-                    logger.warn("ARPHandler Services are not available on subnet addition");
+                if (hostFinders.isEmpty()) {
+                    logger.debug("ARPHandler Services are not available on subnet addition");
                     continue;
                 }
                 logger.debug("Sending the ARP from FailedARPReqList fors IP: {}", decodeIPFromId(arphost.getHostId()));
-                for (IHostFinder hf : hostFinder) {
+                for (IHostFinder hf : hostFinders) {
                     hf.find(decodeIPFromId(arphost.getHostId()));
                 }
             }
         }
     }
 
+    /*
+     * This thread runs every 4 seconds
+     */
+
     class OutStandingARPHandler extends TimerTask {
         @Override
         public void run() {
@@ -955,53 +956,55 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
                 return;
             }
             ARPPending arphost;
-            /* This routine runs every 4 seconds */
-            logger.trace("Number of Entries in ARP Pending/Failed Lists: ARPPendingList = {}, failedARPReqList = {}",
-                    ARPPendingList.size(), failedARPReqList.size());
-            for (Entry<IHostId, ARPPending> entry : ARPPendingList.entrySet()) {
-                arphost = entry.getValue();
-
-                if (hostsDB.containsKey(arphost.getHostId())) {
-                    // this host is already learned, shouldn't be in
-                    // ARPPendingList
-                    // Remove it and continue
-                    logger.warn("Learned Host {} found in ARPPendingList", decodeIPFromId(arphost.getHostId()));
-                    ARPPendingList.remove(entry.getKey());
-                    continue;
-                }
-                if (arphost.getSent_count() < hostRetryCount) {
-                    /*
-                     * No reply has been received of first ARP Req, send the
-                     * next one. Before sending the ARP, check if ARPHandler is
-                     * available or not
-                     */
-                    if (hostFinder == null) {
-                        logger.warn("ARPHandler Services are not available for Outstanding ARPs");
+            try {
+                for (Entry<IHostId, ARPPending> entry : ARPPendingList.entrySet()) {
+                    arphost = entry.getValue();
+
+                    if (hostsDB.containsKey(arphost.getHostId())) {
+                        // this host is already learned, shouldn't be in
+                        // ARPPendingList
+                        // Remove it and continue
+                        logger.warn("Learned Host {} found in ARPPendingList", decodeIPFromId(arphost.getHostId()));
+                        ARPPendingList.remove(entry.getKey());
                         continue;
                     }
-                    for (IHostFinder hf : hostFinder) {
-                        hf.find(decodeIPFromId(arphost.getHostId()));
-                    }
-                    arphost.sent_count++;
-                    logger.debug("ARP Sent from ARPPending List, IP: {}", decodeIPFromId(arphost.getHostId()));
-                } else if (arphost.getSent_count() >= hostRetryCount) {
-                    /*
-                     * ARP requests have been sent without receiving a reply,
-                     * remove this from the pending list
-                     */
-                    ARPPendingList.remove(entry.getKey());
-                    logger.debug("ARP reply not received after multiple attempts, removing from Pending List IP: {}",
-                            decodeIPFromId(arphost.getHostId()));
-                    /*
-                     * Add this host to a different list which will be processed
-                     * on link up events
-                     */
-                    logger.debug("Adding the host to FailedARPReqList IP: {}", decodeIPFromId(arphost.getHostId()));
-                    failedARPReqList.put(entry.getKey(), arphost);
+                    if (arphost.getSent_count() < hostRetryCount) {
+                        /*
+                         * No reply has been received of first ARP Req, send the
+                         * next one. Before sending the ARP, check if ARPHandler
+                         * is available or not
+                         */
+                        if (hostFinders.isEmpty()) {
+                            logger.warn("ARPHandler Services are not available for Outstanding ARPs");
+                            continue;
+                        }
+                        for (IHostFinder hf : hostFinders) {
+                            hf.find(decodeIPFromId(arphost.getHostId()));
+                        }
+                        arphost.sent_count++;
+                        logger.debug("ARP Sent from ARPPending List, IP: {}", decodeIPFromId(arphost.getHostId()));
+                    } else if (arphost.getSent_count() >= hostRetryCount) {
+                        /*
+                         * ARP requests have been sent without receiving a
+                         * reply, remove this from the pending list
+                         */
+                        ARPPendingList.remove(entry.getKey());
+                        logger.debug(
+                                "ARP reply not received after multiple attempts, removing from Pending List IP: {}",
+                                decodeIPFromId(arphost.getHostId()));
+                        /*
+                         * Add this host to a different list which will be
+                         * processed on link up events
+                         */
+                        logger.debug("Adding the host to FailedARPReqList IP: {}", decodeIPFromId(arphost.getHostId()));
+                        failedARPReqList.put(entry.getKey(), arphost);
 
-                } else {
-                    logger.error("Inavlid arp_sent count for entry: {}", entry);
+                    } else {
+                        logger.error("Inavlid arp_sent count for entry: {}", entry);
+                    }
                 }
+            } catch (IllegalStateException e) {
+                logger.debug("IllegalStateException Received by OutStandingARPHandler from: {}", e.getMessage());
             }
         }
     }
@@ -1009,10 +1012,10 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
     private class ARPRefreshHandler extends TimerTask {
         @Override
         public void run() {
-            if (stopping) {
+            if ((clusterContainerService != null) && !clusterContainerService.amICoordinator()) {
                 return;
             }
-            if ((clusterContainerService != null) && !clusterContainerService.amICoordinator()) {
+            if (stopping) {
                 return;
             }
             if (!hostRefresh) {
@@ -1026,49 +1029,54 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
                 logger.error("ARPRefreshHandler(): hostsDB is not allocated yet:");
                 return;
             }
-            for (Entry<IHostId, HostNodeConnector> entry : hostsDB.entrySet()) {
-                HostNodeConnector host = entry.getValue();
-                if (host.isStaticHost()) {
-                    /* this host was learned via API3, don't age it out */
-                    continue;
-                }
-
-                short arp_cntdown = host.getArpSendCountDown();
-                arp_cntdown--;
-                if (arp_cntdown > hostRetryCount) {
-                    host.setArpSendCountDown(arp_cntdown);
-                } else if (arp_cntdown <= 0) {
-                    /*
-                     * No ARP Reply received in last 2 minutes, remove this host
-                     * and inform applications
-                     */
-                    removeKnownHost(entry.getKey());
-                    notifyHostLearnedOrRemoved(host, false);
-                } else if (arp_cntdown <= hostRetryCount) {
-                    /*
-                     * Use the services of arphandler to check if host is still
-                     * there
-                     */
-                    if (logger.isTraceEnabled()) {
-                        logger.trace(
-                                "ARP Probing ({}) for {}({})",
-                                new Object[] { arp_cntdown, host.getNetworkAddress().getHostAddress(),
-                                        HexEncode.bytesToHexString(host.getDataLayerAddressBytes()) });
+            try {
+                for (Entry<IHostId, HostNodeConnector> entry : hostsDB.entrySet()) {
+                    HostNodeConnector host = entry.getValue();
+                    if (host.isStaticHost()) {
+                        /* this host was learned via API3, don't age it out */
+                        continue;
                     }
-                    host.setArpSendCountDown(arp_cntdown);
-                    if (hostFinder == null) {
+
+                    short arp_cntdown = host.getArpSendCountDown();
+                    arp_cntdown--;
+                    if (arp_cntdown > hostRetryCount) {
+                        host.setArpSendCountDown(arp_cntdown);
+                    } else if (arp_cntdown <= 0) {
                         /*
-                         * If hostfinder is not available, then can't send the
-                         * probe. However, continue the age out the hosts since
-                         * we don't know if the host is indeed out there or not.
+                         * No ARP Reply received in last 2 minutes, remove this
+                         * host and inform applications
                          */
-                        logger.trace("ARPHandler is not avaialable, can't send the probe");
-                        continue;
-                    }
-                    for (IHostFinder hf : hostFinder) {
-                        hf.probe(host);
+                        removeKnownHost(entry.getKey());
+                        notifyHostLearnedOrRemoved(host, false);
+                    } else if (arp_cntdown <= hostRetryCount) {
+                        /*
+                         * Use the services of arphandler to check if host is
+                         * still there
+                         */
+                        if (logger.isTraceEnabled()) {
+                            logger.trace(
+                                    "ARP Probing ({}) for {}({})",
+                                    new Object[] { arp_cntdown, host.getNetworkAddress().getHostAddress(),
+                                            HexEncode.bytesToHexString(host.getDataLayerAddressBytes()) });
+                        }
+                        host.setArpSendCountDown(arp_cntdown);
+                        if (hostFinders.isEmpty()) {
+                            /*
+                             * If hostfinder is not available, then can't send
+                             * the probe. However, continue the age out the
+                             * hosts since we don't know if the host is indeed
+                             * out there or not.
+                             */
+                            logger.trace("ARPHandler is not avaialable, can't send the probe");
+                            continue;
+                        }
+                        for (IHostFinder hf : hostFinders) {
+                            hf.probe(host);
+                        }
                     }
                 }
+            } catch (IllegalStateException e) {
+                logger.debug("IllegalStateException  Received by ARPRefreshHandler from: {}", e.getMessage());
             }
         }
     }
@@ -1406,7 +1414,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
         for (Entry<IHostId, ARPPending> entry : failedARPReqList.entrySet()) {
             arphost = entry.getValue();
             logger.trace("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostId());
-            if (hostFinder == null) {
+            if (hostFinders.isEmpty()) {
                 logger.warn("ARPHandler is not available at interface  up");
                 logger.warn("Since this event is missed, host(s) connected to interface {} may not be discovered",
                         nodeConnector);
@@ -1419,7 +1427,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
                 byte[] dataLayerAddress = NetUtils.getBroadcastMACAddr();
                 host = new HostNodeConnector(dataLayerAddress, decodeIPFromId(arphost.getHostId()), nodeConnector,
                         (short) 0);
-                for (IHostFinder hf : hostFinder) {
+                for (IHostFinder hf : hostFinders) {
                     hf.probe(host);
                 }
             } catch (ConstructionException e) {
@@ -1611,4 +1619,24 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
         IHostId id = HostIdFactory.create(addr, null);
         return getHostNetworkHierarchy(id);
     }
+
+    @Override
+    public List<String> dumpPendingArpReqList() {
+        ARPPending arphost;
+        List<String> arpReq = new ArrayList<String>();
+        for (Entry<IHostId, ARPPending> entry : ARPPendingList.entrySet()) {
+            arpReq.add(entry.getValue().getHostId().toString());
+        }
+        return arpReq;
+    }
+
+    @Override
+    public List<String> dumpFailedArpReqList() {
+        ARPPending arphost;
+        List<String> arpReq = new ArrayList<String>();
+        for (Entry<IHostId, ARPPending> entry : failedARPReqList.entrySet()) {
+            arpReq.add(entry.getValue().getHostId().toString());
+        }
+        return arpReq;
+    }
 }