X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fprotocol_plugins%2Fopenflow%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fprotocol_plugin%2Fopenflow%2Finternal%2FTopologyServiceShim.java;h=4e4e867fec637a30c3a0a26eedb128becbda84c7;hp=b62b068b8164cbb9f2857ade33a291d8dad7cc25;hb=0ae12c54560ef14cb8c08beef4553f7523d41578;hpb=29f7cfb54b580928c7feac63abce028a7014b0d5 diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/TopologyServiceShim.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/TopologyServiceShim.java index b62b068b81..4e4e867fec 100644 --- a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/TopologyServiceShim.java +++ b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/TopologyServiceShim.java @@ -1,4 +1,3 @@ - /* * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. * @@ -10,7 +9,9 @@ package org.opendaylight.controller.protocol_plugin.openflow.internal; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -26,37 +27,42 @@ import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import org.eclipse.osgi.framework.console.CommandInterpreter; import org.eclipse.osgi.framework.console.CommandProvider; +import org.opendaylight.controller.protocol_plugin.openflow.IDiscoveryListener; +import org.opendaylight.controller.protocol_plugin.openflow.IInventoryShimExternalListener; import org.opendaylight.controller.protocol_plugin.openflow.IOFStatisticsManager; import org.opendaylight.controller.protocol_plugin.openflow.IRefreshInternalProvider; import org.opendaylight.controller.protocol_plugin.openflow.ITopologyServiceShimListener; -import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import org.opendaylight.controller.sal.core.Bandwidth; +import org.opendaylight.controller.sal.core.Config; import org.opendaylight.controller.sal.core.ContainerFlow; import org.opendaylight.controller.sal.core.Edge; +import org.opendaylight.controller.sal.core.IContainerAware; import org.opendaylight.controller.sal.core.IContainerListener; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.NodeConnector; import org.opendaylight.controller.sal.core.Property; +import org.opendaylight.controller.sal.core.State; import org.opendaylight.controller.sal.core.UpdateType; -import org.opendaylight.controller.sal.discovery.IDiscoveryService; +import org.opendaylight.controller.sal.topology.TopoEdgeUpdate; import org.opendaylight.controller.sal.utils.GlobalConstants; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * The class describes a shim layer that relays the topology events from OpenFlow - * core to various listeners. The notifications are filtered based on container - * configurations. + * The class describes a shim layer that relays the topology events from + * OpenFlow core to various listeners. The notifications are filtered based on + * container configurations. */ -public class TopologyServiceShim implements IDiscoveryService, - IContainerListener, CommandProvider, IRefreshInternalProvider { +public class TopologyServiceShim implements IDiscoveryListener, + IContainerListener, CommandProvider, IRefreshInternalProvider, + IInventoryShimExternalListener, IContainerAware { protected static final Logger logger = LoggerFactory .getLogger(TopologyServiceShim.class); private ConcurrentMap topologyServiceShimListeners = new ConcurrentHashMap(); private ConcurrentMap> containerMap = new ConcurrentHashMap>(); - private ConcurrentMap>>> edgeMap = new ConcurrentHashMap>>>(); + private ConcurrentMap>>> edgeMap = new ConcurrentHashMap>>>(); private BlockingQueue notifyQ; private Thread notifyThread; @@ -69,46 +75,79 @@ public class TopologyServiceShim implements IDiscoveryService, private Thread bwUtilNotifyThread; private BlockingQueue bwUtilNotifyQ; private List connectorsOverUtilized; - private float bwThresholdFactor = (float) 0.8; // Threshold = 80% of link bandwidth + private float bwThresholdFactor = (float) 0.8; // Threshold = 80% of link + // bandwidth class NotifyEntry { String container; - Pair> edgeProps; - UpdateType type; + List teuList; - NotifyEntry(String container, Pair> edgeProps, - UpdateType type) { + public NotifyEntry(String container, TopoEdgeUpdate teu) { this.container = container; - this.edgeProps = edgeProps; - this.type = type; + this.teuList = new ArrayList(); + if (teu != null) { + this.teuList.add(teu); + } + } + + public NotifyEntry(String container, List teuList) { + this.container = container; + this.teuList = new ArrayList(); + if (teuList != null) { + this.teuList.addAll(teuList); + } } } class TopologyNotify implements Runnable { private final BlockingQueue notifyQ; + private NotifyEntry entry; + private Map> teuMap = new HashMap>(); + private List teuList; + private boolean notifyListeners; TopologyNotify(BlockingQueue notifyQ) { this.notifyQ = notifyQ; } + @Override public void run() { while (true) { try { - NotifyEntry entry = notifyQ.take(); + teuMap.clear(); + notifyListeners = false; + while (!notifyQ.isEmpty()) { + entry = notifyQ.take(); + teuList = teuMap.get(entry.container); + if (teuList == null) { + teuList = new ArrayList(); + } + // group all the updates together + teuList.addAll(entry.teuList); + teuMap.put(entry.container, teuList); + notifyListeners = true; + } - ITopologyServiceShimListener topologServiceShimListener = topologyServiceShimListeners - .get(entry.container); - topologServiceShimListener.edgeUpdate(entry.edgeProps - .getLeft(), entry.type, entry.edgeProps.getRight()); + if (notifyListeners) { + for (String container : teuMap.keySet()) { + // notify the listener + ITopologyServiceShimListener l = topologyServiceShimListeners.get(container); + // container topology service may not have come up yet + if (l != null) { + l.edgeUpdate(teuMap.get(container)); + } + } + } - entry = null; + Thread.sleep(100); } catch (InterruptedException e1) { - logger.warn("TopologyNotify interrupted", e1.getMessage()); + logger.warn("TopologyNotify interrupted {}", + e1.getMessage()); if (shuttingDown) { return; } } catch (Exception e2) { - e2.printStackTrace(); + logger.error("", e2); } } } @@ -131,12 +170,13 @@ public class TopologyServiceShim implements IDiscoveryService, this.notifyQ = notifyQ; } + @Override public void run() { while (true) { try { UtilizationUpdate update = notifyQ.take(); NodeConnector connector = update.connector; - Set containerList = edgeMap.keySet();//.get(connector); + Set containerList = edgeMap.keySet(); for (String container : containerList) { Map>> edgePropsMap = edgeMap .get(container); @@ -154,15 +194,14 @@ public class TopologyServiceShim implements IDiscoveryService, } } } catch (InterruptedException e1) { - logger - .warn( - "Edge Bandwidth Utilization Notify Thread interrupted", - e1.getMessage()); + logger.warn( + "Edge Bandwidth Utilization Notify Thread interrupted {}", + e1.getMessage()); if (shuttingDown) { return; } } catch (Exception e2) { - e2.printStackTrace(); + logger.error("", e2); } } } @@ -212,10 +251,10 @@ public class TopologyServiceShim implements IDiscoveryService, } /** - * Continuously polls the transmit bit rate for all the node connectors - * from statistics manager and trigger the warning notification upward - * when the transmit rate is above a threshold which is a percentage of - * the edge bandwidth + * Continuously polls the transmit bit rate for all the node connectors from + * statistics manager and trigger the warning notification upward when the + * transmit rate is above a threshold which is a percentage of the edge + * bandwidth */ protected void pollTxBitRates() { Map>> globalContainerEdges = edgeMap @@ -226,7 +265,8 @@ public class TopologyServiceShim implements IDiscoveryService, for (NodeConnector connector : globalContainerEdges.keySet()) { // Skip if node connector belongs to production switch - if (connector.getType() == NodeConnector.NodeConnectorIDType.PRODUCTION) { + if (connector.getType().equals( + NodeConnector.NodeConnectorIDType.PRODUCTION)) { continue; } @@ -258,18 +298,18 @@ public class TopologyServiceShim implements IDiscoveryService, // Compare bandwidth usage Long switchId = (Long) connector.getNode().getID(); Short port = (Short) connector.getID(); - float rate = statsMgr.getTransmitRate(switchId, port); - if (rate > bwThresholdFactor * bw) { - if (!connectorsOverUtilized.contains(connector)) { - connectorsOverUtilized.add(connector); - this.bwUtilNotifyQ.add(new UtilizationUpdate(connector, - UpdateType.ADDED)); - } - } else { - if (connectorsOverUtilized.contains(connector)) { - connectorsOverUtilized.remove(connector); - this.bwUtilNotifyQ.add(new UtilizationUpdate(connector, - UpdateType.REMOVED)); + if (statsMgr != null) { + float rate = statsMgr.getTransmitRate(switchId, port); + if (rate > bwThresholdFactor * bw) { + if (!connectorsOverUtilized.contains(connector)) { + connectorsOverUtilized.add(connector); + this.bwUtilNotifyQ.add(new UtilizationUpdate(connector, UpdateType.ADDED)); + } + } else { + if (connectorsOverUtilized.contains(connector)) { + connectorsOverUtilized.remove(connector); + this.bwUtilNotifyQ.add(new UtilizationUpdate(connector, UpdateType.REMOVED)); + } } } } @@ -277,9 +317,9 @@ public class TopologyServiceShim implements IDiscoveryService, } /** - * Function called by the dependency manager when at least one - * dependency become unsatisfied or when the component is shutting - * down because for example bundle is being stopped. + * Function called by the dependency manager when at least one dependency + * become unsatisfied or when the component is shutting down because for + * example bundle is being stopped. * */ void destroy() { @@ -289,9 +329,8 @@ public class TopologyServiceShim implements IDiscoveryService, } /** - * Function called by dependency manager after "init ()" is called - * and after the services provided by the class are registered in - * the service registry + * Function called by dependency manager after "init ()" is called and after + * the services provided by the class are registered in the service registry * */ void start() { @@ -303,9 +342,9 @@ public class TopologyServiceShim implements IDiscoveryService, } /** - * Function called by the dependency manager before the services - * exported by the component are unregistered, this will be - * followed by a "destroy ()" calls + * Function called by the dependency manager before the services exported by + * the component are unregistered, this will be followed by a "destroy ()" + * calls * */ void stop() { @@ -326,10 +365,11 @@ public class TopologyServiceShim implements IDiscoveryService, return; } if ((this.topologyServiceShimListeners != null) - && !this.topologyServiceShimListeners.containsKey(s)) { + && !this.topologyServiceShimListeners + .containsKey(containerName)) { this.topologyServiceShimListeners.put(containerName, s); - logger.trace("Added topologyServiceShimListener for container:" - + containerName); + logger.trace("Added topologyServiceShimListener for container: {}", + containerName); } } @@ -345,10 +385,13 @@ public class TopologyServiceShim implements IDiscoveryService, return; } if ((this.topologyServiceShimListeners != null) - && this.topologyServiceShimListeners.containsKey(s)) { + && this.topologyServiceShimListeners.containsKey(containerName) + && this.topologyServiceShimListeners.get(containerName).equals( + s)) { this.topologyServiceShimListeners.remove(containerName); - logger.trace("Removed topologyServiceShimListener for container: " - + containerName); + logger.trace( + "Removed topologyServiceShimListener for container: {}", + containerName); } } @@ -362,8 +405,95 @@ public class TopologyServiceShim implements IDiscoveryService, } } + private void updateContainerMap(List containers, NodeConnector p) { + if (containers.isEmpty()) { + // Do cleanup to reduce memory footprint if no + // elements to be tracked + this.containerMap.remove(p); + } else { + this.containerMap.put(p, containers); + } + } + + /** + * From a given edge map, retrieve the edge sourced by the port and update + * the local cache in the container + * + * @param container + * the container name + * @param nodeConnector + * the node connector + * @param edges + * the given edge map + * @return the found edge + */ + private Edge addEdge(String container, NodeConnector nodeConnector, + Map>> edges) { + logger.debug("Search edge sourced by port {} in container {}", nodeConnector, container); + + // Retrieve the associated edge + Pair> edgeProps = edges.get(nodeConnector); + if (edgeProps == null) { + logger.debug("edgePros is null for port {} in container {}", nodeConnector, container); + return null; + } + + Edge edge = edgeProps.getLeft(); + if (edge == null) { + logger.debug("edge is null for port {} in container {}", nodeConnector, container); + return null; + } + + // Make sure the peer port is in the same container + NodeConnector peerConnector = edge.getHeadNodeConnector(); + List containers = this.containerMap.get(peerConnector); + if ((containers == null) || !containers.contains(container)) { + logger.debug("peer port {} of edge {} is not part of the container {}", new Object[] { peerConnector, edge, + container }); + return null; + } + + // Update the local cache + updateLocalEdgeMap(container, edge, UpdateType.ADDED, edgeProps.getRight()); + logger.debug("Added edge {} to local cache in container {}", edge, container); + + return edge; + } + + private void addNodeConnector(String container, + NodeConnector nodeConnector) { + // Use the global edge map for the newly added port in a container + Map>> globalEdgeMap = edgeMap.get(GlobalConstants.DEFAULT + .toString()); + if (globalEdgeMap == null) { + return; + } + + // Get the edge and update local cache in the container + Edge edge1, edge2; + edge1 = addEdge(container, nodeConnector, globalEdgeMap); + if (edge1 == null) { + return; + } + + // Get the edge in reverse direction and update local cache in the container + NodeConnector peerConnector = edge1.getHeadNodeConnector(); + edge2 = addEdge(container, peerConnector, globalEdgeMap); + + // Send notification upwards in one shot + List teuList = new ArrayList(); + teuList.add(new TopoEdgeUpdate(edge1, null, UpdateType.ADDED)); + logger.debug("Notify edge1: {} in container {}", edge1, container); + if (edge2 != null) { + teuList.add(new TopoEdgeUpdate(edge2, null, UpdateType.ADDED)); + logger.debug("Notify edge2: {} in container {}", edge2, container); + } + notifyEdge(container, teuList); + } + private void removeNodeConnector(String container, NodeConnector nodeConnector) { + List teuList = new ArrayList(); Map>> edgePropsMap = edgeMap .get(container); if (edgePropsMap == null) { @@ -375,7 +505,8 @@ public class TopologyServiceShim implements IDiscoveryService, if (edgeProps == null) { return; } - notifyEdge(container, edgeProps.getLeft(), UpdateType.REMOVED, null); + teuList.add(new TopoEdgeUpdate(edgeProps.getLeft(), null, + UpdateType.REMOVED)); // Remove edge in another direction edgeProps = edgePropsMap @@ -383,51 +514,130 @@ public class TopologyServiceShim implements IDiscoveryService, if (edgeProps == null) { return; } - notifyEdge(container, edgeProps.getLeft(), UpdateType.REMOVED, null); + teuList.add(new TopoEdgeUpdate(edgeProps.getLeft(), null, + UpdateType.REMOVED)); + + // Update in one shot + notifyEdge(container, teuList); } - private void notifyEdge(String container, Edge edge, UpdateType type, - Set props) { - Map>> edgePropsMap = edgeMap + /** + * Update local cache and return true if it needs to notify upper layer + * Topology listeners. + * + * @param container + * The network container + * @param edge + * The edge + * @param type + * The update type + * @param props + * The edge properties + * @return true if it needs to notify upper layer Topology listeners + */ + private boolean updateLocalEdgeMap(String container, Edge edge, + UpdateType type, Set props) { + ConcurrentMap>> edgePropsMap = edgeMap .get(container); NodeConnector src = edge.getTailNodeConnector(); Pair> edgeProps = new ImmutablePair>( edge, props); + boolean rv = false; switch (type) { case ADDED: case CHANGED: if (edgePropsMap == null) { - edgePropsMap = new HashMap>>(); + edgePropsMap = new ConcurrentHashMap>>(); + rv = true; } else { if (edgePropsMap.containsKey(src) && edgePropsMap.get(src).equals(edgeProps)) { - // Entry already exists. Return here. - return; + // Entry already exists. No update. + rv = false; + } else { + rv = true; } } - edgePropsMap.put(src, edgeProps); - edgeMap.put(container, edgePropsMap); + if (rv) { + edgePropsMap.put(src, edgeProps); + edgeMap.put(container, edgePropsMap); + } break; case REMOVED: - if (edgePropsMap != null) { + if ((edgePropsMap != null) && edgePropsMap.containsKey(src)) { edgePropsMap.remove(src); if (edgePropsMap.isEmpty()) { edgeMap.remove(container); } else { edgeMap.put(container, edgePropsMap); } + rv = true; } break; default: - logger.debug("Invalid " + type + " Edge " + edge - + " in container {}", container); + logger.debug( + "notifyLocalEdgeMap: invalid {} for Edge {} in container {}", + new Object[] { type.getName(), edge, container }); + } + + if (rv) { + logger.debug( + "notifyLocalEdgeMap: {} for Edge {} in container {}", + new Object[] { type.getName(), edge, container }); + } + + return rv; + } + + private void notifyEdge(String container, Edge edge, UpdateType type, + Set props) { + boolean notifyListeners; + + // Update local cache + notifyListeners = updateLocalEdgeMap(container, edge, type, props); + + // Prepare to update TopologyService + if (notifyListeners) { + notifyQ.add(new NotifyEntry(container, new TopoEdgeUpdate(edge, props, + type))); + logger.debug("notifyEdge: {} Edge {} in container {}", + new Object[] { type.getName(), edge, container }); + } + } + + private void notifyEdge(String container, List etuList) { + if (etuList == null) { return; } - notifyQ.add(new NotifyEntry(container, edgeProps, type)); + Edge edge; + UpdateType type; + List etuNotifyList = new ArrayList(); + boolean notifyListeners = false, rv; + + for (TopoEdgeUpdate etu : etuList) { + edge = etu.getEdge(); + type = etu.getUpdateType(); + + // Update local cache + rv = updateLocalEdgeMap(container, edge, type, etu.getProperty()); + if (rv) { + if (!notifyListeners) { + notifyListeners = true; + } + etuNotifyList.add(etu); + logger.debug( + "notifyEdge(TopoEdgeUpdate): {} Edge {} in container {}", + new Object[] { type.getName(), edge, container }); + } + } - logger.trace(type + " Edge " + edge + " in container {}", container); + // Prepare to update TopologyService + if (notifyListeners) { + notifyQ.add(new NotifyEntry(container, etuNotifyList)); + logger.debug("notifyEdge(TopoEdgeUpdate): add notifyQ"); + } } @Override @@ -455,8 +665,7 @@ public class TopologyServiceShim implements IDiscoveryService, NodeConnector src = edge.getTailNodeConnector(), dst = edge .getHeadNodeConnector(); - if (!src.getType().equals( - NodeConnector.NodeConnectorIDType.PRODUCTION)) { + if (!src.getType().equals(NodeConnector.NodeConnectorIDType.PRODUCTION)) { /* Find the common containers for both ends */ List srcContainers = this.containerMap.get(src), dstContainers = this.containerMap .get(dst), cmnContainers = null; @@ -495,33 +704,24 @@ public class TopologyServiceShim implements IDiscoveryService, if (containers == null) { containers = new CopyOnWriteArrayList(); } - boolean updateMap = false; switch (t) { case ADDED: if (!containers.contains(containerName)) { containers.add(containerName); - updateMap = true; + updateContainerMap(containers, p); + addNodeConnector(containerName, p); } break; case REMOVED: if (containers.contains(containerName)) { containers.remove(containerName); - updateMap = true; + updateContainerMap(containers, p); removeNodeConnector(containerName, p); } break; case CHANGED: break; } - if (updateMap) { - if (containers.isEmpty()) { - // Do cleanup to reduce memory footprint if no - // elements to be tracked - this.containerMap.remove(p); - } else { - this.containerMap.put(p, containers); - } - } } @Override @@ -540,8 +740,8 @@ public class TopologyServiceShim implements IDiscoveryService, public String getHelp() { StringBuffer help = new StringBuffer(); help.append("---Topology Service Shim---\n"); - help - .append("\t pem [container] - Print edgeMap entries for a given container\n"); + help.append("\t pem [container] - Print edgeMap entries"); + help.append(" for a given container\n"); return help.toString(); } @@ -552,28 +752,32 @@ public class TopologyServiceShim implements IDiscoveryService, } ci.println("Container: " + container); - ci - .println(" Edge Bandwidth"); + ci.println(" Edge Bandwidth"); Map>> edgePropsMap = edgeMap .get(container); if (edgePropsMap == null) { return; } + int count = 0; for (Pair> edgeProps : edgePropsMap.values()) { if (edgeProps == null) { continue; } long bw = 0; - for (Property prop : edgeProps.getRight()) { - if (prop.getName().equals(Bandwidth.BandwidthPropName)) { - bw = ((Bandwidth) prop).getValue(); + Set props = edgeProps.getRight(); + if (props != null) { + for (Property prop : props) { + if (prop.getName().equals(Bandwidth.BandwidthPropName)) { + bw = ((Bandwidth) prop).getValue(); + } } } - + count++; ci.println(edgeProps.getLeft() + " " + bw); } + ci.println("Total number of Edges: " + count); } public void _bwfactor(CommandInterpreter ci) { @@ -588,15 +792,14 @@ public class TopologyServiceShim implements IDiscoveryService, } /** - * This method will trigger topology updates to be sent - * toward SAL. SAL then pushes the updates to ALL the applications - * that have registered as listeners for this service. SAL has no - * way of knowing which application requested for the refresh. + * This method will trigger topology updates to be sent toward SAL. SAL then + * pushes the updates to ALL the applications that have registered as + * listeners for this service. SAL has no way of knowing which application + * requested for the refresh. * - * As an example of this case, is stopping and starting the - * Topology Manager. When the topology Manager is stopped, - * and restarted, it will no longer have the latest topology. - * Hence, a request is sent here. + * As an example of this case, is stopping and starting the Topology + * Manager. When the topology Manager is stopped, and restarted, it will no + * longer have the latest topology. Hence, a request is sent here. * * @param containerName * @return void @@ -609,17 +812,35 @@ public class TopologyServiceShim implements IDiscoveryService, } /** - * Reading the current topology database, the method will replay - * all the edge updates for the ITopologyServiceShimListener instance - * in the given container, which will in turn publish them toward SAL. + * Retrieve the edges for a given container + * * @param containerName + * the container name + * @return the edges and their properties */ - private void TopologyBulkUpdate(String containerName) { + private Collection>> getEdgeProps(String containerName) { Map>> edgePropMap = null; - - logger.debug("Try bulk update for container:{}", containerName); edgePropMap = edgeMap.get(containerName); if (edgePropMap == null) { + return null; + } + return edgePropMap.values(); + } + + /** + * Reading the current topology database, the method will replay all the + * edge updates for the ITopologyServiceShimListener instance in the given + * container, which will in turn publish them toward SAL. + * + * @param containerName + * the container name + */ + private void TopologyBulkUpdate(String containerName) { + Collection>> edgeProps = null; + + logger.debug("Try bulk update for container:{}", containerName); + edgeProps = getEdgeProps(containerName); + if (edgeProps == null) { logger.debug("No edges known for container:{}", containerName); return; } @@ -631,15 +852,96 @@ public class TopologyServiceShim implements IDiscoveryService, return; } int i = 0; - for (Pair> edgeProps : edgePropMap.values()) { - if (edgeProps != null) { + List teuList = new ArrayList(); + for (Pair> edgeProp : edgeProps) { + if (edgeProp != null) { i++; - logger.trace("Add edge {}", edgeProps.getLeft()); - topologServiceShimListener.edgeUpdate(edgeProps.getLeft(), - UpdateType.ADDED, edgeProps.getRight()); + teuList.add(new TopoEdgeUpdate(edgeProp.getLeft(), edgeProp + .getRight(), UpdateType.ADDED)); + logger.trace("Add edge {}", edgeProp.getLeft()); } } + if (i > 0) { + topologServiceShimListener.edgeUpdate(teuList); + } logger.debug("Sent {} updates", i); } + @Override + public void updateNode(Node node, UpdateType type, Set props) { + } + + @Override + public void updateNodeConnector(NodeConnector nodeConnector, + UpdateType type, Set props) { + List containers = new ArrayList(); + List conList = this.containerMap.get(nodeConnector); + + containers.add(GlobalConstants.DEFAULT.toString()); + if (conList != null) { + containers.addAll(conList); + } + + switch (type) { + case ADDED: + break; + case CHANGED: + if (props == null) { + break; + } + + boolean rmEdge = false; + for (Property prop : props) { + if (((prop instanceof Config) && (((Config) prop).getValue() != Config.ADMIN_UP)) + || ((prop instanceof State) && (((State) prop) + .getValue() != State.EDGE_UP))) { + /* + * If port admin down or link down, remove the edges + * associated with the port + */ + rmEdge = true; + break; + } + } + + if (rmEdge) { + for (String cName : containers) { + removeNodeConnector(cName, nodeConnector); + } + } + break; + case REMOVED: + for (String cName : containers) { + removeNodeConnector(cName, nodeConnector); + } + break; + default: + break; + } + } + + @Override + public void containerCreate(String containerName) { + // do nothing + } + + @Override + public void containerDestroy(String containerName) { + Set removeNodeConnectorSet = new HashSet(); + for (Map.Entry> entry : containerMap.entrySet()) { + List ncContainers = entry.getValue(); + if (ncContainers.contains(containerName)) { + NodeConnector nodeConnector = entry.getKey(); + removeNodeConnectorSet.add(nodeConnector); + } + } + for (NodeConnector nodeConnector : removeNodeConnectorSet) { + List ncContainers = containerMap.get(nodeConnector); + ncContainers.remove(containerName); + if (ncContainers.isEmpty()) { + containerMap.remove(nodeConnector); + } + } + edgeMap.remove(containerName); + } }