Merge pull request #521 from n-shiota/topodev
Refactor event handling
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
index 0728f9a..4c801d6 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
@@ -14,6 +14,7 @@
import net.floodlightcontroller.core.IOFSwitch;
import net.onrc.onos.datagrid.IDatagridService;
+import net.onrc.onos.graph.GraphDBOperation;
import net.onrc.onos.ofcontroller.topology.Topology;
import net.onrc.onos.ofcontroller.topology.TopologyElement;
import net.onrc.onos.ofcontroller.topology.TopologyManager;
@@ -46,7 +47,11 @@
class FlowEventHandler extends Thread implements IFlowEventHandlerService {
/** The logger. */
private final static Logger log = LoggerFactory.getLogger(FlowEventHandler.class);
+
+ // Flag to enable feature of acquiring topology information from DB instead of datagrid.
+ private final boolean accessDBFlag = false;
+ private GraphDBOperation dbHandler;
private FlowManager flowManager; // The Flow Manager to use
private IDatagridService datagridService; // The Datagrid Service to use
private Topology topology; // The network topology
@@ -93,10 +98,12 @@
* @param datagridService the Datagrid Service to use.
*/
FlowEventHandler(FlowManager flowManager,
- IDatagridService datagridService) {
+ IDatagridService datagridService,
+ GraphDBOperation dbHandler) {
this.flowManager = flowManager;
this.datagridService = datagridService;
this.topology = new Topology();
+ this.dbHandler = dbHandler;
}
/**
@@ -185,6 +192,7 @@
if (event.eventData() instanceof TopologyElement) {
EventEntry<TopologyElement> topologyEventEntry =
(EventEntry<TopologyElement>)event;
+
topologyEvents.add(topologyEventEntry);
continue;
}
@@ -224,7 +232,7 @@
log.debug("Exception processing Network Events: ", exception);
}
}
-
+
/**
* Process the events (if any)
*/
@@ -493,20 +501,28 @@
// Process all Topology events and update the appropriate state
//
boolean isTopologyModified = false;
- for (EventEntry<TopologyElement> eventEntry : topologyEvents) {
- TopologyElement topologyElement = eventEntry.eventData();
+ if (accessDBFlag) {
+ log.debug("[BEFORE] {}", topology.toString());
+ if (! topology.readFromDatabase(dbHandler)) {
+ isTopologyModified = true;
+ }
+ log.debug("[AFTER] {}", topology.toString());
+ } else {
+ for (EventEntry<TopologyElement> eventEntry : topologyEvents) {
+ TopologyElement topologyElement = eventEntry.eventData();
+
+ log.debug("Topology Event: {} {}", eventEntry.eventType(),
+ topologyElement.toString());
- log.debug("Topology Event: {} {}", eventEntry.eventType(),
- topologyElement);
-
- switch (eventEntry.eventType()) {
- case ENTRY_ADD:
- isTopologyModified |= topology.addTopologyElement(topologyElement);
- break;
- case ENTRY_REMOVE:
- isTopologyModified |= topology.removeTopologyElement(topologyElement);
- break;
- }
+ switch (eventEntry.eventType()) {
+ case ENTRY_ADD:
+ isTopologyModified |= topology.addTopologyElement(topologyElement);
+ break;
+ case ENTRY_REMOVE:
+ isTopologyModified |= topology.removeTopologyElement(topologyElement);
+ break;
+ }
+ }
}
if (isTopologyModified) {
// TODO: For now, if the topology changes, we recompute all Flows
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
index 02e3210..388035a 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
@@ -224,7 +224,7 @@
// - register with the Datagrid Service
// - startup
//
- flowEventHandler = new FlowEventHandler(this, datagridService);
+ flowEventHandler = new FlowEventHandler(this, datagridService, dbHandlerInner);
datagridService.registerFlowEventHandlerService(flowEventHandler);
flowEventHandler.start();
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java b/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
index fc75591..dedb589 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
@@ -381,12 +381,18 @@
* Read topology state from the database.
*
* @param dbHandler the Graph Database handler to use.
+ * @return true if topology is updated. In other words,
+ * topology read from database is different from current topology.
*/
- public void readFromDatabase(GraphDBOperation dbHandler) {
+ public boolean readFromDatabase(GraphDBOperation dbHandler) {
//
// Fetch the relevant info from the Switch and Port vertices
// from the Titan Graph.
//
+
+ Map<Long,Node> oldNodesMap = nodesMap;
+ nodesMap = new TreeMap<Long,Node>();
+
Iterable<ISwitchObject> activeSwitches = dbHandler.getActiveSwitches();
for (ISwitchObject switchObj : activeSwitches) {
Vertex nodeVertex = switchObj.asVertex();
@@ -450,5 +456,76 @@
}
}
dbHandler.commit();
+ return ! compareTopology(oldNodesMap, nodesMap);
+ }
+
+ // TODO Merge into loops in readFromDatabase() can reduce execution time.
+ /**
+ * Check given two topology are identical or not.
+ * @param topo1
+ * @param topo2
+ * @return true if identical
+ */
+ private boolean compareTopology(Map<Long,Node> topo1, Map<Long,Node> topo2) {
+ if (topo1.size() != topo2.size()) {
+ return false;
+ }
+
+ for (Map.Entry<Long,Node> nodeEntry : topo1.entrySet()) {
+ Long dpid = nodeEntry.getKey();
+ if (! topo2.containsKey(dpid)) {
+ return false;
+ }
+
+ Node n1 = nodeEntry.getValue();
+ Node n2 = topo2.get(dpid);
+
+ // check port identity
+ if (n1.ports().size() != n2.ports().size()) {
+ return false;
+ }
+ for (Integer port : n1.ports().keySet()) {
+ if (! n2.ports().containsKey(port)) {
+ return false;
+ }
+ }
+
+ // check link identity
+ if (n1.links.size() != n2.links.size()) {
+ return false;
+ }
+ for (Map.Entry<Integer, Node.Link> linkEntry : n1.links.entrySet()) {
+ Integer p1 = linkEntry.getKey();
+ Node.Link l1 = linkEntry.getValue();
+
+ if (! n2.links.containsKey(p1)) {
+ return false;
+ }
+ Node.Link l2 = n2.links.get(p1);
+
+ // Supposition: Link's "me" and "neighbor" is properly set.
+ if (l1.myPort != l2.myPort ||
+ l1.neighborPort != l2.neighborPort) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ // Only for debug use
+ @Override
+ public String toString() {
+ long numNodes = nodesMap.size();
+ long numLinks = 0;
+ for (Map.Entry<Long, Node> entry : nodesMap.entrySet()) {
+ Node n = entry.getValue();
+ for (Map.Entry<Integer, Node.Link> linkEntry : n.links.entrySet()) {
+ if (n.nodeId > linkEntry.getValue().neighbor.nodeId) {
+ ++numLinks;
+ }
+ }
+ }
+ return "Topology has " + numNodes + " Nodes and " + numLinks + " Links.";
}
}