Merge "Gracefully stop HT threads when the bundle is being stopped (cache terminated...
authorJason Ye <yisye@cisco.com>
Fri, 30 Aug 2013 14:53:01 +0000 (14:53 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Fri, 30 Aug 2013 14:53:01 +0000 (14:53 +0000)
1  2 
opendaylight/hosttracker/api/src/main/java/org/opendaylight/controller/hosttracker/hostAware/HostNodeConnector.java
opendaylight/hosttracker/implementation/src/main/java/org/opendaylight/controller/hosttracker/internal/HostTracker.java

index 5d52e24c16f3dd82e998459f328689b64b8a6944,eb9a436ed55db7171a833c67b1bf9451e6bff28b..f3f86a56e2b16f70441a0794a88b957f4fae9015
@@@ -8,7 -8,6 +8,6 @@@
  
  package org.opendaylight.controller.hosttracker.hostAware;
  
- import java.io.Serializable;
  import java.net.Inet4Address;
  import java.net.Inet6Address;
  import java.net.InetAddress;
@@@ -27,7 -26,7 +26,7 @@@ import org.opendaylight.controller.sal.
  
  @XmlRootElement(name = "host")
  @XmlAccessorType(XmlAccessType.NONE)
- public class HostNodeConnector extends Host implements Serializable {
+ public class HostNodeConnector extends Host {
      private static final long serialVersionUID = 1L;
      @XmlElement
      private NodeConnector nodeConnector;
  
      @Override
      public boolean equals(Object obj) {
-         if (this == obj)
+         if (this == obj) {
              return true;
-         if (!super.equals(obj))
+         }
+         if (!super.equals(obj)) {
              return false;
-         if (getClass() != obj.getClass())
+         }
+         if (getClass() != obj.getClass()) {
              return false;
+         }
          HostNodeConnector other = (HostNodeConnector) obj;
          if (nodeConnector == null) {
-             if (other.nodeConnector != null)
+             if (other.nodeConnector != null) {
                  return false;
-         } else if (!nodeConnector.equals(other.nodeConnector))
+             }
+         } else if (!nodeConnector.equals(other.nodeConnector)) {
              return false;
-         if (staticHost != other.staticHost)
+         }
+         if (staticHost != other.staticHost) {
              return false;
-         if (vlan != other.vlan)
+         }
+         if (vlan != other.vlan) {
              return false;
+         }
          return true;
      }
  
              EthernetAddress e = (EthernetAddress) getDataLayerAddress();
              macaddr = e.getValue();
          }
-         if (macaddr == null)
+         if (macaddr == null) {
              return false;
+         }
          return !Arrays.equals(emptyArray, macaddr);
      }
  
 +    /*
 +     * (non-Javadoc)
 +     *
 +     * @see java.lang.Object#toString()
 +     */
      @Override
      public String toString() {
 -        return "HostNodeConnector [nodeConnector=" + nodeConnector + ", vlan="
 -                + vlan + ", staticHost=" + staticHost + "]";
 +        StringBuilder builder = new StringBuilder();
 +        builder.append("HostNodeConnector [");
 +        if (nodeConnector != null) {
 +            builder.append("nodeConnector=")
 +                    .append(nodeConnector)
 +                    .append(", ");
 +        }
 +        builder.append("vlan=")
 +                .append(vlan)
 +                .append(", staticHost=")
 +                .append(staticHost)
 +                .append(", arpSendCountDown=")
 +                .append(arpSendCountDown)
 +                .append("]");
 +        return builder.toString();
      }
  
      public boolean isV4Host() {
index 2fd81cbcd7b652e604f63c8f691a16b7dd29b185,a6e1a32c54c257aecce985219f9f1aaa035a71d4..e4704d30489b2a212538ebc1d1503a95b4064784
@@@ -88,8 -88,8 +88,8 @@@ public class HostTracker implements IfI
      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);
