blob: 82d4a7e502da9ad5811af7f38cf3901877bce6cd [file] [log] [blame]
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001package net.onrc.onos.ofcontroller.flowmanager;
2
3import java.io.PrintWriter;
4import java.io.StringWriter;
5import java.util.ArrayList;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07006import java.util.LinkedList;
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08007import java.util.Map;
8
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07009import net.floodlightcontroller.util.MACAddress;
yoshitomob292c622013-11-23 14:35:58 -080010import net.onrc.onos.graph.DBOperation;
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -080011import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IBaseObject;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070012import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
13import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
14import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
15import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
16import net.onrc.onos.ofcontroller.util.*;
17
18import org.slf4j.Logger;
19import org.slf4j.LoggerFactory;
20
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -080021import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -080022import com.tinkerpop.blueprints.impls.ramcloud.RamCloudVertex;
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -080023
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070024/**
25 * Class for performing Flow-related operations on the Database.
26 */
Pavlin Radoslavov6bfaea62013-12-03 14:55:57 -080027public class FlowDatabaseOperation {
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070028 private final static Logger log = LoggerFactory.getLogger(FlowDatabaseOperation.class);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -080029 private static final boolean measureONOSFlowTimeProp = Long.valueOf(System.getProperty("benchmark.measureONOSFlow", "0")) != 0;
30 private static final boolean measureONOSFlowEntryTimeProp = Long.valueOf(System.getProperty("benchmark.measureONOSFlowEntry", "0")) != 0;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070031
32 /**
33 * Add a flow.
34 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070035 * @param dbHandler the Graph Database handler to use.
36 * @param flowPath the Flow Path to install.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070037 * @return true on success, otherwise false.
38 */
onlab-qa38805cd2013-12-06 20:08:54 -080039 static boolean addFlow(DBOperation dbHandler, FlowPath flowPath) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070040 IFlowPath flowObj = null;
41 boolean found = false;
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080042 long startAddFlow = 0;
43 long endAddFlow = 0;
44 long endSearchExistingFlowPathTime = 0;
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -080045 long startCreateNewFlowPathTime = 0;
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080046 long endCreateNewFlowPathTime = 0;
47 long startFollowExistingFlowEntries = 0;
48 long endFollowExistingFlowEntries = 0;
49 long accTimeRemovingFlowEntriesFromFlowPath = 0;
50 long accTimeRemovingFlowEntriesFromDB = 0;
51 long startSettingFlowPathProps = 0;
52 long endSettingFlowPathProps = 0;
53 int numPropsSet = 0;
54 long accTimeAddFlowEntries = 0;
55 int numNewFlowEntries = 0;
56 LinkedList<long[]> flowEntryTimes = new LinkedList<>();
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -080057 PerfMon pm = PerfMon.getInstance();
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080058
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -080059 pm.addflowpath_start();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070060 try {
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080061 if ( measureONOSFlowTimeProp ) {
62 startAddFlow = System.nanoTime();
63 }
yoshi40210942013-12-03 08:21:02 -080064 flowObj = dbHandler.searchFlowPath(flowPath.flowId());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080065 if ( measureONOSFlowTimeProp ) {
66 endSearchExistingFlowPathTime = System.nanoTime();
67 }
yoshi40210942013-12-03 08:21:02 -080068 if (flowObj != null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070069 found = true;
70 } else {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -080071 if ( measureONOSFlowTimeProp ) {
72 startCreateNewFlowPathTime = System.nanoTime();
73 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070074 flowObj = dbHandler.newFlowPath();
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080075 if ( measureONOSFlowTimeProp ) {
76 endCreateNewFlowPathTime = System.nanoTime();
77 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070078 }
79 } catch (Exception e) {
80 dbHandler.rollback();
81
82 StringWriter sw = new StringWriter();
83 e.printStackTrace(new PrintWriter(sw));
84 String stacktrace = sw.toString();
85
86 log.error(":addFlow FlowId:{} failed: {}",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -080087 flowPath.flowId(),
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070088 stacktrace);
89 return false;
90 }
91 if (flowObj == null) {
92 log.error(":addFlow FlowId:{} failed: Flow object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -080093 flowPath.flowId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070094 dbHandler.rollback();
95 return false;
96 }
97
98 //
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -080099 // Remove the old Flow Entries
100 //
101 if (found) {
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800102 if ( measureONOSFlowTimeProp ) {
103 startFollowExistingFlowEntries = System.nanoTime();
104 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800105 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800106 if ( measureONOSFlowTimeProp ) {
107 endFollowExistingFlowEntries = System.nanoTime();
108 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800109 LinkedList<IFlowEntry> deleteFlowEntries =
110 new LinkedList<IFlowEntry>();
111 for (IFlowEntry flowEntryObj : flowEntries)
112 deleteFlowEntries.add(flowEntryObj);
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800113 if( measureONOSFlowTimeProp ) {
114 for (IFlowEntry flowEntryObj : deleteFlowEntries) {
115 long start = System.nanoTime();
116 flowObj.removeFlowEntry(flowEntryObj);
117 accTimeRemovingFlowEntriesFromFlowPath += System.nanoTime() - start;
118 start = System.nanoTime();
119 dbHandler.removeFlowEntry(flowEntryObj);
120 accTimeRemovingFlowEntriesFromDB += System.nanoTime() - start;
121 }
122 } else {
123 for (IFlowEntry flowEntryObj : deleteFlowEntries) {
124 flowObj.removeFlowEntry(flowEntryObj);
125 dbHandler.removeFlowEntry(flowEntryObj);
126 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800127 }
128 }
129
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800130 if ( measureONOSFlowTimeProp ) {
131 startSettingFlowPathProps = System.nanoTime();
132 }
Toshio Koidea9b25142014-01-10 01:15:57 -0800133
134 FlowPathProperty flowProp = new FlowPathProperty(dbHandler, flowObj);
135
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800136 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700137 // Set the Flow key:
138 // - flowId
139 //
Toshio Koidea9b25142014-01-10 01:15:57 -0800140 flowProp.setFlowId(flowPath.flowId().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800141 if ( measureONOSFlowTimeProp ) {
142 numPropsSet += 2;
143 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700144
145 //
146 // Set the Flow attributes:
147 // - flowPath.installerId()
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700148 // - flowPath.flowPathType()
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700149 // - flowPath.flowPathUserState()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700150 // - flowPath.flowPathFlags()
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800151 // - flowPath.idleTimeout()
152 // - flowPath.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700153 // - flowPath.dataPath().srcPort()
154 // - flowPath.dataPath().dstPort()
155 // - flowPath.matchSrcMac()
156 // - flowPath.matchDstMac()
157 // - flowPath.matchEthernetFrameType()
158 // - flowPath.matchVlanId()
159 // - flowPath.matchVlanPriority()
160 // - flowPath.matchSrcIPv4Net()
161 // - flowPath.matchDstIPv4Net()
162 // - flowPath.matchIpProto()
163 // - flowPath.matchIpToS()
164 // - flowPath.matchSrcTcpUdpPort()
165 // - flowPath.matchDstTcpUdpPort()
166 // - flowPath.flowEntryActions()
167 //
Toshio Koidea9b25142014-01-10 01:15:57 -0800168 flowProp.setInstallerId(flowPath.installerId().toString());
169 flowProp.setFlowPathType(flowPath.flowPathType().toString());
170 flowProp.setFlowPathUserState(flowPath.flowPathUserState().toString());
171 flowProp.setFlowPathFlags(flowPath.flowPathFlags().flags());
172 flowProp.setIdleTimeout(flowPath.idleTimeout());
173 flowProp.setHardTimeout(flowPath.hardTimeout());
174 flowProp.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
175 flowProp.setSrcPort(flowPath.dataPath().srcPort().port().value());
176 flowProp.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
177 flowProp.setDstPort(flowPath.dataPath().dstPort().port().value());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800178 if ( measureONOSFlowTimeProp ) {
179 numPropsSet += 10;
180 }
181
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700182 if (flowPath.flowEntryMatch().matchSrcMac()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800183 flowProp.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800184 if ( measureONOSFlowTimeProp ) {
185 ++numPropsSet;
186 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700187 }
188 if (flowPath.flowEntryMatch().matchDstMac()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800189 flowProp.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800190 if ( measureONOSFlowTimeProp ) {
191 ++numPropsSet;
192 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700193 }
194 if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800195 flowProp.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800196 if ( measureONOSFlowTimeProp ) {
197 ++numPropsSet;
198 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700199 }
200 if (flowPath.flowEntryMatch().matchVlanId()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800201 flowProp.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800202 if ( measureONOSFlowTimeProp ) {
203 ++numPropsSet;
204 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700205 }
206 if (flowPath.flowEntryMatch().matchVlanPriority()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800207 flowProp.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800208 if ( measureONOSFlowTimeProp ) {
209 ++numPropsSet;
210 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700211 }
212 if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800213 flowProp.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800214 if ( measureONOSFlowTimeProp ) {
215 ++numPropsSet;
216 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700217 }
218 if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800219 flowProp.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800220 if ( measureONOSFlowTimeProp ) {
221 ++numPropsSet;
222 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700223 }
224 if (flowPath.flowEntryMatch().matchIpProto()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800225 flowProp.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800226 if ( measureONOSFlowTimeProp ) {
227 ++numPropsSet;
228 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700229 }
230 if (flowPath.flowEntryMatch().matchIpToS()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800231 flowProp.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800232 if ( measureONOSFlowTimeProp ) {
233 ++numPropsSet;
234 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700235 }
236 if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800237 flowProp.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800238 if ( measureONOSFlowTimeProp ) {
239 ++numPropsSet;
240 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700241 }
242 if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800243 flowProp.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800244 if ( measureONOSFlowTimeProp ) {
245 ++numPropsSet;
246 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700247 }
248 if (! flowPath.flowEntryActions().actions().isEmpty()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800249 flowProp.setActions(flowPath.flowEntryActions().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800250 if ( measureONOSFlowTimeProp ) {
251 ++numPropsSet;
252 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700253 }
Toshio Koidea9b25142014-01-10 01:15:57 -0800254 flowProp.setDataPathSummary(flowPath.dataPath().dataPathSummary());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800255 if ( measureONOSFlowTimeProp ) {
256 ++numPropsSet;
257 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700258
259 if (found)
Toshio Koidea9b25142014-01-10 01:15:57 -0800260 flowProp.setFlowPathUserState("FP_USER_MODIFY");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700261 else
Toshio Koidea9b25142014-01-10 01:15:57 -0800262 flowProp.setFlowPathUserState("FP_USER_ADD");
263
264 flowProp.commitProperties();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700265
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800266 if ( measureONOSFlowTimeProp ) {
267 ++numPropsSet;
268 }
269
270 if ( measureONOSFlowTimeProp ) {
271 endSettingFlowPathProps = System.nanoTime();
272 }
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800273 pm.addflowpath_end();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700274 // Flow edges:
275 // HeadFE
276
277
278 //
279 // Flow Entries:
280 // flowPath.dataPath().flowEntries()
281 //
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800282 pm.addflowentry_start();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700283 for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800284 if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE)
285 continue; // Skip: all Flow Entries were deleted earlier
286
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800287 pm.addflowentry_incr();
288
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800289 long startAddFlowEntry = 0, endAddFlowEntry;
290 if( measureONOSFlowTimeProp ) {
291 startAddFlowEntry = System.nanoTime();
292 }
293 IFlowEntry iFlowEntry = addFlowEntry(dbHandler, flowObj, flowEntry);
294 if( measureONOSFlowTimeProp ) {
295 endAddFlowEntry = System.nanoTime();
296 accTimeAddFlowEntries += endAddFlowEntry - startAddFlowEntry;
297
298 flowEntryTimes.addLast( new long[]{flowEntry.flowId().value(), endAddFlowEntry - startAddFlowEntry} );
299 }
300 if ( iFlowEntry == null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700301 dbHandler.rollback();
302 return false;
303 }
304 }
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800305 pm.addflowentry_end();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700306 dbHandler.commit();
307
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800308
309 if ( measureONOSFlowTimeProp ) {
310 endAddFlow = System.nanoTime();
311
Yuta HIGUCHI0b4fbaf2014-01-04 22:23:05 -0800312 log.error("Performance addFlow(_,{}) -- "
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800313 + "GrandTotal: {} "
314 + "only FlowPathTotal: {} "
315 + "searchExistingFlowPath: {} "
316 + "createNewFlowPathTime: {}"
317 + "followExistingFlowEntries: {} "
318 + "accTimeRemovingFlowEntriesFromFlowPath: {} "
319 + "accTimeRemovingFlowEntriesFromDB: {} "
320 + "settingFlowPathProps: {} #Props: {} "
321 + "accFlowEntries: {} #FEs: {}",
322 flowPath.flowId(),
323 (endAddFlow - startAddFlow),
324 (endSettingFlowPathProps - startAddFlow),
325 (endSearchExistingFlowPathTime - startAddFlow),
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800326 (endCreateNewFlowPathTime - startCreateNewFlowPathTime),
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800327 (endFollowExistingFlowEntries - startFollowExistingFlowEntries),
328 (accTimeRemovingFlowEntriesFromFlowPath),
329 (accTimeRemovingFlowEntriesFromDB),
330 (endSettingFlowPathProps - startSettingFlowPathProps), numPropsSet,
331 accTimeAddFlowEntries, numNewFlowEntries
332 );
333
334 // Each FlowEntries
335 final String strFlowId = flowPath.flowId().toString();
336 for ( long[] idFE_Time : flowEntryTimes ) {
Yuta HIGUCHI0b4fbaf2014-01-04 22:23:05 -0800337 log.error("Performance addFlowEntry(_,{},{})@addFlow -- FlowEntryTotal: {}",
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800338 strFlowId,
339 "0x" + Long.toHexString(idFE_Time[0]),
340 idFE_Time[1]);
341 }
342 }
343
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700344 return true;
345 }
346
347 /**
348 * Add a flow entry to the Network MAP.
349 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700350 * @param dbHandler the Graph Database handler to use.
351 * @param flowObj the corresponding Flow Path object for the Flow Entry.
352 * @param flowEntry the Flow Entry to install.
353 * @return the added Flow Entry object on success, otherwise null.
354 */
onlab-qa38805cd2013-12-06 20:08:54 -0800355 static IFlowEntry addFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700356 IFlowPath flowObj,
357 FlowEntry flowEntry) {
358 // Flow edges
359 // HeadFE (TODO)
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800360 long startAddFlowEntry = 0;
361 long endAddFlowEntry = 0;
362
363 long endSearchFlowEntry = 0;
364
365 long startCreateNewFlowEntry = 0;
366 long endCreateNewFlowEntry = 0;
367
368 long startSetProperties = 0;
369 long endSetProperties = 0;
370 int numProperties = 0;
371
372 long startSearchSwitch = 0;
373 long endSearchSwitch = 0;
374
375 long startAddEdgeToSwitch =0;
376 long endAddEdgeToSwitch =0;
377
378 long startSearchInPort = 0;
379 long endSearchInPort = 0;
380
381 long startAddEdgeToInPort =0;
382 long endAddEdgeToInPort =0;
383
384 long startSearchOutPort = 0;
385 long endSearchOutPort = 0;
386
387 long startAddEdgeToOutPort =0;
388 long endAddEdgeToOutPort =0;
389
390 long startAddEdgeBetweenFlowPath = 0;
391 long endAddEdgeBetweenFlowPath = 0;
392
393 if (measureONOSFlowEntryTimeProp) {
394 startAddFlowEntry = System.nanoTime();
395 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700396
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700397 IFlowEntry flowEntryObj = null;
398 boolean found = false;
399 try {
Yuta HIGUCHIc27a6c92014-01-07 11:51:11 -0800400 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
401 if (measureONOSFlowEntryTimeProp) {
402 endSearchFlowEntry = System.nanoTime();
403 }
404 if (flowEntryObj != null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700405 found = true;
406 } else {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800407 if (measureONOSFlowEntryTimeProp) {
408 startCreateNewFlowEntry = System.nanoTime();
409 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700410 flowEntryObj = dbHandler.newFlowEntry();
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800411 if (measureONOSFlowEntryTimeProp) {
412 endCreateNewFlowEntry = System.nanoTime();
413 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700414 }
415 } catch (Exception e) {
416 log.error(":addFlow FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800417 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700418 return null;
419 }
420 if (flowEntryObj == null) {
421 log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800422 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700423 return null;
424 }
425
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800426 if (measureONOSFlowEntryTimeProp) {
427 startSetProperties = System.nanoTime();
428 }
Yuta HIGUCHI8685f9c2014-01-07 15:53:28 -0800429
Toshio Koide7f76e9e2014-01-09 22:06:35 -0800430 FlowEntryProperty flowProp = new FlowEntryProperty(dbHandler, flowEntryObj);
Yuta HIGUCHI8685f9c2014-01-07 15:53:28 -0800431
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700432 //
433 // Set the Flow Entry key:
434 // - flowEntry.flowEntryId()
435 //
Toshio Koide3f233542014-01-07 14:19:09 -0800436 flowProp.setFlowEntryId(flowEntry.flowEntryId().toString());
437 flowProp.setType("flow_entry");
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800438 if (measureONOSFlowEntryTimeProp) {
439 numProperties += 2;
440 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700441
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800442 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700443 // Set the Flow Entry Edges and attributes:
444 // - Switch edge
445 // - InPort edge
446 // - OutPort edge
447 //
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800448 // - flowEntry.idleTimeout()
449 // - flowEntry.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700450 // - flowEntry.dpid()
451 // - flowEntry.flowEntryUserState()
452 // - flowEntry.flowEntrySwitchState()
453 // - flowEntry.flowEntryErrorState()
454 // - flowEntry.matchInPort()
455 // - flowEntry.matchSrcMac()
456 // - flowEntry.matchDstMac()
457 // - flowEntry.matchEthernetFrameType()
458 // - flowEntry.matchVlanId()
459 // - flowEntry.matchVlanPriority()
460 // - flowEntry.matchSrcIPv4Net()
461 // - flowEntry.matchDstIPv4Net()
462 // - flowEntry.matchIpProto()
463 // - flowEntry.matchIpToS()
464 // - flowEntry.matchSrcTcpUdpPort()
465 // - flowEntry.matchDstTcpUdpPort()
466 // - flowEntry.actionOutputPort()
467 // - flowEntry.actions()
468 //
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800469 if (measureONOSFlowEntryTimeProp) {
470 startSearchSwitch = System.nanoTime();
471 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700472 ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800473 if (measureONOSFlowEntryTimeProp) {
474 endSearchSwitch = System.nanoTime();
475 }
476
Toshio Koide3f233542014-01-07 14:19:09 -0800477 flowProp.setIdleTimeout(flowEntry.idleTimeout());
478 flowProp.setHardTimeout(flowEntry.hardTimeout());
479 flowProp.setSwitchDpid(flowEntry.dpid().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800480 if (measureONOSFlowEntryTimeProp) {
481 numProperties += 3;
482 }
483
484 if (measureONOSFlowEntryTimeProp) {
485 startAddEdgeToSwitch = System.nanoTime();
486 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700487 flowEntryObj.setSwitch(sw);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800488 if (measureONOSFlowEntryTimeProp) {
489 endAddEdgeToSwitch = System.nanoTime();
490 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700491 if (flowEntry.flowEntryMatch().matchInPort()) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800492 if (measureONOSFlowEntryTimeProp) {
493 startSearchInPort = System.nanoTime();
494 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700495 IPortObject inport =
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800496 dbHandler.searchPort(flowEntry.dpid().toString(),
497 flowEntry.flowEntryMatch().inPort().value());
498 if (measureONOSFlowEntryTimeProp) {
499 endSearchInPort = System.nanoTime();
500 }
501
Toshio Koide3f233542014-01-07 14:19:09 -0800502 flowProp.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800503 if (measureONOSFlowEntryTimeProp) {
504 ++numProperties;
505 }
506
507 if (measureONOSFlowEntryTimeProp) {
508 startAddEdgeToInPort = System.nanoTime();
509 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700510 flowEntryObj.setInPort(inport);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800511 if (measureONOSFlowEntryTimeProp) {
512 endAddEdgeToInPort = System.nanoTime();
513 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700514 }
515 if (flowEntry.flowEntryMatch().matchSrcMac()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800516 flowProp.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800517 if (measureONOSFlowEntryTimeProp) {
518 ++numProperties;
519 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700520 }
521 if (flowEntry.flowEntryMatch().matchDstMac()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800522 flowProp.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800523 if (measureONOSFlowEntryTimeProp) {
524 ++numProperties;
525 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700526 }
527 if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800528 flowProp.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800529 if (measureONOSFlowEntryTimeProp) {
530 ++numProperties;
531 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700532 }
533 if (flowEntry.flowEntryMatch().matchVlanId()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800534 flowProp.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800535 if (measureONOSFlowEntryTimeProp) {
536 ++numProperties;
537 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700538 }
539 if (flowEntry.flowEntryMatch().matchVlanPriority()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800540 flowProp.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800541 if (measureONOSFlowEntryTimeProp) {
542 ++numProperties;
543 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700544 }
545 if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800546 flowProp.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800547 if (measureONOSFlowEntryTimeProp) {
548 ++numProperties;
549 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700550 }
551 if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800552 flowProp.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800553 if (measureONOSFlowEntryTimeProp) {
554 ++numProperties;
555 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700556 }
557 if (flowEntry.flowEntryMatch().matchIpProto()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800558 flowProp.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800559 if (measureONOSFlowEntryTimeProp) {
560 ++numProperties;
561 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700562 }
563 if (flowEntry.flowEntryMatch().matchIpToS()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800564 flowProp.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800565 if (measureONOSFlowEntryTimeProp) {
566 ++numProperties;
567 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700568 }
569 if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800570 flowProp.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800571 if (measureONOSFlowEntryTimeProp) {
572 ++numProperties;
573 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700574 }
575 if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800576 flowProp.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800577 if (measureONOSFlowEntryTimeProp) {
578 ++numProperties;
579 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700580 }
581
582 for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
583 if (fa.actionOutput() != null) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800584 if (measureONOSFlowEntryTimeProp) {
585 if ( startSearchOutPort != 0 ) log.error("Performance addFlowEntry(_,{},{}) -- Multiple output port action unexpected.", flowEntry.flowId(), flowEntry.flowEntryId());
586 startSearchOutPort = System.nanoTime();
587 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700588 IPortObject outport =
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800589 dbHandler.searchPort(flowEntry.dpid().toString(),
590 fa.actionOutput().port().value());
591 if (measureONOSFlowEntryTimeProp) {
592 endSearchOutPort = System.nanoTime();
593 }
594
Toshio Koide3f233542014-01-07 14:19:09 -0800595 flowProp.setActionOutputPort(fa.actionOutput().port().value());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800596 if (measureONOSFlowEntryTimeProp) {
597 ++numProperties;
598 }
599
600 if (measureONOSFlowEntryTimeProp) {
601 startAddEdgeToOutPort = System.nanoTime();
602 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700603 flowEntryObj.setOutPort(outport);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800604 if (measureONOSFlowEntryTimeProp) {
605 endAddEdgeToOutPort = System.nanoTime();
606 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700607 }
608 }
609 if (! flowEntry.flowEntryActions().isEmpty()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800610 flowProp.setActions(flowEntry.flowEntryActions().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800611 if (measureONOSFlowEntryTimeProp) {
612 ++numProperties;
613 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700614 }
615
616 // TODO: Hacks with hard-coded state names!
617 if (found)
Toshio Koide3f233542014-01-07 14:19:09 -0800618 flowProp.setUserState("FE_USER_MODIFY");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700619 else
Toshio Koide3f233542014-01-07 14:19:09 -0800620 flowProp.setUserState("FE_USER_ADD");
621 flowProp.setSwitchState(flowEntry.flowEntrySwitchState().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800622 if (measureONOSFlowEntryTimeProp) {
623 numProperties += 2;
624 }
Yuta HIGUCHI8685f9c2014-01-07 15:53:28 -0800625 flowProp.commitProperties();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700626 //
627 // TODO: Take care of the FlowEntryErrorState.
628 //
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800629 if (measureONOSFlowEntryTimeProp) {
630 endSetProperties = System.nanoTime();
631 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700632
633 // Flow Entries edges:
634 // Flow
635 // NextFE (TODO)
636 if (! found) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800637 if (measureONOSFlowEntryTimeProp) {
638 startAddEdgeBetweenFlowPath = System.nanoTime();
639 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700640 flowObj.addFlowEntry(flowEntryObj);
641 flowEntryObj.setFlow(flowObj);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800642 if (measureONOSFlowEntryTimeProp) {
643 endAddEdgeBetweenFlowPath = System.nanoTime();
644 }
645 }
646 if (measureONOSFlowEntryTimeProp) {
647 endAddFlowEntry = System.nanoTime();
648
649 log.error("Performance addFlowEntry(_,{},{}) -- "
650 + "GrandTotal: {} "
651 + "SearchExistingFE: {} "
652 + "CreateNewFE: {} "
653 + "SetProp+Edge: {} #Props: {} "
654 + "SearchSwitch: {} "
655 + "AddEdgeToSwitch: {} "
656 + "SearchInPort: {} "
657 + "AddEdgeToInPort: {} "
658 + "SearchOutPort: {} "
659 + "AddEdgeToOutPort: {} "
660 + "AddEdgeBetweenFlowPath: {} "
661 , flowEntry.flowId(), flowEntry.flowEntryId()
662 , endAddFlowEntry - startAddFlowEntry
663 , endSearchFlowEntry - startAddFlowEntry
664 , endCreateNewFlowEntry - startCreateNewFlowEntry
665 , endSetProperties - startSetProperties, numProperties
666 , endSearchSwitch - startSearchSwitch
667 , endAddEdgeToSwitch - startAddEdgeToSwitch
668 , endSearchInPort - startSearchInPort
669 , endAddEdgeToInPort - startAddEdgeToInPort
670 , endSearchOutPort - startSearchOutPort
671 , endAddEdgeToOutPort - startAddEdgeToOutPort
672 , endAddEdgeBetweenFlowPath - startAddEdgeBetweenFlowPath
673 );
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700674 }
675
676 return flowEntryObj;
677 }
678
679 /**
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700680 * Delete a flow entry from the Network MAP.
681 *
682 * @param dbHandler the Graph Database handler to use.
683 * @param flowObj the corresponding Flow Path object for the Flow Entry.
684 * @param flowEntry the Flow Entry to delete.
685 * @return true on success, otherwise false.
686 */
yoshitomob292c622013-11-23 14:35:58 -0800687 static boolean deleteFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700688 IFlowPath flowObj,
689 FlowEntry flowEntry) {
690 IFlowEntry flowEntryObj = null;
691 try {
692 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
693 } catch (Exception e) {
694 log.error(":deleteFlowEntry FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800695 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700696 return false;
697 }
698 //
699 // TODO: Don't print an error for now, because multiple controller
700 // instances might be deleting the same flow entry.
701 //
702 /*
703 if (flowEntryObj == null) {
704 log.error(":deleteFlowEntry FlowEntryId:{} failed: FlowEntry object not found",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800705 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700706 return false;
707 }
708 */
709 if (flowEntryObj == null)
710 return true;
711
712 flowObj.removeFlowEntry(flowEntryObj);
713 dbHandler.removeFlowEntry(flowEntryObj);
714 return true;
715 }
716
717 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700718 * Delete all previously added flows.
719 *
720 * @param dbHandler the Graph Database handler to use.
721 * @return true on success, otherwise false.
722 */
yoshitomob292c622013-11-23 14:35:58 -0800723 static boolean deleteAllFlows(DBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700724 Iterable<IFlowPath> allFlowPaths = dbHandler.getAllFlowPaths();
725 for (IFlowPath flowPathObj : allFlowPaths) {
726 if (flowPathObj == null)
727 continue;
Yuta HIGUCHI53794052014-01-10 16:49:41 -0800728 deleteIFlowPath(dbHandler, flowPathObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700729 }
Yuta HIGUCHI0cc22372014-01-13 14:54:00 -0800730 dbHandler.commit();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700731
732 return true;
733 }
734
735 /**
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800736 * Delete a previously added flow.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700737 *
738 * @param dbHandler the Graph Database handler to use.
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800739 * @param flowId the Flow ID of the flow to delete.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700740 * @return true on success, otherwise false.
741 */
yoshitomob292c622013-11-23 14:35:58 -0800742 static boolean deleteFlow(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700743 IFlowPath flowObj = null;
744 try {
745 flowObj = dbHandler.searchFlowPath(flowId);
746 } catch (Exception e) {
747 // TODO: handle exceptions
748 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800749 log.error(":deleteFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700750 return false;
751 }
752 if (flowObj == null) {
753 dbHandler.commit();
754 return true; // OK: No such flow
755 }
756
Yuta HIGUCHI53794052014-01-10 16:49:41 -0800757 deleteIFlowPath(dbHandler, flowObj);
Yuta HIGUCHI0cc22372014-01-13 14:54:00 -0800758 dbHandler.commit();
Yuta HIGUCHI53794052014-01-10 16:49:41 -0800759
760 return true;
761 }
762
763 private static void deleteIFlowPath(DBOperation dbHandler, IFlowPath flowObj) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700764 //
765 // Remove all Flow Entries
766 //
767 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
768 for (IFlowEntry flowEntryObj : flowEntries) {
769 flowObj.removeFlowEntry(flowEntryObj);
770 dbHandler.removeFlowEntry(flowEntryObj);
771 }
772 // Remove the Flow itself
773 dbHandler.removeFlowPath(flowObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700774 }
775
776 /**
777 * Get a previously added flow.
778 *
779 * @param dbHandler the Graph Database handler to use.
780 * @param flowId the Flow ID of the flow to get.
781 * @return the Flow Path if found, otherwise null.
782 */
yoshitomob292c622013-11-23 14:35:58 -0800783 static FlowPath getFlow(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700784 IFlowPath flowObj = null;
785 try {
786 flowObj = dbHandler.searchFlowPath(flowId);
787 } catch (Exception e) {
788 // TODO: handle exceptions
789 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800790 log.error(":getFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700791 return null;
792 }
793 if (flowObj == null) {
794 dbHandler.commit();
795 return null; // Flow not found
796 }
797
798 //
799 // Extract the Flow state
800 //
801 FlowPath flowPath = extractFlowPath(flowObj);
802 dbHandler.commit();
803
804 return flowPath;
805 }
806
807 /**
808 * Get all installed flows by all installers.
809 *
810 * @param dbHandler the Graph Database handler to use.
811 * @return the Flow Paths if found, otherwise null.
812 */
yoshitomob292c622013-11-23 14:35:58 -0800813 static ArrayList<FlowPath> getAllFlows(DBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700814 Iterable<IFlowPath> flowPathsObj = null;
815 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
816
817 try {
818 flowPathsObj = dbHandler.getAllFlowPaths();
819 } catch (Exception e) {
820 // TODO: handle exceptions
821 dbHandler.rollback();
822 log.error(":getAllFlowPaths failed");
823 return flowPaths;
824 }
825 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
826 dbHandler.commit();
827 return flowPaths; // No Flows found
828 }
829
830 for (IFlowPath flowObj : flowPathsObj) {
831 //
832 // Extract the Flow state
833 //
834 FlowPath flowPath = extractFlowPath(flowObj);
835 if (flowPath != null)
836 flowPaths.add(flowPath);
837 }
838
839 dbHandler.commit();
840
841 return flowPaths;
842 }
843
844 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700845 * Extract Flow Path State from a Titan Database Object @ref IFlowPath.
846 *
847 * @param flowObj the object to extract the Flow Path State from.
848 * @return the extracted Flow Path State.
849 */
850 private static FlowPath extractFlowPath(IFlowPath flowObj) {
851 //
852 // Extract the Flow state
853 //
Toshio Koidea9b25142014-01-10 01:15:57 -0800854 log.info("extractFlowPath: start");
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -0800855 String flowIdStr;
856 String installerIdStr;
857 String flowPathType;
858 String flowPathUserState;
859 Long flowPathFlags;
860 Integer idleTimeout;
861 Integer hardTimeout;
862 String srcSwitchStr;
863 Short srcPortShort;
864 String dstSwitchStr;
865 Short dstPortShort;
866
867 if ( flowObj.asVertex() instanceof RamCloudVertex ) {
868 RamCloudVertex v = (RamCloudVertex)flowObj.asVertex();
869 Map<String,Object> propMap = v.getProperties();
870
871 flowIdStr = (String) propMap.get("flow_id");
872 installerIdStr = (String) propMap.get("installer_id");
873 flowPathType = (String) propMap.get("flow_path_type");
874 flowPathUserState = (String) propMap.get("user_state");
875 flowPathFlags = (Long)propMap.get("flow_path_flags");
876 idleTimeout = (Integer) propMap.get("idle_timeout");
877 hardTimeout = (Integer) propMap.get("hard_timeout");
878 srcSwitchStr = (String) propMap.get("src_switch");
879 srcPortShort = (Short)propMap.get("src_port");
880 dstSwitchStr = (String) propMap.get("dst_switch");
881 dstPortShort = (Short)propMap.get("dst_port");
882 } else {
883 flowIdStr = flowObj.getFlowId();
884 installerIdStr = flowObj.getInstallerId();
885 flowPathType = flowObj.getFlowPathType();
886 flowPathUserState = flowObj.getFlowPathUserState();
887 flowPathFlags = flowObj.getFlowPathFlags();
888 idleTimeout = flowObj.getIdleTimeout();
889 hardTimeout = flowObj.getHardTimeout();
890 srcSwitchStr = flowObj.getSrcSwitch();
891 srcPortShort = flowObj.getSrcPort();
892 dstSwitchStr = flowObj.getDstSwitch();
893 dstPortShort = flowObj.getDstPort();
894 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700895
896 if ((flowIdStr == null) ||
897 (installerIdStr == null) ||
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700898 (flowPathType == null) ||
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700899 (flowPathUserState == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700900 (flowPathFlags == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800901 (idleTimeout == null) ||
902 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700903 (srcSwitchStr == null) ||
904 (srcPortShort == null) ||
905 (dstSwitchStr == null) ||
906 (dstPortShort == null)) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800907 // TODO: A work-around, because of some bogus database objects
908 log.error("extractFlowPath: wrong properties");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700909 return null;
910 }
911
912 FlowPath flowPath = new FlowPath();
913 flowPath.setFlowId(new FlowId(flowIdStr));
914 flowPath.setInstallerId(new CallerId(installerIdStr));
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700915 flowPath.setFlowPathType(FlowPathType.valueOf(flowPathType));
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700916 flowPath.setFlowPathUserState(FlowPathUserState.valueOf(flowPathUserState));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700917 flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800918 flowPath.setIdleTimeout(idleTimeout);
919 flowPath.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700920 flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
921 flowPath.dataPath().srcPort().setPort(new Port(srcPortShort));
922 flowPath.dataPath().dstPort().setDpid(new Dpid(dstSwitchStr));
923 flowPath.dataPath().dstPort().setPort(new Port(dstPortShort));
924 //
925 // Extract the match conditions common for all Flow Entries
926 //
927 {
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -0800928 FlowEntryMatch match = extractMatch(flowObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700929
930 flowPath.setFlowEntryMatch(match);
931 }
932 //
933 // Extract the actions for the first Flow Entry
934 //
935 {
936 String actionsStr = flowObj.getActions();
937 if (actionsStr != null) {
938 FlowEntryActions flowEntryActions = new FlowEntryActions(actionsStr);
939 flowPath.setFlowEntryActions(flowEntryActions);
940 }
941 }
942
943 //
944 // Extract all Flow Entries
945 //
946 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
947 for (IFlowEntry flowEntryObj : flowEntries) {
948 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
949 if (flowEntry == null)
950 continue;
951 flowPath.dataPath().flowEntries().add(flowEntry);
952 }
953
Toshio Koidea9b25142014-01-10 01:15:57 -0800954 log.info("extractFlowPath: end");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700955 return flowPath;
956 }
957
958 /**
959 * Extract Flow Entry State from a Titan Database Object @ref IFlowEntry.
960 *
961 * @param flowEntryObj the object to extract the Flow Entry State from.
962 * @return the extracted Flow Entry State.
963 */
Brian O'Connora8e49802013-10-30 20:49:59 -0700964 public static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800965 log.info("extractFlowEntry: start");
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800966 IFlowPath flowObj = flowEntryObj.getFlow();
Toshio Koidea9b25142014-01-10 01:15:57 -0800967 if (flowObj == null) {
968 log.error("extractFlowEntry: no flowPath exists");
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800969 return null;
Toshio Koidea9b25142014-01-10 01:15:57 -0800970 }
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800971
972 String flowIdStr = flowObj.getFlowId();
973 //
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -0800974 String flowEntryIdStr;
975 Integer idleTimeout;
976 Integer hardTimeout;
977 String switchDpidStr;
978 String userState;
979 String switchState;
980 if ( flowEntryObj.asVertex() instanceof RamCloudVertex ) {
981 RamCloudVertex v = (RamCloudVertex)flowEntryObj.asVertex();
982 Map<String,Object> propMap = v.getProperties();
983
984 flowEntryIdStr = (String) propMap.get("flow_entry_id");
985 idleTimeout = (Integer) propMap.get("idle_timeout");
986 hardTimeout = (Integer) propMap.get("hard_timeout");
987 switchDpidStr = (String) propMap.get("switch_dpid");
988 userState = (String) propMap.get("user_state");
989 switchState = (String) propMap.get("switch_state");
990 } else {
991 flowEntryIdStr = flowEntryObj.getFlowEntryId();
992 idleTimeout = flowEntryObj.getIdleTimeout();
993 hardTimeout = flowEntryObj.getHardTimeout();
994 switchDpidStr = flowEntryObj.getSwitchDpid();
995 userState = flowEntryObj.getUserState();
996 switchState = flowEntryObj.getSwitchState();
997 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700998
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800999 if ((flowIdStr == null) ||
1000 (flowEntryIdStr == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -08001001 (idleTimeout == null) ||
1002 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001003 (switchDpidStr == null) ||
1004 (userState == null) ||
1005 (switchState == null)) {
Brian O'Connora8e49802013-10-30 20:49:59 -07001006 // TODO: A work-around, because of some bogus database objects
Toshio Koidea9b25142014-01-10 01:15:57 -08001007 log.error("extractFlowEntry: wrong properties");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001008 return null;
1009 }
1010
1011 FlowEntry flowEntry = new FlowEntry();
1012 flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001013 flowEntry.setFlowId(new FlowId(flowIdStr));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001014 flowEntry.setDpid(new Dpid(switchDpidStr));
yoshia97632b2013-12-17 15:46:08 -08001015 flowEntry.setIdleTimeout(idleTimeout);
1016 flowEntry.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001017
1018 //
1019 // Extract the match conditions
1020 //
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001021 FlowEntryMatch match = extractMatch(flowEntryObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001022 flowEntry.setFlowEntryMatch(match);
1023
1024 //
1025 // Extract the actions
1026 //
1027 FlowEntryActions actions = new FlowEntryActions();
1028 String actionsStr = flowEntryObj.getActions();
1029 if (actionsStr != null)
1030 actions = new FlowEntryActions(actionsStr);
1031 flowEntry.setFlowEntryActions(actions);
1032 flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
1033 flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
1034 //
1035 // TODO: Take care of FlowEntryErrorState.
1036 //
Toshio Koidea9b25142014-01-10 01:15:57 -08001037 log.info("extractFlowEntry: end");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001038 return flowEntry;
1039 }
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001040
1041 /**
1042 * Extract FlowEntryMatch from IFlowPath or IFlowEntry
1043 * @param flowObj : either IFlowPath or IFlowEntry
1044 * @return extracted Match info
1045 */
1046 private static FlowEntryMatch extractMatch(IBaseObject flowObj) {
1047 FlowEntryMatch match = new FlowEntryMatch();
1048
1049 Short matchInPort = null; // Only for IFlowEntry
1050 String matchSrcMac = null;
1051 String matchDstMac = null;
1052 Short matchEthernetFrameType = null;
1053 Short matchVlanId = null;
1054 Byte matchVlanPriority = null;
1055 String matchSrcIPv4Net = null;
1056 String matchDstIPv4Net = null;
1057 Byte matchIpProto = null;
1058 Byte matchIpToS = null;
1059 Short matchSrcTcpUdpPort = null;
1060 Short matchDstTcpUdpPort = null;
1061
1062 if ( flowObj.asVertex() instanceof RamCloudVertex ) {
1063 RamCloudVertex v = (RamCloudVertex)flowObj.asVertex();
1064 Map<String,Object> propMap = v.getProperties();
1065 matchInPort = (Short) propMap.get("matchInPort");
1066 matchSrcMac = (String) propMap.get("matchSrcMac");
1067 matchDstMac = (String) propMap.get("matchDstMac");
1068 matchEthernetFrameType = (Short) propMap.get("matchEthernetFrameType");
1069 matchVlanId = (Short) propMap.get("matchVlanId");
1070 matchVlanPriority = (Byte) propMap.get("matchVlanPriority");
1071 matchSrcIPv4Net = (String) propMap.get("matchSrcIPv4Net");
1072 matchDstIPv4Net = (String) propMap.get("matchDstIPv4Net");
1073 matchIpProto = (Byte) propMap.get("matchIpProto");
1074 matchIpToS = (Byte) propMap.get("matchIpToS");
1075 matchSrcTcpUdpPort = (Short) propMap.get("matchSrcTcpUdpPort");
1076 matchDstTcpUdpPort = (Short) propMap.get("matchDstTcpUdpPort");
1077 } else {
1078 if (flowObj instanceof IFlowEntry ){
1079 IFlowEntry flowEntry = (IFlowEntry) flowObj;
1080 matchInPort = flowEntry.getMatchInPort();
1081 matchSrcMac = flowEntry.getMatchSrcMac();
1082 matchDstMac = flowEntry.getMatchDstMac();
1083 matchEthernetFrameType = flowEntry.getMatchEthernetFrameType();
1084 matchVlanId = flowEntry.getMatchVlanId();
1085 matchVlanPriority = flowEntry.getMatchVlanPriority();
1086 matchSrcIPv4Net = flowEntry.getMatchSrcIPv4Net();
1087 matchDstIPv4Net = flowEntry.getMatchDstIPv4Net();
1088 matchIpProto = flowEntry.getMatchIpProto();
1089 matchIpToS = flowEntry.getMatchIpToS();
1090 matchSrcTcpUdpPort = flowEntry.getMatchSrcTcpUdpPort();
1091 matchDstTcpUdpPort = flowEntry.getMatchDstTcpUdpPort();
1092 } else if(flowObj instanceof IFlowPath) {
1093 IFlowPath flowPath = (IFlowPath) flowObj;
1094 matchSrcMac = flowPath.getMatchSrcMac();
1095 matchDstMac = flowPath.getMatchDstMac();
1096 matchEthernetFrameType = flowPath.getMatchEthernetFrameType();
1097 matchVlanId = flowPath.getMatchVlanId();
1098 matchVlanPriority = flowPath.getMatchVlanPriority();
1099 matchSrcIPv4Net = flowPath.getMatchSrcIPv4Net();
1100 matchDstIPv4Net = flowPath.getMatchDstIPv4Net();
1101 matchIpProto = flowPath.getMatchIpProto();
1102 matchIpToS = flowPath.getMatchIpToS();
1103 matchSrcTcpUdpPort = flowPath.getMatchSrcTcpUdpPort();
1104 matchDstTcpUdpPort = flowPath.getMatchDstTcpUdpPort();
1105 }
1106 }
1107
1108 if (matchInPort != null)
1109 match.enableInPort(new Port(matchInPort));
1110 if (matchSrcMac != null)
1111 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
1112 if (matchDstMac != null)
1113 match.enableDstMac(MACAddress.valueOf(matchDstMac));
1114 if (matchEthernetFrameType != null)
1115 match.enableEthernetFrameType(matchEthernetFrameType);
1116 if (matchVlanId != null)
1117 match.enableVlanId(matchVlanId);
1118 if (matchVlanPriority != null)
1119 match.enableVlanPriority(matchVlanPriority);
1120 if (matchSrcIPv4Net != null)
1121 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
1122 if (matchDstIPv4Net != null)
1123 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
1124 if (matchIpProto != null)
1125 match.enableIpProto(matchIpProto);
1126 if (matchIpToS != null)
1127 match.enableIpToS(matchIpToS);
1128 if (matchSrcTcpUdpPort != null)
1129 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
1130 if (matchDstTcpUdpPort != null)
1131 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
1132 return match;
1133 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001134}