@Test public void testHARoleChange() throws Exception { LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager(); IOFSwitch sw1 = createMockSwitch(1L); IOFSwitch sw2 = createMockSwitch(2L); replay(sw1, sw2); Link lt = new Link(1L, 2, 2L, 1); NodePortTuple srcNpt = new NodePortTuple(1L, 2); NodePortTuple dstNpt = new NodePortTuple(2L, 1); LinkInfo info = new LinkInfo(System.currentTimeMillis(), System.currentTimeMillis(), null); linkDiscovery.addOrUpdateLink(lt, info); assertNotNull(linkDiscovery.switchLinks.get(lt.getSrc())); assertTrue(linkDiscovery.switchLinks.get(lt.getSrc()).contains(lt)); assertNotNull(linkDiscovery.portLinks.get(srcNpt)); assertTrue(linkDiscovery.portLinks.get(srcNpt).contains(lt)); assertNotNull(linkDiscovery.portLinks.get(dstNpt)); assertTrue(linkDiscovery.portLinks.get(dstNpt).contains(lt)); assertTrue(linkDiscovery.links.containsKey(lt)); }
@LogMessageDocs({ @LogMessageDoc(message="Inter-switch link detected:", explanation="Detected a new link between two openflow switches," + "use show link to find current status"), @LogMessageDoc(message="Inter-switch link updated:", explanation="Detected a link change between two openflow switches, " + "use show link to find current status") }) protected boolean addOrUpdateLink(Link lt, LinkInfo newInfo) { boolean linkChanged = false; lock.writeLock().lock(); try { LinkInfo oldInfo = links.put(lt, newInfo); if (oldInfo != null && oldInfo.getFirstSeenTime() < newInfo.getFirstSeenTime()) newInfo.setFirstSeenTime(oldInfo.getFirstSeenTime()); if (log.isTraceEnabled()) { log.trace("addOrUpdateLink: {} {}", lt, (newInfo.getMulticastValidTime() != null) ? "multicast" : "unicast"); } UpdateOperation updateOperation = null; linkChanged = false; if (oldInfo == null) { addLink(lt, newInfo); updateOperation = UpdateOperation.LINK_UPDATED; linkChanged = true; LinkType linkType = getLinkType(lt, newInfo); if (linkType == ILinkDiscovery.LinkType.DIRECT_LINK) { log.info("Inter-switch link detected: {}", lt); evDirectLink.updateEventNoFlush(new DirectLinkEvent(lt.getSrc(), lt.getSrcPort(), lt.getDst(), lt.getDstPort(), "direct-link-added::rcvd LLDP")); } notifier.postNotification("Link added: " + lt.toString()); } else { linkChanged = updateLink(lt, oldInfo, newInfo); if (linkChanged) { updateOperation = UpdateOperation.LINK_UPDATED; LinkType linkType = getLinkType(lt, newInfo); if (linkType == ILinkDiscovery.LinkType.DIRECT_LINK) { log.info("Inter-switch link updated: {}", lt); evDirectLink.updateEventNoFlush(new DirectLinkEvent(lt.getSrc(), lt.getSrcPort(), lt.getDst(), lt.getDstPort(), "link-port-state-updated::rcvd LLDP")); } notifier.postNotification("Link updated: " + lt.toString()); } } writeLinkToStorage(lt, newInfo); if (linkChanged) { updates.add(new LDUpdate(lt.getSrc(), lt.getSrcPort(), lt.getDst(), lt.getDstPort(), getLinkType(lt, newInfo), updateOperation)); } } finally { lock.writeLock().unlock(); } return linkChanged; }
LinkDiscoveryManager implements IOFMessageListener,
    IOFSwitchListener, IStorageSourceListener, ILinkDiscoveryService,
    IFloodlightModule, IInfoProvider { @LogMessageDocs({ @LogMessageDoc(message="Inter-switch link detected:", explanation="Detected a new link between two openflow switches," + "use show link to find current status"), @LogMessageDoc(message="Inter-switch link updated:", explanation="Detected a link change between two openflow switches, " + "use show link to find current status") }) protected boolean addOrUpdateLink(Link lt, LinkInfo newInfo) { boolean linkChanged = false; lock.writeLock().lock(); try { LinkInfo oldInfo = links.put(lt, newInfo); if (oldInfo != null && oldInfo.getFirstSeenTime() < newInfo.getFirstSeenTime()) newInfo.setFirstSeenTime(oldInfo.getFirstSeenTime()); if (log.isTraceEnabled()) { log.trace("addOrUpdateLink: {} {}", lt, (newInfo.getMulticastValidTime() != null) ? "multicast" : "unicast"); } UpdateOperation updateOperation = null; linkChanged = false; if (oldInfo == null) { addLink(lt, newInfo); updateOperation = UpdateOperation.LINK_UPDATED; linkChanged = true; LinkType linkType = getLinkType(lt, newInfo); if (linkType == ILinkDiscovery.LinkType.DIRECT_LINK) { log.info("Inter-switch link detected: {}", lt); evDirectLink.updateEventNoFlush(new DirectLinkEvent(lt.getSrc(), lt.getSrcPort(), lt.getDst(), lt.getDstPort(), "direct-link-added::rcvd LLDP")); } notifier.postNotification("Link added: " + lt.toString()); } else { linkChanged = updateLink(lt, oldInfo, newInfo); if (linkChanged) { updateOperation = UpdateOperation.LINK_UPDATED; LinkType linkType = getLinkType(lt, newInfo); if (linkType == ILinkDiscovery.LinkType.DIRECT_LINK) { log.info("Inter-switch link updated: {}", lt); evDirectLink.updateEventNoFlush(new DirectLinkEvent(lt.getSrc(), lt.getSrcPort(), lt.getDst(), lt.getDstPort(), "link-port-state-updated::rcvd LLDP")); } notifier.postNotification("Link updated: " + lt.toString()); } } writeLinkToStorage(lt, newInfo); if (linkChanged) { updates.add(new LDUpdate(lt.getSrc(), lt.getSrcPort(), lt.getDst(), lt.getDstPort(), getLinkType(lt, newInfo), updateOperation)); } } finally { lock.writeLock().unlock(); } return linkChanged; } }
