import org.opendaylight.controller.sal.utils.ObjectWriter;
import org.opendaylight.controller.sal.utils.Status;
import org.opendaylight.controller.sal.utils.StatusCode;
+import org.opendaylight.controller.switchmanager.ISwitchManager;
import org.opendaylight.controller.topologymanager.ITopologyManager;
import org.opendaylight.controller.topologymanager.ITopologyManagerAware;
import org.opendaylight.controller.topologymanager.ITopologyManagerClusterWideAware;
* topology database and notifies all the listeners of topology changes.
*/
public class TopologyManagerImpl implements
- ICacheUpdateAware,
+ ICacheUpdateAware<Object, Object>,
ITopologyManager,
IConfigurationContainerAware,
IListenTopoUpdates,
static final String TOPONODECONNECTORDB = "topologymanager.nodeConnectorDB";
static final String TOPOUSERLINKSDB = "topologymanager.userLinksDB";
private static final Logger log = LoggerFactory.getLogger(TopologyManagerImpl.class);
- private static final String SAVE = "Save";
private ITopologyService topoService;
private IClusterContainerServices clusterContainerService;
+ private ISwitchManager switchManager;
// DB of all the Edges with properties which constitute our topology
private ConcurrentMap<Edge, Set<Property>> edgesDB;
// DB of all NodeConnector which are part of ISL Edges, meaning they
}
}
+ void setSwitchManager(ISwitchManager s) {
+ log.debug("Adding ISwitchManager: {}", s);
+ this.switchManager = s;
+ }
+
+ void unsetSwitchManager(ISwitchManager s) {
+ if (this.switchManager == s) {
+ log.debug("Removing ISwitchManager: {}", s);
+ this.switchManager = null;
+ }
+ }
+
/**
* Function called by the dependency manager when all the required
* dependencies are satisfied
notifyThread = new Thread(new TopologyNotify(notifyQ));
}
- @SuppressWarnings({ "unchecked", "deprecation" })
+ @SuppressWarnings({ "unchecked" })
private void allocateCaches() {
try {
this.edgesDB =
}
}
- @SuppressWarnings({ "unchecked", "deprecation" })
+ @SuppressWarnings({ "unchecked" })
private void retrieveCaches() {
if (this.clusterContainerService == null) {
log.error("Cluster Services is null, can't retrieve caches.");
}
}
+ private boolean nodeConnectorsExist(Edge e) {
+ NodeConnector head = e.getHeadNodeConnector();
+ NodeConnector tail = e.getTailNodeConnector();
+ return (switchManager.doesNodeConnectorExist(head) &&
+ switchManager.doesNodeConnectorExist(tail));
+ }
+
private TopoEdgeUpdate edgeUpdate(Edge e, UpdateType type, Set<Property> props) {
switch (type) {
case ADDED:
+ // Avoid redundant update as notifications trigger expensive tasks
+ if (edgesDB.containsKey(e)) {
+ log.trace("Skipping redundant edge addition: {}", e);
+ return null;
+ }
+ // Ensure that both tail and head node connectors exist.
+ if (!nodeConnectorsExist(e)) {
+ log.warn("Ignore edge that contains invalid node connector: {}", e);
+ return null;
+ }
+
// Make sure the props are non-null
if (props == null) {
props = new HashSet<Property>();
Set<Property> p = topoedgeupdateList.get(i).getProperty();
UpdateType type = topoedgeupdateList.get(i).getUpdateType();
TopoEdgeUpdate teu = edgeUpdate(e, type, p);
- teuList.add(teu);
+ if (teu != null) {
+ teuList.add(teu);
+ }
}
- // Now update the listeners
- for (ITopologyManagerAware s : this.topologyManagerAware) {
- try {
- s.edgeUpdate(teuList);
- } catch (Exception exc) {
- log.error("Exception on edge update:", exc);
+ if (!teuList.isEmpty()) {
+ // Now update the listeners
+ for (ITopologyManagerAware s : this.topologyManagerAware) {
+ try {
+ s.edgeUpdate(teuList);
+ } catch (Exception exc) {
+ log.error("Exception on edge update:", exc);
+ }
}
}
-
}
private Edge getReverseLinkTuple(TopologyUserLinkConfig link) {
Edge linkTuple = getLinkTuple(userLink);
if (linkTuple != null) {
if (!isProductionLink(linkTuple)) {
- edgeUpdate(linkTuple, UpdateType.ADDED, new HashSet<Property>());
+ TopoEdgeUpdate teu = edgeUpdate(linkTuple, UpdateType.ADDED,
+ new HashSet<Property>());
+ if (teu == null) {
+ userLinksDB.remove(userLink.getName());
+ return new Status(StatusCode.NOTFOUND,
+ "Link configuration contains invalid node connector: "
+ + userLink);
+ }
}
linkTuple = getReverseLinkTuple(userLink);
public void entryUpdated(final Object key, final Object new_value, final String cacheName, final boolean originLocal) {
if (cacheName.equals(TOPOEDGESDB)) {
final Edge e = (Edge) key;
- log.trace("Edge {} CHANGED isLocal:{}", e, originLocal);
+ log.trace("Edge {} UPDATED isLocal:{}", e, originLocal);
final Set<Property> props = (Set<Property>) new_value;
edgeUpdateClusterWide(e, UpdateType.CHANGED, props, originLocal);
}
// Lets sleep for sometime to allow aggregation of event
Thread.sleep(100);
} catch (InterruptedException e1) {
- log.warn("TopologyNotify interrupted {}", e1.getMessage());
if (shuttingDown) {
return;
}
+ log.warn("TopologyNotify interrupted {}", e1.getMessage());
} catch (Exception e2) {
log.error("", e2);
}