-     private IHostFinder hostFinder;
-     private ConcurrentMap<InetAddress, HostNodeConnector> hostsDB;
+     protected IHostFinder hostFinder;
+     protected ConcurrentMap<InetAddress, HostNodeConnector> hostsDB;
      /*
       * Following is a list of hosts which have been requested by NB APIs to be
       * added, but either the switch or the port is not sup, so they will be
      private final Set<IfNewHostNotify> newHostNotify = Collections.synchronizedSet(new HashSet<IfNewHostNotify>());
  
      private ITopologyManager topologyManager;
-     private IClusterContainerServices clusterContainerService = null;
-     private ISwitchManager switchManager = null;
+     protected IClusterContainerServices clusterContainerService = null;
+     protected ISwitchManager switchManager = null;
      private Timer timer;
      private Timer arpRefreshTimer;
      private String containerName = null;
      private ExecutorService executor;
+     protected boolean stopping;
      private static class ARPPending {
          protected InetAddress hostIP;
          protected short sent_count;
              hostTrackerCallable = callable;
          }
      }
      // This list contains the hosts for which ARP requests are being sent
      // periodically
      ConcurrentMap<InetAddress, ARPPending> ARPPendingList;
          nonClusterObjectCreate();
          allocateCache();
          retrieveCache();
+         stopping = false;
  
          timer = new Timer();
          timer.schedule(new OutStandingARPHandler(), 4000, 4000);
          logger.debug("startUp: Caches created, timers started");
      }
  
-     @SuppressWarnings("deprecation")
      private void allocateCache() {
          if (this.clusterContainerService == null) {
              logger.error("un-initialized clusterContainerService, can't create cache");
          logger.debug("Cache successfully created for HostTracker");
      }
  
-     @SuppressWarnings({ "unchecked", "deprecation" })
+     @SuppressWarnings({ "unchecked" })
      private void retrieveCache() {
          if (this.clusterContainerService == null) {
              logger.error("un-initialized clusterContainerService, can't retrieve cache");
          failedARPReqList = new ConcurrentHashMap<InetAddress, ARPPending>();
      }
  
      public void shutDown() {
      }
  
  
          /* Add this host to ARPPending List for any potential retries */
  
-         AddtoARPPendingList(networkAddress);
+         addToARPPendingList(networkAddress);
          logger.debug("hostFind(): Host Not Found for IP: {}, Inititated Host Discovery ...",
                  networkAddress.getHostAddress());
  
          return list;
      }
  
