-
/*
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Dictionary;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
+import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.opendaylight.controller.sal.core.Host;
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType;
import org.opendaylight.controller.sal.core.Property;
import org.opendaylight.controller.sal.core.TimeStamp;
import org.opendaylight.controller.sal.core.UpdateType;
+import org.opendaylight.controller.sal.core.Node.NodeIDType;
import org.opendaylight.controller.sal.topology.IListenTopoUpdates;
import org.opendaylight.controller.sal.topology.ITopologyService;
+import org.opendaylight.controller.sal.topology.TopoEdgeUpdate;
import org.opendaylight.controller.sal.utils.StatusCode;
import org.opendaylight.controller.sal.utils.GlobalConstants;
-import org.opendaylight.controller.sal.utils.HexEncode;
import org.opendaylight.controller.sal.utils.IObjectReader;
import org.opendaylight.controller.sal.utils.ObjectReader;
import org.opendaylight.controller.sal.utils.ObjectWriter;
private IClusterContainerServices clusterContainerService = null;
// DB of all the Edges with properties which constitute our topology
private ConcurrentMap<Edge, Set<Property>> edgesDB = null;
- // DB of all NodeConnector which are part of Edges, meaning they
- // are connected to another NodeConnector on the other side
+ // DB of all NodeConnector which are part of ISL Edges, meaning they
+ // are connected to another NodeConnector on the other side of an ISL link.
+ // NodeConnector of a Production Edge is not part of this DB.
private ConcurrentMap<NodeConnector, Set<Property>> nodeConnectorsDB = null;
// DB of all the NodeConnectors with an Host attached to it
private ConcurrentMap<NodeConnector, ImmutablePair<Host, Set<Property>>> hostsDB = null;
private static String ROOT = GlobalConstants.STARTUPHOME.toString();
private String userLinksFileName = null;
private ConcurrentMap<String, TopologyUserLinkConfig> userLinks;
-
+
void nonClusterObjectCreate() {
- edgesDB = new ConcurrentHashMap<Edge, Set<Property>>();
- hostsDB = new ConcurrentHashMap<NodeConnector, ImmutablePair<Host, Set<Property>>>();
- userLinks = new ConcurrentHashMap<String, TopologyUserLinkConfig>();
- nodeConnectorsDB = new ConcurrentHashMap<NodeConnector, Set<Property>>();
+ edgesDB = new ConcurrentHashMap<Edge, Set<Property>>();
+ hostsDB = new ConcurrentHashMap<NodeConnector, ImmutablePair<Host, Set<Property>>>();
+ userLinks = new ConcurrentHashMap<String, TopologyUserLinkConfig>();
+ nodeConnectorsDB = new ConcurrentHashMap<NodeConnector, Set<Property>>();
}
-
void setTopologyManagerAware(ITopologyManagerAware s) {
if (this.topologyManagerAware != null) {
- log.debug("Adding ITopologyManagerAware: " + s);
+ log.debug("Adding ITopologyManagerAware: {}", s);
this.topologyManagerAware.add(s);
}
}
void unsetTopologyManagerAware(ITopologyManagerAware s) {
if (this.topologyManagerAware != null) {
+ log.debug("Removing ITopologyManagerAware: {}", s);
this.topologyManagerAware.remove(s);
}
}
void setTopoService(ITopologyService s) {
+ log.debug("Adding ITopologyService: {}", s);
this.topoService = s;
}
void unsetTopoService(ITopologyService s) {
if (this.topoService == s) {
+ log.debug("Removing ITopologyService: {}", s);
this.topoService = null;
}
}
/**
* Function called by the dependency manager when all the required
* dependencies are satisfied
- *
+ *
*/
void init(Component c) {
String containerName = null;
}
/**
- * Function called after the topology manager has registered the
- * service in OSGi service registry.
- *
+ * Function called after the topology manager has registered the service in
+ * OSGi service registry.
+ *
*/
void started() {
// SollicitRefresh MUST be called here else if called at init
}
/**
- * 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() {
if (this.clusterContainerService == null) {
this.clusterContainerService
.destroyCache("topologymanager.nodeConnectorDB");
this.nodeConnectorsDB = null;
- log.debug("Topology Manager DB DE-allocated");
+ log.debug("Topology Manager DB Deallocated");
}
@SuppressWarnings("unchecked")
// Publish the save config event to the cluster nodes
/**
* Get the CLUSTERING SERVICES WORKING BEFORE TRYING THIS
-
- configSaveEvent.put(new Date().getTime(), SAVE);
+ *
+ * configSaveEvent.put(new Date().getTime(), SAVE);
*/
return saveConfigInternal();
}
public Status saveConfigInternal() {
- Status retS;
+ Status retS;
ObjectWriter objWriter = new ObjectWriter();
- retS = objWriter.write(
- new ConcurrentHashMap<String, TopologyUserLinkConfig>(
+ retS = objWriter
+ .write(new ConcurrentHashMap<String, TopologyUserLinkConfig>(
userLinks), userLinksFileName);
if (retS.isSuccess()) {
}
/**
- * The Map returned is a copy of the current topology hence if the
- * topology changes the copy doesn't
- *
- * @return A Map representing the current topology expressed as
- * edges of the network
+ * This method returns true if the edge is an ISL link.
+ *
+ * @param e
+ * The edge
+ * @return true if it is an ISL link
+ */
+ public boolean isISLink(Edge e) {
+ return (!isProductionLink(e));
+ }
+
+ /**
+ * This method returns true if the edge is a production link.
+ *
+ * @param e
+ * The edge
+ * @return true if it is a production link
+ */
+ public boolean isProductionLink(Edge e) {
+ return (e.getHeadNodeConnector().getType()
+ .equals(NodeConnector.NodeConnectorIDType.PRODUCTION) || e
+ .getTailNodeConnector().getType()
+ .equals(NodeConnector.NodeConnectorIDType.PRODUCTION));
+ }
+
+ /**
+ * The Map returned is a copy of the current topology hence if the topology
+ * changes the copy doesn't
+ *
+ * @return A Map representing the current topology expressed as edges of the
+ * network
*/
@Override
public Map<Edge, Set<Property>> getEdges() {
for (Edge key : this.edgesDB.keySet()) {
// Sets of props are copied because the composition of
// those properties could change with time
- HashSet<Property> prop = new HashSet<Property>(this.edgesDB
- .get(key));
+ HashSet<Property> prop = new HashSet<Property>(
+ this.edgesDB.get(key));
// We can simply reuse the key because the object is
// immutable so doesn't really matter that we are
// referencing the only owned by a different table, the
// TODO remove with spring-dm removal
/**
- * @param set the topologyAware to set
+ * @param set
+ * the topologyAware to set
*/
public void setTopologyAware(Set<Object> set) {
for (Object s : set) {
}
}
- @Override
- public void edgeUpdate(Edge e, UpdateType type, Set<Property> props) {
+ private TopoEdgeUpdate edgeUpdate(Edge e, UpdateType type,
+ Set<Property> props) {
switch (type) {
case ADDED:
// Make sure the props are non-null
props = (Set<Property>) new HashSet(props);
}
- // Now make sure thre is the creation timestamp for the
+ // Now make sure there is the creation timestamp for the
// edge, if not there timestamp with the first update
boolean found_create = false;
for (Property prop : props) {
this.edgesDB.put(e, props);
// Now populate the DB of NodeConnectors
- // NOTE WELL: properties are empy sets, not really needed
+ // NOTE WELL: properties are empty sets, not really needed
// for now.
- this.nodeConnectorsDB.put(e.getHeadNodeConnector(),
- new HashSet<Property>());
- this.nodeConnectorsDB.put(e.getTailNodeConnector(),
- new HashSet<Property>());
+ // The DB only contains ISL ports
+ if (isISLink(e)) {
+ this.nodeConnectorsDB.put(e.getHeadNodeConnector(),
+ new HashSet<Property>());
+ this.nodeConnectorsDB.put(e.getTailNodeConnector(),
+ new HashSet<Property>());
+ }
+ log.trace("Edge {} {}", e.toString(), type.name());
break;
case REMOVED:
// Now remove the edge from edgesDB
// should be safe to assume that won't happen.
this.nodeConnectorsDB.remove(e.getHeadNodeConnector());
this.nodeConnectorsDB.remove(e.getTailNodeConnector());
+ log.trace("Edge {} {}", e.toString(), type.name());
break;
case CHANGED:
Set<Property> old_props = this.edgesDB.get(e);
}
}
- // Now lest make sure new properties are non-null
+ // Now lets make sure new properties are non-null
// Make sure the props are non-null
if (props == null) {
props = (Set<Property>) new HashSet();
// Finally update
this.edgesDB.put(e, props);
+ log.trace("Edge {} {}", e.toString(), type.name());
break;
}
+ return new TopoEdgeUpdate(e, props, type);
+ }
+
+ @Override
+ public void edgeUpdate(List<TopoEdgeUpdate> topoedgeupdateList) {
+ List<TopoEdgeUpdate> teuList = new ArrayList<TopoEdgeUpdate>();
+ for (int i = 0; i < topoedgeupdateList.size(); i++) {
+ Edge e = topoedgeupdateList.get(i).getEdge();
+ Set<Property> p = topoedgeupdateList.get(i).getProperty();
+ UpdateType type = topoedgeupdateList.get(i).getUpdateType();
+ TopoEdgeUpdate teu = edgeUpdate(e, type, p);
+ teuList.add(teu);
+ }
// Now update the listeners
for (ITopologyManagerAware s : this.topologyManagerAware) {
try {
- s.edgeUpdate(e, type, props);
+ s.edgeUpdate(teuList);
} catch (Exception exc) {
log.error("Exception on callback", exc);
}
}
+
}
private Edge getReverseLinkTuple(TopologyUserLinkConfig link) {
- TopologyUserLinkConfig rLink = new TopologyUserLinkConfig(link
- .getName(), link.getDstSwitchId(), link.getDstPort(), link
- .getSrcSwitchId(), link.getSrcPort());
+ TopologyUserLinkConfig rLink = new TopologyUserLinkConfig(
+ link.getName(), link.getDstNodeIDType(), link.getDstSwitchId(),
+ link.getDstNodeConnectorIDType(), link.getDstPort(),
+ link.getSrcNodeIDType(), link.getSrcSwitchId(),
+ link.getSrcNodeConnectorIDType(), link.getSrcPort());
return getLinkTuple(rLink);
}
private Edge getLinkTuple(TopologyUserLinkConfig link) {
Edge linkTuple = null;
- Long sID = link.getSrcSwitchIDLong();
- Long dID = link.getDstSwitchIDLong();
- Short srcPort = Short.valueOf((short) 0);
- Short dstPort = Short.valueOf((short) 0);
- if (link.isSrcPortByName()) {
- // TODO find the inventory service to do this, for now 0
- //srcPort = srcSw.getPortNumber(link.getSrcPort());
- } else {
- srcPort = Short.parseShort(link.getSrcPort());
- }
-
- if (link.isDstPortByName()) {
- //dstPort = dstSw.getPortNumber(link.getDstPort());;
- } else {
- dstPort = Short.parseShort(link.getDstPort());
- }
- // if atleast 1 link exists for the srcPort and atleast 1 link exists for the dstPort
+ // if atleast 1 link exists for the srcPort and atleast 1 link exists
+ // for the dstPort
// that makes it ineligible for the Manual link addition
// This is just an extra protection to avoid mis-programming.
boolean srcLinkExists = false;
boolean dstLinkExists = false;
- /**
- * Disabling this optimization for now to understand the real benefit of doing this.
- * Since this is a Manual Link addition, the user knows what he is doing and it is
- * not good to restrict such creativity...
- */
- /*
- Set <Edge> links = oneTopology.getLinks().keySet();
- if (links != null) {
- for (Edge eLink : links) {
- if (!eLink.isUserCreated() &&
- eLink.getSrc().getSid().equals(link.getSrcSwitchIDLong()) &&
- eLink.getSrc().getPort().equals(srcPort)) {
- srcLinkExists = true;
- }
-
- if (!eLink.isUserCreated() &&
- eLink.getSrc().getSid().equals(link.getSrcSwitchIDLong()) &&
- eLink.getSrc().getPort().equals(srcPort)) {
- dstLinkExists = true;
- }
-
- if (!eLink.isUserCreated() &&
- eLink.getDst().getSid().equals(link.getSrcSwitchIDLong()) &&
- eLink.getDst().getPort().equals(srcPort)) {
- srcLinkExists = true;
- }
-
- if (!eLink.isUserCreated() &&
- eLink.getDst().getSid().equals(link.getSrcSwitchIDLong()) &&
- eLink.getDst().getPort().equals(srcPort)) {
- dstLinkExists = true;
- }
- }
- }
- */
- //TODO check a way to validate the port with inventory services
- //if (srcSw.getPorts().contains(srcPort) &&
- //dstSw.getPorts().contains(srcPort) &&
+ // TODO check a way to validate the port with inventory services
+ // if (srcSw.getPorts().contains(srcPort) &&
+ // dstSw.getPorts().contains(srcPort) &&
if (!srcLinkExists && !dstLinkExists) {
Node sNode = null;
Node dNode = null;
NodeConnector sPort = null;
NodeConnector dPort = null;
linkTuple = null;
+ String srcNodeIDType = link.getSrcNodeIDType();
+ String srcNodeConnectorIDType = link.getSrcNodeConnectorIDType();
+ String dstNodeIDType = link.getDstNodeIDType();
+ String dstNodeConnectorIDType = link.getDstNodeConnectorIDType();
try {
- sNode = new Node(Node.NodeIDType.OPENFLOW, sID);
- dNode = new Node(Node.NodeIDType.OPENFLOW, dID);
- sPort = new NodeConnector(
- NodeConnector.NodeConnectorIDType.OPENFLOW, srcPort,
- sNode);
- dPort = new NodeConnector(
- NodeConnector.NodeConnectorIDType.OPENFLOW, dstPort,
- dNode);
+ if (srcNodeIDType.equals(NodeIDType.OPENFLOW)) {
+ sNode = new Node(srcNodeIDType, link.getSrcSwitchIDLong());
+ } else {
+ sNode = new Node(srcNodeIDType, link.getSrcSwitchId());
+ }
+
+ if (dstNodeIDType.equals(NodeIDType.OPENFLOW)) {
+ dNode = new Node(dstNodeIDType, link.getDstSwitchIDLong());
+ } else {
+ dNode = new Node(dstNodeIDType, link.getDstSwitchId());
+ }
+
+ if (srcNodeConnectorIDType.equals(NodeConnectorIDType.OPENFLOW)) {
+ Short srcPort = Short.valueOf((short) 0);
+ if (!link.isSrcPortByName()) {
+ srcPort = Short.parseShort(link.getSrcPort());
+ }
+ sPort = new NodeConnector(srcNodeConnectorIDType, srcPort,
+ sNode);
+ } else {
+ sPort = new NodeConnector(srcNodeConnectorIDType,
+ link.getSrcPort(), sNode);
+ }
+
+ if (dstNodeConnectorIDType.equals(NodeConnectorIDType.OPENFLOW)) {
+ Short dstPort = Short.valueOf((short) 0);
+ if (!link.isDstPortByName()) {
+ dstPort = Short.parseShort(link.getDstPort());
+ }
+ dPort = new NodeConnector(dstNodeConnectorIDType, dstPort,
+ dNode);
+ } else {
+ dPort = new NodeConnector(dstNodeConnectorIDType,
+ link.getDstPort(), dNode);
+ }
linkTuple = new Edge(sPort, dPort);
} catch (ConstructionException cex) {
+ log.warn("Caught exception ", cex);
}
return linkTuple;
}
@Override
public Status addUserLink(TopologyUserLinkConfig link) {
if (!link.isValid()) {
- return new Status(StatusCode.BADREQUEST,
- "Configuration Invalid. Please check the parameters");
+ return new Status(StatusCode.BADREQUEST,
+ "Configuration Invalid. Please check the parameters");
}
if (userLinks.get(link.getName()) != null) {
- return new Status(StatusCode.CONFLICT,
- "Link with name : " + link.getName()
+ return new Status(StatusCode.CONFLICT, "Link with name : "
+ + link.getName()
+ " already exists. Please use another name");
}
if (userLinks.containsValue(link)) {
Edge linkTuple = getLinkTuple(link);
if (linkTuple != null) {
try {
- // TODO The onetopology will be gone too, topology
- //manager is the master of the topology at this point
- //if (oneTopology.addUserConfiguredLink(linkTuple)) {
linkTuple = getReverseLinkTuple(link);
- //if (oneTopology.addUserConfiguredLink(linkTuple)) {
link.setStatus(TopologyUserLinkConfig.STATUS.SUCCESS);
- //}
- //}
} catch (Exception e) {
return new Status(StatusCode.INTERNALERROR,
- "Exception while adding custom link : " +
- e.getMessage());
+ "Exception while adding custom link : "
+ + e.getMessage());
}
}
return new Status(StatusCode.SUCCESS, null);
@Override
public Status deleteUserLink(String linkName) {
if (linkName == null) {
- return new Status(StatusCode.BADREQUEST,
- "A valid linkName is required to Delete a link");
+ return new Status(StatusCode.BADREQUEST,
+ "A valid linkName is required to Delete a link");
}
TopologyUserLinkConfig link = userLinks.get(linkName);
userLinks.remove(linkName);
if (linkTuple != null) {
try {
- //oneTopology.deleteUserConfiguredLink(linkTuple);
+ // oneTopology.deleteUserConfiguredLink(linkTuple);
} catch (Exception e) {
- log
- .warn("Harmless : Exception while Deleting User Configured link "
- + link + " " + e.toString());
+ log.warn(
+ "Harmless : Exception while Deleting User Configured link {} {}",
+ link, e.toString());
}
linkTuple = getReverseLinkTuple(link);
try {
- //oneTopology.deleteUserConfiguredLink(linkTuple);
+ // oneTopology.deleteUserConfiguredLink(linkTuple);
} catch (Exception e) {
- log
- .error("Harmless : Exception while Deleting User Configured Reverse link "
- + link + " " + e.toString());
+ log.warn(
+ "Harmless : Exception while Deleting User Configured Reverse link {} {}",
+ link, e.toString());
}
}
return new Status(StatusCode.SUCCESS, null);
public String getHelp() {
StringBuffer help = new StringBuffer();
help.append("---Topology Manager---\n");
- help
- .append("\t addTopo name <src-sw-id> <port-number> <dst-sw-id> <port-number>\n");
+ help.append("\t addTopo name <NodeIDType> <src-sw-id> <NodeConnectorIDType> <port-number> <NodeIDType> <dst-sw-id> <NodeConnectorIDType> <port-number>\n");
help.append("\t delTopo name\n");
- help.append("\t _printTopo\n");
+ help.append("\t printTopo\n");
+ help.append("\t printNodeEdges\n");
return help.toString();
}
public void _printTopo(CommandInterpreter ci) {
for (String name : this.userLinks.keySet()) {
- ci.println(name + " : " + userLinks.get(name));
+ TopologyUserLinkConfig linkConfig = userLinks.get(name);
+ ci.println("Name : " + name);
+ ci.println(linkConfig);
+ ci.println("Edge " + getLinkTuple(linkConfig));
+ ci.println("Reverse Edge " + getReverseLinkTuple(linkConfig));
}
}
return;
}
+ String srcNodeIDType = ci.nextArgument();
+ if (srcNodeIDType == null) {
+ ci.println("Null source node ID Type. Example: OF or PR");
+ return;
+ }
+
String dpid = ci.nextArgument();
if (dpid == null) {
- ci.println("Invalid Switch ID. Format xx:xx:xx:xx:xx:xx:xx:xx");
+ ci.println("Null source node id");
return;
}
- try {
- HexEncode.stringToLong(dpid);
- } catch (Exception e) {
- ci.println("Invalid Switch ID. Format xx:xx:xx:xx:xx:xx:xx:xx");
+
+ String srcNodeConnectorIDType = ci.nextArgument();
+ if (srcNodeConnectorIDType == null) {
+ ci.println("Null source node connector ID Type. Example: OF or PR");
return;
}
String port = ci.nextArgument();
if (port == null) {
- ci.println("Invalid port number");
+ ci.println("Null source port number");
+ return;
+ }
+
+ String dstNodeIDType = ci.nextArgument();
+ if (dstNodeIDType == null) {
+ ci.println("Null destination node ID Type. Example: OF or PR");
return;
}
String ddpid = ci.nextArgument();
if (ddpid == null) {
- ci.println("Invalid Switch ID. Format xx:xx:xx:xx:xx:xx:xx:xx");
+ ci.println("Null destination node ID");
return;
}
- try {
- HexEncode.stringToLong(ddpid);
- } catch (Exception e) {
- ci.println("Invalid Switch ID. Format xx:xx:xx:xx:xx:xx:xx:xx");
+
+ String dstNodeConnectorIDType = ci.nextArgument();
+ if (dstNodeConnectorIDType == null) {
+ ci.println("Null destination node connector ID Type. Example: OF or PR");
return;
}
String dport = ci.nextArgument();
if (dport == null) {
- ci.println("Invalid port number");
+ ci.println("Null destination port number");
return;
}
TopologyUserLinkConfig config = new TopologyUserLinkConfig(name,
- dpid, port, ddpid, dport);
+ srcNodeIDType, dpid, srcNodeConnectorIDType, port,
+ dstNodeIDType, ddpid, dstNodeConnectorIDType, dport);
ci.println(this.addUserLink(config));
}
this.deleteUserLink(name);
}
+ public void _printNodeEdges(CommandInterpreter ci) {
+ Map<Node, Set<Edge>> nodeEdges = getNodeEdges();
+ if (nodeEdges == null) {
+ return;
+ }
+ Set<Node> nodeSet = nodeEdges.keySet();
+ if (nodeSet == null) {
+ return;
+ }
+ ci.println(" Node Edge");
+ for (Node node : nodeSet) {
+ Set<Edge> edgeSet = nodeEdges.get(node);
+ if (edgeSet == null) {
+ continue;
+ }
+ for (Edge edge : edgeSet) {
+ ci.println(node + " " + edge);
+ }
+ }
+ }
+
@Override
public Object readObject(ObjectInputStream ois)
throws FileNotFoundException, IOException, ClassNotFoundException {
@Override
public void edgeOverUtilized(Edge edge) {
- log.warn("Link Utilization above normal: " + edge);
+ log.warn("Link Utilization above normal: {}", edge);
}
@Override
public void edgeUtilBackToNormal(Edge edge) {
- log.warn("Link Utilization back to normal: " + edge);
+ log.warn("Link Utilization back to normal: {}", edge);
}
}