WIP: addFlowFast()
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
index 82d4a7e..e68d04b 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
@@ -28,6 +28,7 @@
private final static Logger log = LoggerFactory.getLogger(FlowDatabaseOperation.class);
private static final boolean measureONOSFlowTimeProp = Long.valueOf(System.getProperty("benchmark.measureONOSFlow", "0")) != 0;
private static final boolean measureONOSFlowEntryTimeProp = Long.valueOf(System.getProperty("benchmark.measureONOSFlowEntry", "0")) != 0;
+ private static final boolean useFastAddFlow = true;
/**
* Add a flow.
@@ -36,7 +37,204 @@
* @param flowPath the Flow Path to install.
* @return true on success, otherwise false.
*/
+ static boolean addFlowFast(DBOperation dbHandler, FlowPath flowPath) {
+ IFlowPath flowPathObj = null;
+ FlowPathProperty flowProp = new FlowPathProperty();
+
+ flowPathObj = dbHandler.searchFlowPath(flowPath.flowId()); // toshi memo: getVertices("flow_id")
+ if (flowPathObj == null) {
+ try {
+ flowPathObj = dbHandler.newFlowPath(); // toshi memo: addVertex(), setType("flow")
+ } catch (Exception e) {
+ flowPathObj = null;
+ StringWriter sw = new StringWriter();
+ e.printStackTrace(new PrintWriter(sw));
+ log.error(":addFlow FlowId:{} failed: {}", flowPath.flowId(), sw.toString());
+ }
+ flowProp.setFlowPathUserState("FP_USER_ADD");
+ } else {
+ // Remove the old Flow Entries (this is special for RAMCloud)
+ for (IFlowEntry flowEntryObj : flowPathObj.getFlowEntries()) { // toshi memo: get.@Adjacency("flow", IN)
+ //flowObj.removeFlowEntry(flowEntryObj); // toshi memo: remove.@Adjacency("flow", IN)
+ dbHandler.removeFlowEntry(flowEntryObj); // toshi memo: removeVertex()
+ }
+ flowProp.setFlowPathUserState("FP_USER_MODIFY");
+ }
+ if (flowPathObj == null) {
+ log.error(":addFlow FlowId:{} failed: Flow object not created", flowPath.flowId());
+ dbHandler.rollback();
+
+ return false;
+ }
+
+ // Set the Flow key
+ flowProp.setFlowId(flowPath.flowId().toString());
+
+ // Set the Flow attributes
+ flowProp.setInstallerId(flowPath.installerId().toString());
+ flowProp.setFlowPathType(flowPath.flowPathType().toString());
+ flowProp.setFlowPathUserState(flowPath.flowPathUserState().toString());
+ flowProp.setFlowPathFlags(flowPath.flowPathFlags().flags());
+ flowProp.setIdleTimeout(flowPath.idleTimeout());
+ flowProp.setHardTimeout(flowPath.hardTimeout());
+ flowProp.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
+ flowProp.setSrcPort(flowPath.dataPath().srcPort().port().value());
+ flowProp.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
+ flowProp.setDstPort(flowPath.dataPath().dstPort().port().value());
+
+ if (flowPath.flowEntryMatch().matchSrcMac()) {
+ flowProp.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
+ }
+ if (flowPath.flowEntryMatch().matchDstMac()) {
+ flowProp.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
+ }
+ if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
+ flowProp.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
+ }
+ if (flowPath.flowEntryMatch().matchVlanId()) {
+ flowProp.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
+ }
+ if (flowPath.flowEntryMatch().matchVlanPriority()) {
+ flowProp.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
+ }
+ if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
+ flowProp.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
+ }
+ if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
+ flowProp.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
+ }
+ if (flowPath.flowEntryMatch().matchIpProto()) {
+ flowProp.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
+ }
+ if (flowPath.flowEntryMatch().matchIpToS()) {
+ flowProp.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
+ }
+ if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
+ flowProp.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
+ }
+ if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
+ flowProp.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
+ }
+ if (! flowPath.flowEntryActions().actions().isEmpty()) {
+ flowProp.setActions(flowPath.flowEntryActions().toString());
+ }
+ flowProp.setDataPathSummary(flowPath.dataPath().dataPathSummary());
+
+ flowProp.commitProperties(dbHandler, flowPathObj); // toshi memo: flowObj.setProperties()
+
+ //
+ // Flow Entries:
+ // flowPath.dataPath().flowEntries()
+ //
+ for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
+ if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE)
+ continue; // Skip: all Flow Entries were deleted earlier
+
+ IFlowEntry iFlowEntry = null;
+ FlowEntryProperty flowEntryProp = new FlowEntryProperty();
+
+ try {
+ iFlowEntry = dbHandler.searchFlowEntry(flowEntry.flowEntryId()); // toshi memo: getVertices()
+ if (iFlowEntry != null) {
+ flowEntryProp.setUserState("FE_USER_MODIFY");
+ } else {
+ flowEntryProp.setUserState("FE_USER_ADD");
+ iFlowEntry = dbHandler.newFlowEntry(); // toshi memo: addVertex(). setType("flow_entry")
+ //flowObj.addFlowEntry(iFlowEntry); // toshi memo: add.@Adjacency("flow", IN)
+ iFlowEntry.setFlow(flowPathObj); // toshi memo: set.@Adjacency("flow")
+ }
+ } catch (Exception e) {
+ iFlowEntry = null;
+ }
+ if (iFlowEntry == null) {
+ log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created", flowEntry.flowEntryId());
+ dbHandler.rollback();
+ return false;
+ }
+
+ // Set the Flow Entry key
+ flowEntryProp.setFlowEntryId(flowEntry.flowEntryId().toString());
+ flowEntryProp.setType("flow_entry");
+
+ // Set the Flow Entry Edges
+ ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString()); // toshi memo: getVertices()
+
+ flowEntryProp.setIdleTimeout(flowEntry.idleTimeout());
+ flowEntryProp.setHardTimeout(flowEntry.hardTimeout());
+ flowEntryProp.setSwitchDpid(flowEntry.dpid().toString());
+
+ iFlowEntry.setSwitch(sw); // toshi memo: set.@Adjacency("switch")
+ if (flowEntry.flowEntryMatch().matchInPort()) {
+ IPortObject inport = dbHandler.searchPort(flowEntry.dpid().toString(), flowEntry.flowEntryMatch().inPort().value()); // toshi memo: getVertices()
+ flowEntryProp.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
+ iFlowEntry.setInPort(inport); // toshi memo: set.@Adjacency("inport")
+ }
+
+ // Set the Flow Entry attributes
+ if (flowEntry.flowEntryMatch().matchSrcMac()) {
+ flowEntryProp.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
+ }
+ if (flowEntry.flowEntryMatch().matchDstMac()) {
+ flowEntryProp.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
+ }
+ if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
+ flowEntryProp.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
+ }
+ if (flowEntry.flowEntryMatch().matchVlanId()) {
+ flowEntryProp.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
+ }
+ if (flowEntry.flowEntryMatch().matchVlanPriority()) {
+ flowEntryProp.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
+ }
+ if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
+ flowEntryProp.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
+ }
+ if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
+ flowEntryProp.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
+ }
+ if (flowEntry.flowEntryMatch().matchIpProto()) {
+ flowEntryProp.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
+ }
+ if (flowEntry.flowEntryMatch().matchIpToS()) {
+ flowEntryProp.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
+ }
+ if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
+ flowEntryProp.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
+ }
+ if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
+ flowEntryProp.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
+ }
+
+ for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
+ if (fa.actionOutput() != null) {
+ IPortObject outport = dbHandler.searchPort(flowEntry.dpid().toString(), fa.actionOutput().port().value()); // toshi memo: getVertices()
+ flowEntryProp.setActionOutputPort(fa.actionOutput().port().value());
+ iFlowEntry.setOutPort(outport); // set.@Adjacency("outport")
+ }
+ }
+ if (! flowEntry.flowEntryActions().isEmpty()) {
+ flowEntryProp.setActions(flowEntry.flowEntryActions().toString());
+ }
+
+ flowEntryProp.setSwitchState(flowEntry.flowEntrySwitchState().toString());
+ flowEntryProp.commitProperties(dbHandler, iFlowEntry); // toshi memo: setProperties()
+ }
+
+ dbHandler.commit();
+ return true;
+ }
+
+ /**
+ * Add a flow.
+ *
+ * @param dbHandler the Graph Database handler to use.
+ * @param flowPath the Flow Path to install.
+ * @return true on success, otherwise false.
+ */
static boolean addFlow(DBOperation dbHandler, FlowPath flowPath) {
+ if (useFastAddFlow)
+ return addFlowFast(dbHandler, flowPath);
+
IFlowPath flowObj = null;
boolean found = false;
long startAddFlow = 0;
@@ -131,7 +329,7 @@
startSettingFlowPathProps = System.nanoTime();
}
- FlowPathProperty flowProp = new FlowPathProperty(dbHandler, flowObj);
+ FlowPathProperty flowProp = new FlowPathProperty();
//
// Set the Flow key:
@@ -261,7 +459,7 @@
else
flowProp.setFlowPathUserState("FP_USER_ADD");
- flowProp.commitProperties();
+ flowProp.commitProperties(dbHandler, flowObj);
if ( measureONOSFlowTimeProp ) {
++numPropsSet;
@@ -427,7 +625,7 @@
startSetProperties = System.nanoTime();
}
- FlowEntryProperty flowProp = new FlowEntryProperty(dbHandler, flowEntryObj);
+ FlowEntryProperty flowProp = new FlowEntryProperty();
//
// Set the Flow Entry key:
@@ -622,7 +820,7 @@
if (measureONOSFlowEntryTimeProp) {
numProperties += 2;
}
- flowProp.commitProperties();
+ flowProp.commitProperties(dbHandler, flowEntryObj);
//
// TODO: Take care of the FlowEntryErrorState.
//
@@ -637,7 +835,7 @@
if (measureONOSFlowEntryTimeProp) {
startAddEdgeBetweenFlowPath = System.nanoTime();
}
- flowObj.addFlowEntry(flowEntryObj);
+ //flowObj.addFlowEntry(flowEntryObj);
flowEntryObj.setFlow(flowObj);
if (measureONOSFlowEntryTimeProp) {
endAddEdgeBetweenFlowPath = System.nanoTime();
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEntryProperty.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEntryProperty.java
index 7b17aaa..b45f8ff 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEntryProperty.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEntryProperty.java
@@ -8,13 +8,6 @@
public class FlowEntryProperty {
private Map<String, Object> map = new HashMap<>();
- private DBOperation dbhandler;
- private IFlowEntry flowEntry;
-
- public FlowEntryProperty(DBOperation dbHandler, IFlowEntry flowEntry) {
- this.dbhandler = dbHandler;
- this.flowEntry = flowEntry;
- }
public void setFlowId(String value) {
map.put("flow_id", value);
@@ -144,7 +137,7 @@
*
* @param dbhandler
*/
- public void commitProperties() {
- dbhandler.setVertexProperties(flowEntry.asVertex() ,map);
+ public void commitProperties(DBOperation dbhandler, IFlowEntry flowEntry) {
+ dbhandler.setVertexProperties(flowEntry.asVertex(), map);
}
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowPathProperty.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowPathProperty.java
index c6a2b98..21db7bc 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowPathProperty.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowPathProperty.java
@@ -8,13 +8,6 @@
public class FlowPathProperty {
private Map<String, Object> map = new HashMap<>();
- private DBOperation dbhandler;
- private IFlowPath flowPath;
-
- public FlowPathProperty(DBOperation dbHandler, IFlowPath flowPath) {
- this.dbhandler = dbHandler;
- this.flowPath = flowPath;
- }
public void setType(String typeStr) {
map.put("type", typeStr);
@@ -120,7 +113,7 @@
*
* @param dbhandler
*/
- public void commitProperties() {
+ public void commitProperties(DBOperation dbhandler, IFlowPath flowPath) {
dbhandler.setVertexProperties(flowPath.asVertex() ,map);
}
}