-     private void AddtoARPPendingList(InetAddress networkAddr) {
+     private void addToARPPendingList(InetAddress networkAddr) {
          ARPPending arphost = new ARPPending();
  
          arphost.setHostIP(networkAddr);
  
      public void setCallableOnPendingARP(InetAddress networkAddr, HostTrackerCallable callable) {
          ARPPending arphost;
-         for (Entry <InetAddress, ARPPending> entry : ARPPendingList.entrySet()) {
+         for (Entry<InetAddress, ARPPending> entry : ARPPendingList.entrySet()) {
              arphost = entry.getValue();
              if (arphost.getHostIP().equals(networkAddr)) {
                  arphost.setHostTrackerCallable(callable);
              // Remove the arphost from ARPPendingList as it has been learned now
              logger.debug("Host Removed from ARPPending List, IP: {}", networkAddr);
              HostTrackerCallable htCallable = arphost.getHostTrackerCallable();
-             if (htCallable != null)
+             if (htCallable != null) {
                  htCallable.wakeup();
+             }
              return;
          }
  
           * It could have been a host from the FailedARPReqList
           */
  
-         if  (failedARPReqList.containsKey(networkAddr)) {
+         if (failedARPReqList.containsKey(networkAddr)) {
              failedARPReqList.remove(networkAddr);
              logger.debug("Host Removed from FailedARPReqList List, IP: {}", networkAddr);
          }
                      replaceHost(networkAddr, removedHost, host);
                      return;
                  } else {
-                     logger.error("Host to be removed not found in hostsDB. Host {}", removedHost);
+                     logger.error("Host to be removed not found in hostsDB");
                  }
              }
  
-             if (removedHost == null) {
-                 // It is a new host
-                 learnNewHost(host);
-             }
+             // It is a new host
+             learnNewHost(host);
  
              /* check if there is an outstanding request for this host */
              processPendingARPReqs(networkAddr);
          if (hostExists(host)) {
              HostNodeConnector existinghost = hostsDB.get(host.getNetworkAddress());
              existinghost.initArpSendCountDown();
 +            // Update the host
 +            hostsDB.put(host.getNetworkAddress(), existinghost);
              return;
          }
          new NotifyHostThread(host).start();
       * @param currentTier
       *            The Tier on which n belongs
       */
+     @SuppressWarnings("unused")
      private void updateSwitchTiers(Node n, int currentTier) {
          Map<Node, Set<Edge>> ndlinks = topologyManager.getNodeEdges();
          if (ndlinks == null) {
          }
          // This is the case where Tier was never set for this node
          Tier t = (Tier) switchManager.getNodeProp(n, Tier.TierPropName);
-         if (t == null)
+         if (t == null) {
              return true;
-         if (t.getValue() == 0)
+         }
+         if (t.getValue() == 0) {
              return true;
-         else if (t.getValue() > tier)
+         } else if (t.getValue() > tier) {
              return true;
+         }
          return false;
      }
  
       * cleanup is performed during cases such as Topology Change where the
       * existing Tier values might become incorrect
       */
+     @SuppressWarnings("unused")
      private void clearTiers() {
          Set<Node> nodes = null;
          if (switchManager == null) {
      @Override
      public List<List<String>> getHostNetworkHierarchy(InetAddress hostAddress) {
          HostNodeConnector host = hostQuery(hostAddress);
-         if (host == null)
+         if (host == null) {
              return null;
+         }
  
          List<List<String>> hierarchies = new ArrayList<List<String>>();
          ArrayList<String> currHierarchy = new ArrayList<String>();
          int result = 0;
          for (int i = 0; i < hex.length(); i++) {
              result = (int) ((dpid >> (i * 8)) & 0xff);
-             if (result == 0)
+             if (result == 0) {
                  continue;
-             if (result < 0x30)
+             }
+             if (result < 0x30) {
                  result += 0x40;
+             }
              sb.append(String.format("%c", result));
          }
          return sb.reverse().toString();
      public void subnetNotify(Subnet sub, boolean add) {
          logger.debug("Received subnet notification: {}  add={}", sub, add);
          if (add) {
-             for (Entry <InetAddress, ARPPending> entry : failedARPReqList.entrySet()) {
+             for (Entry<InetAddress, ARPPending> entry : failedARPReqList.entrySet()) {
                  ARPPending arphost;
                  arphost = entry.getValue();
                  if (hostFinder == null) {
                      logger.warn("ARPHandler Services are not available on subnet addition");
                      continue;
                  }
-                logger.debug("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostIP().getHostAddress());
-                hostFinder.find(arphost.getHostIP());
+                 logger.debug("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostIP().getHostAddress());
+                 hostFinder.find(arphost.getHostIP());
              }
          }
      }
      class OutStandingARPHandler extends TimerTask {
          @Override
          public void run() {
+             if (stopping) {
+                 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 <InetAddress, ARPPending> entry : ARPPendingList.entrySet()) {
+             for (Entry<InetAddress, ARPPending> entry : ARPPendingList.entrySet()) {
                  arphost = entry.getValue();
  
                  if (hostsDB.containsKey(arphost.getHostIP())) {
-                     // this host is already learned, shouldn't be in ARPPendingList
+                     // this host is already learned, shouldn't be in
+                     // ARPPendingList
                      // Remove it and continue
                      logger.warn("Learned Host {} found in ARPPendingList", arphost.getHostIP());
                      ARPPendingList.remove(entry.getKey());
                  if (arphost.getSent_count() < switchManager.getHostRetryCount()) {
                      /*
                       * No reply has been received of first ARP Req, send the
-                      * next one. Before sending the ARP, check if ARPHandler
-                      * is available or not
+                      * 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");
                      logger.debug("ARP Sent from ARPPending List, IP: {}", arphost.getHostIP().getHostAddress());
                  } else if (arphost.getSent_count() >= switchManager.getHostRetryCount()) {
                      /*
-                      * ARP requests have been sent without receiving a
-                      * reply, remove this from the pending list
+                      * 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: {}",
  
      private class ARPRefreshHandler extends TimerTask {
          @Override
-         @SuppressWarnings("deprecation")
          public void run() {
+             if (stopping) {
+                 return;
+             }
              if ((clusterContainerService != null) && !clusterContainerService.amICoordinator()) {
                  return;
              }
  
      @Override
      public void notifyNode(Node node, UpdateType type, Map<String, Property> propMap) {
-         if (node == null)
+         if (node == null) {
              return;
+         }
  
          switch (type) {
          case REMOVED:
  
      @Override
      public void notifyNodeConnector(NodeConnector nodeConnector, UpdateType type, Map<String, Property> propMap) {
-         if (nodeConnector == null)
+         if (nodeConnector == null) {
              return;
+         }
  
          boolean up = false;
          switch (type) {
  
          logger.debug("handleNodeConnectorStatusUp {}", nodeConnector);
  
-         for (Entry <InetAddress, ARPPending> entry : failedARPReqList.entrySet()) {
+         for (Entry<InetAddress, ARPPending> entry : failedARPReqList.entrySet()) {
              arphost = entry.getValue();
              logger.debug("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostIP().getHostAddress());
              if (hostFinder == null) {
      }
  
      public String getContainerName() {
-         if (containerName == null)
+         if (containerName == null) {
              return GlobalConstants.DEFAULT.toString();
+         }
          return containerName;
      }
  
       * calls
       *
       */
-     void stop(){
+     void stop() {
      }
  
      void stopping() {
+         stopping = true;
          arpRefreshTimer.cancel();
          timer.cancel();
-         executor.shutdown();
+         executor.shutdownNow();
      }
  
      @Override
      public void edgeOverUtilized(Edge edge) {
-         // TODO Auto-generated method stub
  
      }
  
      @Override
      public void edgeUtilBackToNormal(Edge edge) {
-         // TODO Auto-generated method stub
  
      }
  
      @Override
-     public void entryCreated(InetAddress key, String cacheName,
-             boolean originLocal) {
-         if (originLocal) return;
+     public void entryCreated(InetAddress key, String cacheName, boolean originLocal) {
+         if (originLocal) {
+             return;
+         }
          processPendingARPReqs(key);
      }
  
      @Override
-     public void entryUpdated(InetAddress key, HostNodeConnector new_value,
-             String cacheName, boolean originLocal) {
+     public void entryUpdated(InetAddress key, HostNodeConnector new_value, String cacheName, boolean originLocal) {
      }
  
      @Override
-     public void entryDeleted(InetAddress key, String cacheName,
-             boolean originLocal) {
+     public void entryDeleted(InetAddress key, String cacheName, boolean originLocal) {
      }
  
      private void registerWithOSGIConsole() {
  
      @Override
      public String getHelp() {
-         // TODO Auto-generated method stub
          return null;
      }
  
      public void _dumpPendingARPReqList(CommandInterpreter ci) {
          ARPPending arphost;
-         for (Entry <InetAddress, ARPPending> entry : ARPPendingList.entrySet()) {
+         for (Entry<InetAddress, ARPPending> entry : ARPPendingList.entrySet()) {
              arphost = entry.getValue();
              ci.println(arphost.getHostIP().toString());
          }
  
      public void _dumpFailedARPReqList(CommandInterpreter ci) {
          ARPPending arphost;
-         for (Entry <InetAddress, ARPPending> entry : failedARPReqList.entrySet()) {
+         for (Entry<InetAddress, ARPPending> entry : failedARPReqList.entrySet()) {
              arphost = entry.getValue();
              ci.println(arphost.getHostIP().toString());
          }