X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fhosttracker%2Fimplementation%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fhosttracker%2Finternal%2FHostTracker.java;h=4fa4da318a2f67f645bad1d92255899fd8875937;hp=446f51eb04c81bd3be6f38038e1d6b33cb5fe964;hb=cafd50eb82c5bb862d16b8f25a0a6bea983732f4;hpb=316c30bf96a3a540154983657490ff2043458d25 diff --git a/opendaylight/hosttracker/implementation/src/main/java/org/opendaylight/controller/hosttracker/internal/HostTracker.java b/opendaylight/hosttracker/implementation/src/main/java/org/opendaylight/controller/hosttracker/internal/HostTracker.java index 446f51eb04..4fa4da318a 100644 --- a/opendaylight/hosttracker/implementation/src/main/java/org/opendaylight/controller/hosttracker/internal/HostTracker.java +++ b/opendaylight/hosttracker/implementation/src/main/java/org/opendaylight/controller/hosttracker/internal/HostTracker.java @@ -31,6 +31,7 @@ import java.util.concurrent.Future; import org.apache.felix.dm.Component; import org.opendaylight.controller.clustering.services.CacheConfigException; import org.opendaylight.controller.clustering.services.CacheExistException; +import org.opendaylight.controller.clustering.services.ICacheUpdateAware; import org.opendaylight.controller.clustering.services.IClusterContainerServices; import org.opendaylight.controller.clustering.services.IClusterServices; import org.opendaylight.controller.hosttracker.IfHostListener; @@ -79,7 +80,9 @@ import org.slf4j.LoggerFactory; */ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAware, IInventoryListener, - ITopologyManagerAware { + ITopologyManagerAware, ICacheUpdateAware { + static final String ACTIVE_HOST_CACHE = "hostTrackerAH"; + static final String INACTIVE_HOST_CACHE = "hostTrackerIH"; private static final Logger logger = LoggerFactory.getLogger(HostTracker.class); private IHostFinder hostFinder; private ConcurrentMap hostsDB; @@ -95,9 +98,9 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw private IClusterContainerServices clusterContainerService = null; private ISwitchManager switchManager = null; private Timer timer; - private Timer arp_refresh_timer; + private Timer arpRefreshTimer; private String containerName = null; - + private ExecutorService executor; private static class ARPPending { protected InetAddress hostIP; protected short sent_count; @@ -147,7 +150,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw * * We can't recover from condition 3 above */ - private final ArrayList failedARPReqList = new ArrayList(); + private final List failedARPReqList = new ArrayList(); public HostTracker() { } @@ -158,10 +161,10 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw timer = new Timer(); timer.schedule(new OutStandingARPHandler(), 4000, 4000); - + executor = Executors.newFixedThreadPool(2); /* ARP Refresh Timer to go off every 5 seconds to implement ARP aging */ - arp_refresh_timer = new Timer(); - arp_refresh_timer.schedule(new ARPRefreshHandler(), 5000, 5000); + arpRefreshTimer = new Timer(); + arpRefreshTimer.schedule(new ARPRefreshHandler(), 5000, 5000); logger.debug("startUp: Caches created, timers started"); } @@ -173,9 +176,9 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw } logger.debug("Creating Cache for HostTracker"); try { - this.clusterContainerService.createCache("hostTrackerAH", + this.clusterContainerService.createCache(ACTIVE_HOST_CACHE, EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL)); - this.clusterContainerService.createCache("hostTrackerIH", + this.clusterContainerService.createCache(INACTIVE_HOST_CACHE, EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL)); } catch (CacheConfigException cce) { logger.error("Cache couldn't be created for HostTracker - check cache mode"); @@ -193,14 +196,14 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw } logger.debug("Retrieving cache for HostTrackerAH"); hostsDB = (ConcurrentMap) this.clusterContainerService - .getCache("hostTrackerAH"); + .getCache(ACTIVE_HOST_CACHE); if (hostsDB == null) { logger.error("Cache couldn't be retrieved for HostTracker"); } logger.debug("Cache was successfully retrieved for HostTracker"); logger.debug("Retrieving cache for HostTrackerIH"); inactiveStaticHosts = (ConcurrentMap) this.clusterContainerService - .getCache("hostTrackerIH"); + .getCache(INACTIVE_HOST_CACHE); if (inactiveStaticHosts == null) { logger.error("Cache couldn't be retrieved for HostTrackerIH"); } @@ -212,17 +215,6 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw inactiveStaticHosts = new ConcurrentHashMap(); } - @SuppressWarnings("deprecation") - private void destroyCache() { - if (this.clusterContainerService == null) { - logger.error("un-initialized clusterMger, can't destroy cache"); - return; - } - logger.debug("Destroying Cache for HostTracker"); - this.clusterContainerService.destroyCache("hostTrackerAH"); - this.clusterContainerService.destroyCache("hostTrackerIH"); - nonClusterObjectCreate(); - } public void shutDown() { } @@ -307,7 +299,6 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw @Override public Future discoverHost(InetAddress networkAddress) { - ExecutorService executor = Executors.newFixedThreadPool(1); if (executor == null) { logger.error("discoverHost: Null executor"); return null; @@ -335,12 +326,16 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw logger.debug("hostFind(): Host found for IP: {}", networkAddress.getHostAddress()); return host; } - /* host is not found, initiate a discovery */ - hostFinder.find(networkAddress); - /* Also add this host to ARPPending List for any potential retries */ + + /* Add this host to ARPPending List for any potential retries */ + AddtoARPPendingList(networkAddress); logger.debug("hostFind(): Host Not Found for IP: {}, Inititated Host Discovery ...", networkAddress.getHostAddress()); + + /* host is not found, initiate a discovery */ + + hostFinder.find(networkAddress); return null; } @@ -409,7 +404,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw } } - private void ProcPendingARPReqs(InetAddress networkAddr) { + private void processPendingARPReqs(InetAddress networkAddr) { ARPPending arphost; for (int i = 0; i < ARPPendingList.size(); i++) { @@ -459,7 +454,13 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw private void replaceHost(InetAddress networkAddr, HostNodeConnector removedHost, HostNodeConnector newHost) { newHost.initArpSendCountDown(); if (hostsDB.replace(networkAddr, removedHost, newHost)) { - logger.debug("Host move occurred. Old Host:{}, New Host: {}", removedHost, newHost); + logger.debug("Host move occurred: Old Host IP:{}, New Host IP: {}", removedHost.getNetworkAddress() + .getHostAddress(), newHost.getNetworkAddress().getHostAddress()); + logger.debug("Old Host MAC: {}, New Host MAC: {}", + HexEncode.bytesToHexString(removedHost.getDataLayerAddressBytes()), + HexEncode.bytesToHexString(newHost.getDataLayerAddressBytes())); + // Display the Old and New HostNodeConnectors also + logger.debug("Old {}, New {}", removedHost, newHost); } else { /* * Host replacement has failed, do the recovery @@ -471,7 +472,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw notifyHostLearnedOrRemoved(removedHost, false); notifyHostLearnedOrRemoved(newHost, true); if (!newHost.isStaticHost()) { - ProcPendingARPReqs(networkAddr); + processPendingARPReqs(networkAddr); } } @@ -522,7 +523,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw } /* check if there is an outstanding request for this host */ - ProcPendingARPReqs(networkAddr); + processPendingARPReqs(networkAddr); notifyHostLearnedOrRemoved(host, true); } } @@ -530,8 +531,9 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw @Override public void hostListener(HostNodeConnector host) { + logger.debug("ARP received for Host: IP {}, MAC {}, {}", host.getNetworkAddress().getHostAddress(), + HexEncode.bytesToHexString(host.getDataLayerAddressBytes()), host); if (hostExists(host)) { - logger.debug("ARP received for Host: {}", host); HostNodeConnector existinghost = hostsDB.get(host.getNetworkAddress()); existinghost.initArpSendCountDown(); return; @@ -544,6 +546,8 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw private void notifyHostLearnedOrRemoved(HostNodeConnector host, boolean add) { // Update listeners if any if (newHostNotify != null) { + logger.debug("Notifying Applications for Host {} Being {}", host.getNetworkAddress().getHostAddress(), + add ? "Added" : "Deleted"); synchronized (this.newHostNotify) { for (IfNewHostNotify ta : newHostNotify) { try { @@ -575,6 +579,8 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw } if (topologyManager != null && p != null && h != null) { + logger.debug("Notifying Topology Manager for Host {} Being {}", h.getNetworkAddress().getHostAddress(), + add ? "Added" : "Deleted"); if (add == true) { Tier tier = new Tier(1); switchManager.setNodeProp(node, tier); @@ -778,10 +784,8 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw private void updateCurrentHierarchy(Node node, ArrayList currHierarchy, List> fullHierarchy) { // currHierarchy.add(String.format("%x", currSw.getId())); currHierarchy.add(dpidToHostNameHack((Long) node.getID())); - ArrayList currHierarchyClone = (ArrayList) currHierarchy.clone(); // Shallow - // copy - // as - // required + // Shallow copy as required + ArrayList currHierarchyClone = (ArrayList) currHierarchy.clone(); Map> ndlinks = topologyManager.getNodeEdges(); if (ndlinks == null) { @@ -803,14 +807,27 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw Node dstNode = lt.getHeadNodeConnector().getNode(); Tier nodeTier = (Tier) switchManager.getNodeProp(node, Tier.TierPropName); + /* + * If the host is directly attached to the src node, then the node + * should have been assigned the "Access" tier in + * notifyHostLearnedOrRemoved. If not, it would be assigned + * "Unknown" tier. Thus the tier of host attached node cannot be + * null. If the src node here, is the next node in the hierarchy of + * the nodes, then its tier cannot be null + */ + Tier dstNodeTier = (Tier) switchManager.getNodeProp(dstNode, Tier.TierPropName); + /* + * Skip if the tier of the destination node is null + */ + if (dstNodeTier == null) { + continue; + } if (dstNodeTier.getValue() > nodeTier.getValue()) { ArrayList buildHierarchy = currHierarchy; if (currHierarchy.size() > currHierarchyClone.size()) { - buildHierarchy = (ArrayList) currHierarchyClone.clone(); // Shallow - // copy - // as - // required + // Shallow copy as required + buildHierarchy = (ArrayList) currHierarchyClone.clone(); fullHierarchy.add(buildHierarchy); } updateCurrentHierarchy(dstNode, buildHierarchy, fullHierarchy); @@ -818,7 +835,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw } } - private void edgeUpdate(Edge e, UpdateType type, Set props) { + private void debugEdgeUpdate(Edge e, UpdateType type, Set props) { Long srcNid = null; Short srcPort = null; Long dstNid = null; @@ -840,7 +857,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw } if (!srcType.equals(NodeConnector.NodeConnectorIDType.OPENFLOW)) { - logger.error("For now we cannot handle updates for " + "non-openflow nodes"); + logger.debug("For now we cannot handle updates for non-openflow nodes"); return; } @@ -850,7 +867,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw } if (!dstType.equals(NodeConnector.NodeConnectorIDType.OPENFLOW)) { - logger.error("For now we cannot handle updates for " + "non-openflow nodes"); + logger.debug("For now we cannot handle updates for non-openflow nodes"); return; } @@ -878,11 +895,14 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw @Override public void edgeUpdate(List topoedgeupdateList) { - for (int i = 0; i < topoedgeupdateList.size(); i++) { - Edge e = topoedgeupdateList.get(i).getEdge(); - Set p = topoedgeupdateList.get(i).getProperty(); - UpdateType type = topoedgeupdateList.get(i).getUpdateType(); - edgeUpdate(e, type, p); + if (logger.isDebugEnabled()) { + for (TopoEdgeUpdate topoEdgeUpdate : topoedgeupdateList) { + Edge e = topoEdgeUpdate.getEdge(); + Set p = topoEdgeUpdate.getProperty(); + UpdateType type = topoEdgeUpdate.getUpdateType(); + + debugEdgeUpdate(e, type, p); + } } } @@ -893,8 +913,12 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw for (int i = 0; i < failedARPReqList.size(); i++) { ARPPending arphost; arphost = failedARPReqList.get(i); - logger.debug("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostIP().getHostAddress()); - hostFinder.find(arphost.getHostIP()); + 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()); } } } @@ -904,24 +928,28 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw public void run() { ARPPending arphost; /* This routine runs every 4 seconds */ - // logger.info ("ARP Handler called"); for (int i = 0; i < ARPPendingList.size(); i++) { arphost = ARPPendingList.get(i); if (arphost.getSent_count() < switchManager.getHostRetryCount()) { /* * No reply has been received of first ARP Req, send the - * next one + * 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"); + continue; + } hostFinder.find(arphost.getHostIP()); arphost.sent_count++; logger.debug("ARP Sent from ARPPending List, IP: {}", arphost.getHostIP().getHostAddress()); } else if (arphost.getSent_count() >= switchManager.getHostRetryCount()) { /* - * Two ARP requests have been sent without receiving a + * ARP requests have been sent without receiving a * reply, remove this from the pending list */ removePendingARPFromList(i); - logger.debug("ARP reply not received after two attempts, removing from Pending List IP: {}", + logger.debug("ARP reply not received after multiple attempts, removing from Pending List IP: {}", arphost.getHostIP().getHostAddress()); /* * Add this host to a different list which will be processed @@ -931,7 +959,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw failedARPReqList.add(arphost); } else { - logger.error("Inavlid arp_sent count for entery at index: {}", i); + logger.error("Inavlid arp_sent count for entry at index: {}", i); } } } @@ -985,6 +1013,15 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw HexEncode.bytesToHexString(host.getDataLayerAddressBytes()) }); } host.setArpSendCountDown(arp_cntdown); + if (hostFinder == null) { + /* + * 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.warn("ARPHandler is not avaialable, can't send the probe"); + continue; + } hostFinder.probe(host); } } @@ -1018,7 +1055,6 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw if (nc == null) { return new Status(StatusCode.BADREQUEST, "Invalid NodeConnector"); } - HostNodeConnector host = null; try { host = new HostNodeConnector(dataLayerAddress, networkAddr, nc, vlan); @@ -1036,6 +1072,14 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw return new Status(StatusCode.CONFLICT, "Existing IP, Use PUT to update"); } host.setStaticHost(true); + /* + * Check if the nc is an ISL port + */ + if (topologyManager != null) { + if (topologyManager.isInternal(nc)) { + return new Status(StatusCode.BADREQUEST, "Cannot add host on ISL port"); + } + } /* * Before adding host, Check if the switch and the port have already * come up @@ -1259,6 +1303,12 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw for (int i = 0; i < failedARPReqList.size(); i++) { arphost = failedARPReqList.get(i); logger.debug("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostIP().getHostAddress()); + if (hostFinder == null) { + 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); + continue; + } hostFinder.find(arphost.getHostIP()); } HostNodeConnector host = inactiveStaticHosts.get(nodeConnector); @@ -1336,7 +1386,6 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw * */ void destroy() { - destroyCache(); } /** @@ -1353,7 +1402,13 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw * calls * */ - void stop() { + void stop(){ + } + + void stopping() { + arpRefreshTimer.cancel(); + timer.cancel(); + executor.shutdown(); } @Override @@ -1368,4 +1423,21 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw } + @Override + 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) { + } + + @Override + public void entryDeleted(InetAddress key, String cacheName, + boolean originLocal) { + } + }