blob: a2f2c2106a15035064da7e418f9e22aeaf100213 [file] [log] [blame]
package net.onrc.onos.ofcontroller.topology;
import java.util.HashMap;
import java.util.Map;
import net.onrc.onos.graph.GraphDBOperation;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
import org.openflow.util.HexString;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Vertex;
/**
* A class for storing Node and Link information for fast computation
* of shortest paths.
*/
class Node {
/**
* A class for storing Link information for fast computation of shortest
* paths.
*/
class Link {
public Node me; // The node this link originates from
public Node neighbor; // The neighbor node on the other side
public short myPort; // Local port number for the link
public short neighborPort; // Neighbor port number for the link
/**
* Link constructor.
*
* @param me the node this link originates from.
* @param the neighbor node on the other side of the link.
* @param myPort local port number for the link.
* @param neighborPort neighrobr port number for the link.
*/
public Link(Node me, Node neighbor, short myPort, short neighborPort) {
this.me = me;
this.neighbor = neighbor;
this.myPort = myPort;
this.neighborPort = neighborPort;
}
};
public long nodeId; // The node ID
public HashMap<Short, Link> links; // The links originating from this node
/**
* Node constructor.
*
* @param nodeId the node ID.
*/
public Node(long nodeId) {
this.nodeId = nodeId;
links = new HashMap<Short, Link>();
}
/**
* Add a neighbor.
*
* A new link to the neighbor will be created.
*
* @param neighbor the neighbor to add.
* @param myPort the local port number for the link to the neighbor.
* @param neighborPort the neighbor port number for the link.
*/
public void addNeighbor(Node neighbor, short myPort, short neighborPort) {
Link link = new Link(this, neighbor, myPort, neighborPort);
links.put(myPort, link);
}
};
/**
* A class for storing topology information.
*/
public class Topology {
private Map<Long, Node> nodesMap; // The dpid->Node mapping
public Topology() {
nodesMap = new HashMap<Long, Node>();
}
/**
* Get a node for a give Node ID.
*
* @param nodeId the Node ID to use.
* @return the corresponding Node if found, otherwise null.
*/
Node getNode(long nodeId) {
return nodesMap.get(nodeId);
}
/**
* Read topology state from the database.
*
* @param dbHandler the Graph Database handler to use.
*/
public void readFromDatabase(GraphDBOperation dbHandler) {
//
// Fetch the relevant info from the Switch and Port vertices
// from the Titan Graph.
//
Iterable<ISwitchObject> activeSwitches = dbHandler.getActiveSwitches();
for (ISwitchObject switchObj : activeSwitches) {
Vertex nodeVertex = switchObj.asVertex();
//
// The Switch info
//
String nodeDpid = nodeVertex.getProperty("dpid").toString();
long nodeId = HexString.toLong(nodeDpid);
Node me = nodesMap.get(nodeId);
if (me == null) {
me = new Node(nodeId);
nodesMap.put(nodeId, me);
}
//
// The local Port info
//
for (Vertex myPortVertex : nodeVertex.getVertices(Direction.OUT, "on")) {
// Ignore inactive ports
if (! myPortVertex.getProperty("state").toString().equals("ACTIVE"))
continue;
short myPort = 0;
Object obj = myPortVertex.getProperty("number");
if (obj instanceof Short) {
myPort = (Short)obj;
} else if (obj instanceof Integer) {
Integer int_nodeId = (Integer)obj;
myPort = int_nodeId.shortValue();
}
//
// The neighbor Port info
//
for (Vertex neighborPortVertex : myPortVertex.getVertices(Direction.OUT, "link")) {
// Ignore inactive ports
if (! neighborPortVertex.getProperty("state").toString().equals("ACTIVE"))
continue;
short neighborPort = 0;
obj = neighborPortVertex.getProperty("number");
if (obj instanceof Short) {
neighborPort = (Short)obj;
} else if (obj instanceof Integer) {
Integer int_nodeId = (Integer)obj;
neighborPort = int_nodeId.shortValue();
}
//
// The neighbor Switch info
//
for (Vertex neighborVertex : neighborPortVertex.getVertices(Direction.IN, "on")) {
// Ignore inactive switches
String state = neighborVertex.getProperty("state").toString();
if (! state.equals(SwitchState.ACTIVE.toString()))
continue;
String neighborDpid = neighborVertex.getProperty("dpid").toString();
long neighborId = HexString.toLong(neighborDpid);
Node neighbor = nodesMap.get(neighborId);
if (neighbor == null) {
neighbor = new Node(neighborId);
nodesMap.put(neighborId, neighbor);
}
me.addNeighbor(neighbor, myPort, neighborPort);
}
}
}
}
dbHandler.commit();
}
}