LinkDiscoveryManager implements IOFMessageListener,
    IOFSwitchListener, IStorageSourceListener, ILinkDiscoveryService,
    IFloodlightModule, IInfoProvider { @LogMessageDocs({ @LogMessageDoc(message="Inter-switch link detected:", explanation="Detected a new link between two openflow switches," + "use show link to find current status"), @LogMessageDoc(message="Inter-switch link updated:", explanation="Detected a link change between two openflow switches, " + "use show link to find current status") }) protected boolean addOrUpdateLink(Link lt, LinkInfo newInfo) { boolean linkChanged = false; lock.writeLock().lock(); try { LinkInfo oldInfo = links.put(lt, newInfo); if (oldInfo != null && oldInfo.getFirstSeenTime() < newInfo.getFirstSeenTime()) newInfo.setFirstSeenTime(oldInfo.getFirstSeenTime()); if (log.isTraceEnabled()) { log.trace("addOrUpdateLink: {} {}", lt, (newInfo.getMulticastValidTime() != null) ? "multicast" : "unicast"); } UpdateOperation updateOperation = null; linkChanged = false; if (oldInfo == null) { addLink(lt, newInfo); updateOperation = UpdateOperation.LINK_UPDATED; linkChanged = true; LinkType linkType = getLinkType(lt, newInfo); if (linkType == ILinkDiscovery.LinkType.DIRECT_LINK) { log.info("Inter-switch link detected: {}", lt); evDirectLink.updateEventNoFlush(new DirectLinkEvent(lt.getSrc(), lt.getSrcPort(), lt.getDst(), lt.getDstPort(), "direct-link-added::rcvd LLDP")); } notifier.postNotification("Link added: " + lt.toString()); } else { linkChanged = updateLink(lt, oldInfo, newInfo); if (linkChanged) { updateOperation = UpdateOperation.LINK_UPDATED; LinkType linkType = getLinkType(lt, newInfo); if (linkType == ILinkDiscovery.LinkType.DIRECT_LINK) { log.info("Inter-switch link updated: {}", lt); evDirectLink.updateEventNoFlush(new DirectLinkEvent(lt.getSrc(), lt.getSrcPort(), lt.getDst(), lt.getDstPort(), "link-port-state-updated::rcvd LLDP")); } notifier.postNotification("Link updated: " + lt.toString()); } } writeLinkToStorage(lt, newInfo); if (linkChanged) { updates.add(new LDUpdate(lt.getSrc(), lt.getSrcPort(), lt.getDst(), lt.getDstPort(), getLinkType(lt, newInfo), updateOperation)); } } finally { lock.writeLock().unlock(); } return linkChanged; }  }
LinkDiscoveryManager implements IOFMessageListener,
    IOFSwitchListener, IStorageSourceListener, ILinkDiscoveryService,
    IFloodlightModule, IInfoProvider { @LogMessageDocs({ @LogMessageDoc(message="Inter-switch link detected:", explanation="Detected a new link between two openflow switches," + "use show link to find current status"), @LogMessageDoc(message="Inter-switch link updated:", explanation="Detected a link change between two openflow switches, " + "use show link to find current status") }) protected boolean addOrUpdateLink(Link lt, LinkInfo newInfo) { boolean linkChanged = false; lock.writeLock().lock(); try { LinkInfo oldInfo = links.put(lt, newInfo); if (oldInfo != null && oldInfo.getFirstSeenTime() < newInfo.getFirstSeenTime()) newInfo.setFirstSeenTime(oldInfo.getFirstSeenTime()); if (log.isTraceEnabled()) { log.trace("addOrUpdateLink: {} {}", lt, (newInfo.getMulticastValidTime() != null) ? "multicast" : "unicast"); } UpdateOperation updateOperation = null; linkChanged = false; if (oldInfo == null) { addLink(lt, newInfo); updateOperation = UpdateOperation.LINK_UPDATED; linkChanged = true; LinkType linkType = getLinkType(lt, newInfo); if (linkType == ILinkDiscovery.LinkType.DIRECT_LINK) { log.info("Inter-switch link detected: {}", lt); evDirectLink.updateEventNoFlush(new DirectLinkEvent(lt.getSrc(), lt.getSrcPort(), lt.getDst(), lt.getDstPort(), "direct-link-added::rcvd LLDP")); } notifier.postNotification("Link added: " + lt.toString()); } else { linkChanged = updateLink(lt, oldInfo, newInfo); if (linkChanged) { updateOperation = UpdateOperation.LINK_UPDATED; LinkType linkType = getLinkType(lt, newInfo); if (linkType == ILinkDiscovery.LinkType.DIRECT_LINK) { log.info("Inter-switch link updated: {}", lt); evDirectLink.updateEventNoFlush(new DirectLinkEvent(lt.getSrc(), lt.getSrcPort(), lt.getDst(), lt.getDstPort(), "link-port-state-updated::rcvd LLDP")); } notifier.postNotification("Link updated: " + lt.toString()); } } writeLinkToStorage(lt, newInfo); if (linkChanged) { updates.add(new LDUpdate(lt.getSrc(), lt.getSrcPort(), lt.getDst(), lt.getDstPort(), getLinkType(lt, newInfo), updateOperation)); } } finally { lock.writeLock().unlock(); } return linkChanged; }  @Override OFPacketOut generateLLDPMessage(long sw, short port,
                                       boolean isStandard, boolean isReverse); int getLldpFrequency(); int getLldpTimeout(); @Override Map<NodePortTuple, Set<Link>> getPortLinks(); @Override Set<NodePortTuple> getSuppressLLDPsInfo(); @Override void AddToSuppressLLDPs(long sw, short port); @Override void RemoveFromSuppressLLDPs(long sw, short port); boolean isShuttingDown(); @Override boolean isTunnelPort(long sw, short port); @Override ILinkDiscovery.LinkType getLinkType(Link lt, LinkInfo info); @Override Set<Short> getQuarantinedPorts(long sw); @Override Map<Long, Set<Link>> getSwitchLinks(); @Override void addMACToIgnoreList(long mac, int ignoreBits); @Override boolean isAutoPortFastFeature(); @Override void setAutoPortFastFeature(boolean autoPortFastFeature); @Override void addListener(ILinkDiscoveryListener listener); @Override Map<Link, LinkInfo> getLinks(); @Override LinkInfo getLinkInfo(Link link); @Override String getName(); @Override Command receive(IOFSwitch sw, OFMessage msg,
                           FloodlightContext cntx); @Override boolean isCallbackOrderingPrereq(OFType type, String name); @Override boolean isCallbackOrderingPostreq(OFType type, String name); @Override void switchPortChanged(long switchId,
            ImmutablePort port,
            IOFSwitch.PortChangeType type); @Override void switchAdded(long switchId); @Override void switchRemoved(long sw); @Override void switchActivated(long switchId); @Override void switchChanged(long switchId); void setStorageSource(IStorageSourceService storageSource); IStorageSourceService getStorageSource(); @Override void rowsModified(String tableName, Set<Object> rowKeys); @Override void rowsDeleted(String tableName, Set<Object> rowKeys); Long readLinkValidTime(Link lt); @Override Collection<Class<? extends IFloodlightService>> getModuleServices(); @Override Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls(); @Override Collection<Class<? extends IFloodlightService>> getModuleDependencies(); @Override void init(FloodlightModuleContext context); @Override @LogMessageDocs({ @LogMessageDoc(level = "ERROR", message = "No storage source found.", explanation = "Storage source was not initialized; cannot initialize " + "link discovery.", recommendation = LogMessageDoc.REPORT_CONTROLLER_BUG), @LogMessageDoc(level = "ERROR", message = "Error in installing listener for " + "switch config table {table}", explanation = "Failed to install storage notification for the " + "switch config table", recommendation = LogMessageDoc.REPORT_CONTROLLER_BUG), @LogMessageDoc(level = "ERROR", message = "No storage source found.", explanation = "Storage source was not initialized; cannot initialize " + "link discovery.", recommendation = LogMessageDoc.REPORT_CONTROLLER_BUG), @LogMessageDoc(level = "ERROR", message = "Exception in LLDP send timer.", explanation = "An unknown error occured while sending LLDP " + "messages to switches.", recommendation = LogMessageDoc.CHECK_SWITCH) }) void startUp(FloodlightModuleContext context); @Override Map<String, Object> getInfo(String type); }
LinkDiscoveryManager implements IOFMessageListener,
    IOFSwitchListener, IStorageSourceListener, ILinkDiscoveryService,
    IFloodlightModule, IInfoProvider { @LogMessageDocs({ @LogMessageDoc(message="Inter-switch link detected:", explanation="Detected a new link between two openflow switches," + "use show link to find current status"), @LogMessageDoc(message="Inter-switch link updated:", explanation="Detected a link change between two openflow switches, " + "use show link to find current status") }) protected boolean addOrUpdateLink(Link lt, LinkInfo newInfo) { boolean linkChanged = false; lock.writeLock().lock(); try { LinkInfo oldInfo = links.put(lt, newInfo); if (oldInfo != null && oldInfo.getFirstSeenTime() < newInfo.getFirstSeenTime()) newInfo.setFirstSeenTime(oldInfo.getFirstSeenTime()); if (log.isTraceEnabled()) { log.trace("addOrUpdateLink: {} {}", lt, (newInfo.getMulticastValidTime() != null) ? "multicast" : "unicast"); } UpdateOperation updateOperation = null; linkChanged = false; if (oldInfo == null) { addLink(lt, newInfo); updateOperation = UpdateOperation.LINK_UPDATED; linkChanged = true; LinkType linkType = getLinkType(lt, newInfo); if (linkType == ILinkDiscovery.LinkType.DIRECT_LINK) { log.info("Inter-switch link detected: {}", lt); evDirectLink.updateEventNoFlush(new DirectLinkEvent(lt.getSrc(), lt.getSrcPort(), lt.getDst(), lt.getDstPort(), "direct-link-added::rcvd LLDP")); } notifier.postNotification("Link added: " + lt.toString()); } else { linkChanged = updateLink(lt, oldInfo, newInfo); if (linkChanged) { updateOperation = UpdateOperation.LINK_UPDATED; LinkType linkType = getLinkType(lt, newInfo); if (linkType == ILinkDiscovery.LinkType.DIRECT_LINK) { log.info("Inter-switch link updated: {}", lt); evDirectLink.updateEventNoFlush(new DirectLinkEvent(lt.getSrc(), lt.getSrcPort(), lt.getDst(), lt.getDstPort(), "link-port-state-updated::rcvd LLDP")); } notifier.postNotification("Link updated: " + lt.toString()); } } writeLinkToStorage(lt, newInfo); if (linkChanged) { updates.add(new LDUpdate(lt.getSrc(), lt.getSrcPort(), lt.getDst(), lt.getDstPort(), getLinkType(lt, newInfo), updateOperation)); } } finally { lock.writeLock().unlock(); } return linkChanged; }  @Override OFPacketOut generateLLDPMessage(long sw, short port,
                                       boolean isStandard, boolean isReverse); int getLldpFrequency(); int getLldpTimeout(); @Override Map<NodePortTuple, Set<Link>> getPortLinks(); @Override Set<NodePortTuple> getSuppressLLDPsInfo(); @Override void AddToSuppressLLDPs(long sw, short port); @Override void RemoveFromSuppressLLDPs(long sw, short port); boolean isShuttingDown(); @Override boolean isTunnelPort(long sw, short port); @Override ILinkDiscovery.LinkType getLinkType(Link lt, LinkInfo info); @Override Set<Short> getQuarantinedPorts(long sw); @Override Map<Long, Set<Link>> getSwitchLinks(); @Override void addMACToIgnoreList(long mac, int ignoreBits); @Override boolean isAutoPortFastFeature(); @Override void setAutoPortFastFeature(boolean autoPortFastFeature); @Override void addListener(ILinkDiscoveryListener listener); @Override Map<Link, LinkInfo> getLinks(); @Override LinkInfo getLinkInfo(Link link); @Override String getName(); @Override Command receive(IOFSwitch sw, OFMessage msg,
                           FloodlightContext cntx); @Override boolean isCallbackOrderingPrereq(OFType type, String name); @Override boolean isCallbackOrderingPostreq(OFType type, String name); @Override void switchPortChanged(long switchId,
            ImmutablePort port,
            IOFSwitch.PortChangeType type); @Override void switchAdded(long switchId); @Override void switchRemoved(long sw); @Override void switchActivated(long switchId); @Override void switchChanged(long switchId); void setStorageSource(IStorageSourceService storageSource); IStorageSourceService getStorageSource(); @Override void rowsModified(String tableName, Set<Object> rowKeys); @Override void rowsDeleted(String tableName, Set<Object> rowKeys); Long readLinkValidTime(Link lt); @Override Collection<Class<? extends IFloodlightService>> getModuleServices(); @Override Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls(); @Override Collection<Class<? extends IFloodlightService>> getModuleDependencies(); @Override void init(FloodlightModuleContext context); @Override @LogMessageDocs({ @LogMessageDoc(level = "ERROR", message = "No storage source found.", explanation = "Storage source was not initialized; cannot initialize " + "link discovery.", recommendation = LogMessageDoc.REPORT_CONTROLLER_BUG), @LogMessageDoc(level = "ERROR", message = "Error in installing listener for " + "switch config table {table}", explanation = "Failed to install storage notification for the " + "switch config table", recommendation = LogMessageDoc.REPORT_CONTROLLER_BUG), @LogMessageDoc(level = "ERROR", message = "No storage source found.", explanation = "Storage source was not initialized; cannot initialize " + "link discovery.", recommendation = LogMessageDoc.REPORT_CONTROLLER_BUG), @LogMessageDoc(level = "ERROR", message = "Exception in LLDP send timer.", explanation = "An unknown error occured while sending LLDP " + "messages to switches.", recommendation = LogMessageDoc.CHECK_SWITCH) }) void startUp(FloodlightModuleContext context); @Override Map<String, Object> getInfo(String type); static final String MODULE_NAME; }