blob: 2f42475e63fc2a052beaa23f4988223cdb362e32 [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;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07007import net.floodlightcontroller.util.MACAddress;
yoshitomob292c622013-11-23 14:35:58 -08008import net.onrc.onos.graph.DBOperation;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07009import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
10import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
11import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
12import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
13import net.onrc.onos.ofcontroller.util.*;
14
15import org.slf4j.Logger;
16import org.slf4j.LoggerFactory;
17
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -080018import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
19
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070020/**
21 * Class for performing Flow-related operations on the Database.
22 */
Pavlin Radoslavov6bfaea62013-12-03 14:55:57 -080023public class FlowDatabaseOperation {
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070024 private final static Logger log = LoggerFactory.getLogger(FlowDatabaseOperation.class);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -080025 private static final boolean measureONOSFlowTimeProp = Long.valueOf(System.getProperty("benchmark.measureONOSFlow", "0")) != 0;
26 private static final boolean measureONOSFlowEntryTimeProp = Long.valueOf(System.getProperty("benchmark.measureONOSFlowEntry", "0")) != 0;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070027
28 /**
29 * Add a flow.
30 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070031 * @param dbHandler the Graph Database handler to use.
32 * @param flowPath the Flow Path to install.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070033 * @return true on success, otherwise false.
34 */
onlab-qa38805cd2013-12-06 20:08:54 -080035 static boolean addFlow(DBOperation dbHandler, FlowPath flowPath) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070036 IFlowPath flowObj = null;
37 boolean found = false;
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080038 long startAddFlow = 0;
39 long endAddFlow = 0;
40 long endSearchExistingFlowPathTime = 0;
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -080041 long startCreateNewFlowPathTime = 0;
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080042 long endCreateNewFlowPathTime = 0;
43 long startFollowExistingFlowEntries = 0;
44 long endFollowExistingFlowEntries = 0;
45 long accTimeRemovingFlowEntriesFromFlowPath = 0;
46 long accTimeRemovingFlowEntriesFromDB = 0;
47 long startSettingFlowPathProps = 0;
48 long endSettingFlowPathProps = 0;
49 int numPropsSet = 0;
50 long accTimeAddFlowEntries = 0;
51 int numNewFlowEntries = 0;
52 LinkedList<long[]> flowEntryTimes = new LinkedList<>();
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -080053 PerfMon pm = PerfMon.getInstance();
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080054
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -080055 pm.addflowpath_start();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070056 try {
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080057 if ( measureONOSFlowTimeProp ) {
58 startAddFlow = System.nanoTime();
59 }
yoshi40210942013-12-03 08:21:02 -080060 flowObj = dbHandler.searchFlowPath(flowPath.flowId());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080061 if ( measureONOSFlowTimeProp ) {
62 endSearchExistingFlowPathTime = System.nanoTime();
63 }
yoshi40210942013-12-03 08:21:02 -080064 if (flowObj != null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070065 found = true;
66 } else {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -080067 if ( measureONOSFlowTimeProp ) {
68 startCreateNewFlowPathTime = System.nanoTime();
69 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070070 flowObj = dbHandler.newFlowPath();
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080071 if ( measureONOSFlowTimeProp ) {
72 endCreateNewFlowPathTime = System.nanoTime();
73 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070074 }
75 } catch (Exception e) {
76 dbHandler.rollback();
77
78 StringWriter sw = new StringWriter();
79 e.printStackTrace(new PrintWriter(sw));
80 String stacktrace = sw.toString();
81
82 log.error(":addFlow FlowId:{} failed: {}",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -080083 flowPath.flowId(),
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070084 stacktrace);
85 return false;
86 }
87 if (flowObj == null) {
88 log.error(":addFlow FlowId:{} failed: Flow object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -080089 flowPath.flowId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070090 dbHandler.rollback();
91 return false;
92 }
93
94 //
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -080095 // Remove the old Flow Entries
96 //
97 if (found) {
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080098 if ( measureONOSFlowTimeProp ) {
99 startFollowExistingFlowEntries = System.nanoTime();
100 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800101 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800102 if ( measureONOSFlowTimeProp ) {
103 endFollowExistingFlowEntries = System.nanoTime();
104 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800105 LinkedList<IFlowEntry> deleteFlowEntries =
106 new LinkedList<IFlowEntry>();
107 for (IFlowEntry flowEntryObj : flowEntries)
108 deleteFlowEntries.add(flowEntryObj);
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800109 if( measureONOSFlowTimeProp ) {
110 for (IFlowEntry flowEntryObj : deleteFlowEntries) {
111 long start = System.nanoTime();
112 flowObj.removeFlowEntry(flowEntryObj);
113 accTimeRemovingFlowEntriesFromFlowPath += System.nanoTime() - start;
114 start = System.nanoTime();
115 dbHandler.removeFlowEntry(flowEntryObj);
116 accTimeRemovingFlowEntriesFromDB += System.nanoTime() - start;
117 }
118 } else {
119 for (IFlowEntry flowEntryObj : deleteFlowEntries) {
120 flowObj.removeFlowEntry(flowEntryObj);
121 dbHandler.removeFlowEntry(flowEntryObj);
122 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800123 }
124 }
125
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800126 if ( measureONOSFlowTimeProp ) {
127 startSettingFlowPathProps = System.nanoTime();
128 }
Toshio Koidea9b25142014-01-10 01:15:57 -0800129
130 FlowPathProperty flowProp = new FlowPathProperty(dbHandler, flowObj);
131
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800132 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700133 // Set the Flow key:
134 // - flowId
135 //
Toshio Koidea9b25142014-01-10 01:15:57 -0800136 flowProp.setFlowId(flowPath.flowId().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800137 if ( measureONOSFlowTimeProp ) {
138 numPropsSet += 2;
139 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700140
141 //
142 // Set the Flow attributes:
143 // - flowPath.installerId()
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700144 // - flowPath.flowPathType()
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700145 // - flowPath.flowPathUserState()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700146 // - flowPath.flowPathFlags()
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800147 // - flowPath.idleTimeout()
148 // - flowPath.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700149 // - flowPath.dataPath().srcPort()
150 // - flowPath.dataPath().dstPort()
151 // - flowPath.matchSrcMac()
152 // - flowPath.matchDstMac()
153 // - flowPath.matchEthernetFrameType()
154 // - flowPath.matchVlanId()
155 // - flowPath.matchVlanPriority()
156 // - flowPath.matchSrcIPv4Net()
157 // - flowPath.matchDstIPv4Net()
158 // - flowPath.matchIpProto()
159 // - flowPath.matchIpToS()
160 // - flowPath.matchSrcTcpUdpPort()
161 // - flowPath.matchDstTcpUdpPort()
162 // - flowPath.flowEntryActions()
163 //
Toshio Koidea9b25142014-01-10 01:15:57 -0800164 flowProp.setInstallerId(flowPath.installerId().toString());
165 flowProp.setFlowPathType(flowPath.flowPathType().toString());
166 flowProp.setFlowPathUserState(flowPath.flowPathUserState().toString());
167 flowProp.setFlowPathFlags(flowPath.flowPathFlags().flags());
168 flowProp.setIdleTimeout(flowPath.idleTimeout());
169 flowProp.setHardTimeout(flowPath.hardTimeout());
170 flowProp.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
171 flowProp.setSrcPort(flowPath.dataPath().srcPort().port().value());
172 flowProp.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
173 flowProp.setDstPort(flowPath.dataPath().dstPort().port().value());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800174 if ( measureONOSFlowTimeProp ) {
175 numPropsSet += 10;
176 }
177
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700178 if (flowPath.flowEntryMatch().matchSrcMac()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800179 flowProp.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800180 if ( measureONOSFlowTimeProp ) {
181 ++numPropsSet;
182 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700183 }
184 if (flowPath.flowEntryMatch().matchDstMac()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800185 flowProp.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800186 if ( measureONOSFlowTimeProp ) {
187 ++numPropsSet;
188 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700189 }
190 if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800191 flowProp.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800192 if ( measureONOSFlowTimeProp ) {
193 ++numPropsSet;
194 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700195 }
196 if (flowPath.flowEntryMatch().matchVlanId()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800197 flowProp.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800198 if ( measureONOSFlowTimeProp ) {
199 ++numPropsSet;
200 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700201 }
202 if (flowPath.flowEntryMatch().matchVlanPriority()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800203 flowProp.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800204 if ( measureONOSFlowTimeProp ) {
205 ++numPropsSet;
206 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700207 }
208 if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800209 flowProp.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800210 if ( measureONOSFlowTimeProp ) {
211 ++numPropsSet;
212 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700213 }
214 if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800215 flowProp.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800216 if ( measureONOSFlowTimeProp ) {
217 ++numPropsSet;
218 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700219 }
220 if (flowPath.flowEntryMatch().matchIpProto()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800221 flowProp.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800222 if ( measureONOSFlowTimeProp ) {
223 ++numPropsSet;
224 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700225 }
226 if (flowPath.flowEntryMatch().matchIpToS()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800227 flowProp.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800228 if ( measureONOSFlowTimeProp ) {
229 ++numPropsSet;
230 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700231 }
232 if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800233 flowProp.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800234 if ( measureONOSFlowTimeProp ) {
235 ++numPropsSet;
236 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700237 }
238 if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800239 flowProp.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800240 if ( measureONOSFlowTimeProp ) {
241 ++numPropsSet;
242 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700243 }
244 if (! flowPath.flowEntryActions().actions().isEmpty()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800245 flowProp.setActions(flowPath.flowEntryActions().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800246 if ( measureONOSFlowTimeProp ) {
247 ++numPropsSet;
248 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700249 }
Toshio Koidea9b25142014-01-10 01:15:57 -0800250 flowProp.setDataPathSummary(flowPath.dataPath().dataPathSummary());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800251 if ( measureONOSFlowTimeProp ) {
252 ++numPropsSet;
253 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700254
255 if (found)
Toshio Koidea9b25142014-01-10 01:15:57 -0800256 flowProp.setFlowPathUserState("FP_USER_MODIFY");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700257 else
Toshio Koidea9b25142014-01-10 01:15:57 -0800258 flowProp.setFlowPathUserState("FP_USER_ADD");
259
260 flowProp.commitProperties();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700261
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800262 if ( measureONOSFlowTimeProp ) {
263 ++numPropsSet;
264 }
265
266 if ( measureONOSFlowTimeProp ) {
267 endSettingFlowPathProps = System.nanoTime();
268 }
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800269 pm.addflowpath_end();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700270 // Flow edges:
271 // HeadFE
272
273
274 //
275 // Flow Entries:
276 // flowPath.dataPath().flowEntries()
277 //
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800278 pm.addflowentry_start();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700279 for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800280 if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE)
281 continue; // Skip: all Flow Entries were deleted earlier
282
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800283 pm.addflowentry_incr();
284
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800285 long startAddFlowEntry = 0, endAddFlowEntry;
286 if( measureONOSFlowTimeProp ) {
287 startAddFlowEntry = System.nanoTime();
288 }
289 IFlowEntry iFlowEntry = addFlowEntry(dbHandler, flowObj, flowEntry);
290 if( measureONOSFlowTimeProp ) {
291 endAddFlowEntry = System.nanoTime();
292 accTimeAddFlowEntries += endAddFlowEntry - startAddFlowEntry;
293
294 flowEntryTimes.addLast( new long[]{flowEntry.flowId().value(), endAddFlowEntry - startAddFlowEntry} );
295 }
296 if ( iFlowEntry == null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700297 dbHandler.rollback();
298 return false;
299 }
300 }
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800301 pm.addflowentry_end();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700302 dbHandler.commit();
303
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800304
305 if ( measureONOSFlowTimeProp ) {
306 endAddFlow = System.nanoTime();
307
Yuta HIGUCHI0b4fbaf2014-01-04 22:23:05 -0800308 log.error("Performance addFlow(_,{}) -- "
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800309 + "GrandTotal: {} "
310 + "only FlowPathTotal: {} "
311 + "searchExistingFlowPath: {} "
312 + "createNewFlowPathTime: {}"
313 + "followExistingFlowEntries: {} "
314 + "accTimeRemovingFlowEntriesFromFlowPath: {} "
315 + "accTimeRemovingFlowEntriesFromDB: {} "
316 + "settingFlowPathProps: {} #Props: {} "
317 + "accFlowEntries: {} #FEs: {}",
318 flowPath.flowId(),
319 (endAddFlow - startAddFlow),
320 (endSettingFlowPathProps - startAddFlow),
321 (endSearchExistingFlowPathTime - startAddFlow),
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800322 (endCreateNewFlowPathTime - startCreateNewFlowPathTime),
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800323 (endFollowExistingFlowEntries - startFollowExistingFlowEntries),
324 (accTimeRemovingFlowEntriesFromFlowPath),
325 (accTimeRemovingFlowEntriesFromDB),
326 (endSettingFlowPathProps - startSettingFlowPathProps), numPropsSet,
327 accTimeAddFlowEntries, numNewFlowEntries
328 );
329
330 // Each FlowEntries
331 final String strFlowId = flowPath.flowId().toString();
332 for ( long[] idFE_Time : flowEntryTimes ) {
Yuta HIGUCHI0b4fbaf2014-01-04 22:23:05 -0800333 log.error("Performance addFlowEntry(_,{},{})@addFlow -- FlowEntryTotal: {}",
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800334 strFlowId,
335 "0x" + Long.toHexString(idFE_Time[0]),
336 idFE_Time[1]);
337 }
338 }
339
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700340 return true;
341 }
342
343 /**
344 * Add a flow entry to the Network MAP.
345 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700346 * @param dbHandler the Graph Database handler to use.
347 * @param flowObj the corresponding Flow Path object for the Flow Entry.
348 * @param flowEntry the Flow Entry to install.
349 * @return the added Flow Entry object on success, otherwise null.
350 */
onlab-qa38805cd2013-12-06 20:08:54 -0800351 static IFlowEntry addFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700352 IFlowPath flowObj,
353 FlowEntry flowEntry) {
354 // Flow edges
355 // HeadFE (TODO)
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800356 long startAddFlowEntry = 0;
357 long endAddFlowEntry = 0;
358
359 long endSearchFlowEntry = 0;
360
361 long startCreateNewFlowEntry = 0;
362 long endCreateNewFlowEntry = 0;
363
364 long startSetProperties = 0;
365 long endSetProperties = 0;
366 int numProperties = 0;
367
368 long startSearchSwitch = 0;
369 long endSearchSwitch = 0;
370
371 long startAddEdgeToSwitch =0;
372 long endAddEdgeToSwitch =0;
373
374 long startSearchInPort = 0;
375 long endSearchInPort = 0;
376
377 long startAddEdgeToInPort =0;
378 long endAddEdgeToInPort =0;
379
380 long startSearchOutPort = 0;
381 long endSearchOutPort = 0;
382
383 long startAddEdgeToOutPort =0;
384 long endAddEdgeToOutPort =0;
385
386 long startAddEdgeBetweenFlowPath = 0;
387 long endAddEdgeBetweenFlowPath = 0;
388
389 if (measureONOSFlowEntryTimeProp) {
390 startAddFlowEntry = System.nanoTime();
391 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700392
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700393 IFlowEntry flowEntryObj = null;
394 boolean found = false;
395 try {
Yuta HIGUCHIc27a6c92014-01-07 11:51:11 -0800396 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
397 if (measureONOSFlowEntryTimeProp) {
398 endSearchFlowEntry = System.nanoTime();
399 }
400 if (flowEntryObj != null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700401 found = true;
402 } else {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800403 if (measureONOSFlowEntryTimeProp) {
404 startCreateNewFlowEntry = System.nanoTime();
405 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700406 flowEntryObj = dbHandler.newFlowEntry();
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800407 if (measureONOSFlowEntryTimeProp) {
408 endCreateNewFlowEntry = System.nanoTime();
409 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700410 }
411 } catch (Exception e) {
412 log.error(":addFlow FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800413 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700414 return null;
415 }
416 if (flowEntryObj == null) {
417 log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800418 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700419 return null;
420 }
421
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800422 if (measureONOSFlowEntryTimeProp) {
423 startSetProperties = System.nanoTime();
424 }
Yuta HIGUCHI8685f9c2014-01-07 15:53:28 -0800425
Toshio Koide7f76e9e2014-01-09 22:06:35 -0800426 FlowEntryProperty flowProp = new FlowEntryProperty(dbHandler, flowEntryObj);
Yuta HIGUCHI8685f9c2014-01-07 15:53:28 -0800427
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700428 //
429 // Set the Flow Entry key:
430 // - flowEntry.flowEntryId()
431 //
Toshio Koide3f233542014-01-07 14:19:09 -0800432 flowProp.setFlowEntryId(flowEntry.flowEntryId().toString());
433 flowProp.setType("flow_entry");
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800434 if (measureONOSFlowEntryTimeProp) {
435 numProperties += 2;
436 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700437
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800438 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700439 // Set the Flow Entry Edges and attributes:
440 // - Switch edge
441 // - InPort edge
442 // - OutPort edge
443 //
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800444 // - flowEntry.idleTimeout()
445 // - flowEntry.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700446 // - flowEntry.dpid()
447 // - flowEntry.flowEntryUserState()
448 // - flowEntry.flowEntrySwitchState()
449 // - flowEntry.flowEntryErrorState()
450 // - flowEntry.matchInPort()
451 // - flowEntry.matchSrcMac()
452 // - flowEntry.matchDstMac()
453 // - flowEntry.matchEthernetFrameType()
454 // - flowEntry.matchVlanId()
455 // - flowEntry.matchVlanPriority()
456 // - flowEntry.matchSrcIPv4Net()
457 // - flowEntry.matchDstIPv4Net()
458 // - flowEntry.matchIpProto()
459 // - flowEntry.matchIpToS()
460 // - flowEntry.matchSrcTcpUdpPort()
461 // - flowEntry.matchDstTcpUdpPort()
462 // - flowEntry.actionOutputPort()
463 // - flowEntry.actions()
464 //
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800465 if (measureONOSFlowEntryTimeProp) {
466 startSearchSwitch = System.nanoTime();
467 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700468 ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800469 if (measureONOSFlowEntryTimeProp) {
470 endSearchSwitch = System.nanoTime();
471 }
472
Toshio Koide3f233542014-01-07 14:19:09 -0800473 flowProp.setIdleTimeout(flowEntry.idleTimeout());
474 flowProp.setHardTimeout(flowEntry.hardTimeout());
475 flowProp.setSwitchDpid(flowEntry.dpid().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800476 if (measureONOSFlowEntryTimeProp) {
477 numProperties += 3;
478 }
479
480 if (measureONOSFlowEntryTimeProp) {
481 startAddEdgeToSwitch = System.nanoTime();
482 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700483 flowEntryObj.setSwitch(sw);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800484 if (measureONOSFlowEntryTimeProp) {
485 endAddEdgeToSwitch = System.nanoTime();
486 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700487 if (flowEntry.flowEntryMatch().matchInPort()) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800488 if (measureONOSFlowEntryTimeProp) {
489 startSearchInPort = System.nanoTime();
490 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700491 IPortObject inport =
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800492 dbHandler.searchPort(flowEntry.dpid().toString(),
493 flowEntry.flowEntryMatch().inPort().value());
494 if (measureONOSFlowEntryTimeProp) {
495 endSearchInPort = System.nanoTime();
496 }
497
Toshio Koide3f233542014-01-07 14:19:09 -0800498 flowProp.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800499 if (measureONOSFlowEntryTimeProp) {
500 ++numProperties;
501 }
502
503 if (measureONOSFlowEntryTimeProp) {
504 startAddEdgeToInPort = System.nanoTime();
505 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700506 flowEntryObj.setInPort(inport);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800507 if (measureONOSFlowEntryTimeProp) {
508 endAddEdgeToInPort = System.nanoTime();
509 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700510 }
511 if (flowEntry.flowEntryMatch().matchSrcMac()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800512 flowProp.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800513 if (measureONOSFlowEntryTimeProp) {
514 ++numProperties;
515 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700516 }
517 if (flowEntry.flowEntryMatch().matchDstMac()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800518 flowProp.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800519 if (measureONOSFlowEntryTimeProp) {
520 ++numProperties;
521 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700522 }
523 if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800524 flowProp.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800525 if (measureONOSFlowEntryTimeProp) {
526 ++numProperties;
527 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700528 }
529 if (flowEntry.flowEntryMatch().matchVlanId()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800530 flowProp.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800531 if (measureONOSFlowEntryTimeProp) {
532 ++numProperties;
533 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700534 }
535 if (flowEntry.flowEntryMatch().matchVlanPriority()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800536 flowProp.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800537 if (measureONOSFlowEntryTimeProp) {
538 ++numProperties;
539 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700540 }
541 if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800542 flowProp.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800543 if (measureONOSFlowEntryTimeProp) {
544 ++numProperties;
545 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700546 }
547 if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800548 flowProp.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800549 if (measureONOSFlowEntryTimeProp) {
550 ++numProperties;
551 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700552 }
553 if (flowEntry.flowEntryMatch().matchIpProto()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800554 flowProp.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800555 if (measureONOSFlowEntryTimeProp) {
556 ++numProperties;
557 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700558 }
559 if (flowEntry.flowEntryMatch().matchIpToS()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800560 flowProp.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800561 if (measureONOSFlowEntryTimeProp) {
562 ++numProperties;
563 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700564 }
565 if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800566 flowProp.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800567 if (measureONOSFlowEntryTimeProp) {
568 ++numProperties;
569 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700570 }
571 if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800572 flowProp.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800573 if (measureONOSFlowEntryTimeProp) {
574 ++numProperties;
575 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700576 }
577
578 for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
579 if (fa.actionOutput() != null) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800580 if (measureONOSFlowEntryTimeProp) {
581 if ( startSearchOutPort != 0 ) log.error("Performance addFlowEntry(_,{},{}) -- Multiple output port action unexpected.", flowEntry.flowId(), flowEntry.flowEntryId());
582 startSearchOutPort = System.nanoTime();
583 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700584 IPortObject outport =
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800585 dbHandler.searchPort(flowEntry.dpid().toString(),
586 fa.actionOutput().port().value());
587 if (measureONOSFlowEntryTimeProp) {
588 endSearchOutPort = System.nanoTime();
589 }
590
Toshio Koide3f233542014-01-07 14:19:09 -0800591 flowProp.setActionOutputPort(fa.actionOutput().port().value());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800592 if (measureONOSFlowEntryTimeProp) {
593 ++numProperties;
594 }
595
596 if (measureONOSFlowEntryTimeProp) {
597 startAddEdgeToOutPort = System.nanoTime();
598 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700599 flowEntryObj.setOutPort(outport);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800600 if (measureONOSFlowEntryTimeProp) {
601 endAddEdgeToOutPort = System.nanoTime();
602 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700603 }
604 }
605 if (! flowEntry.flowEntryActions().isEmpty()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800606 flowProp.setActions(flowEntry.flowEntryActions().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800607 if (measureONOSFlowEntryTimeProp) {
608 ++numProperties;
609 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700610 }
611
612 // TODO: Hacks with hard-coded state names!
613 if (found)
Toshio Koide3f233542014-01-07 14:19:09 -0800614 flowProp.setUserState("FE_USER_MODIFY");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700615 else
Toshio Koide3f233542014-01-07 14:19:09 -0800616 flowProp.setUserState("FE_USER_ADD");
617 flowProp.setSwitchState(flowEntry.flowEntrySwitchState().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800618 if (measureONOSFlowEntryTimeProp) {
619 numProperties += 2;
620 }
Yuta HIGUCHI8685f9c2014-01-07 15:53:28 -0800621 flowProp.commitProperties();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700622 //
623 // TODO: Take care of the FlowEntryErrorState.
624 //
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800625 if (measureONOSFlowEntryTimeProp) {
626 endSetProperties = System.nanoTime();
627 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700628
629 // Flow Entries edges:
630 // Flow
631 // NextFE (TODO)
632 if (! found) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800633 if (measureONOSFlowEntryTimeProp) {
634 startAddEdgeBetweenFlowPath = System.nanoTime();
635 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700636 flowObj.addFlowEntry(flowEntryObj);
637 flowEntryObj.setFlow(flowObj);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800638 if (measureONOSFlowEntryTimeProp) {
639 endAddEdgeBetweenFlowPath = System.nanoTime();
640 }
641 }
642 if (measureONOSFlowEntryTimeProp) {
643 endAddFlowEntry = System.nanoTime();
644
645 log.error("Performance addFlowEntry(_,{},{}) -- "
646 + "GrandTotal: {} "
647 + "SearchExistingFE: {} "
648 + "CreateNewFE: {} "
649 + "SetProp+Edge: {} #Props: {} "
650 + "SearchSwitch: {} "
651 + "AddEdgeToSwitch: {} "
652 + "SearchInPort: {} "
653 + "AddEdgeToInPort: {} "
654 + "SearchOutPort: {} "
655 + "AddEdgeToOutPort: {} "
656 + "AddEdgeBetweenFlowPath: {} "
657 , flowEntry.flowId(), flowEntry.flowEntryId()
658 , endAddFlowEntry - startAddFlowEntry
659 , endSearchFlowEntry - startAddFlowEntry
660 , endCreateNewFlowEntry - startCreateNewFlowEntry
661 , endSetProperties - startSetProperties, numProperties
662 , endSearchSwitch - startSearchSwitch
663 , endAddEdgeToSwitch - startAddEdgeToSwitch
664 , endSearchInPort - startSearchInPort
665 , endAddEdgeToInPort - startAddEdgeToInPort
666 , endSearchOutPort - startSearchOutPort
667 , endAddEdgeToOutPort - startAddEdgeToOutPort
668 , endAddEdgeBetweenFlowPath - startAddEdgeBetweenFlowPath
669 );
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700670 }
671
672 return flowEntryObj;
673 }
674
675 /**
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700676 * Delete a flow entry from the Network MAP.
677 *
678 * @param dbHandler the Graph Database handler to use.
679 * @param flowObj the corresponding Flow Path object for the Flow Entry.
680 * @param flowEntry the Flow Entry to delete.
681 * @return true on success, otherwise false.
682 */
yoshitomob292c622013-11-23 14:35:58 -0800683 static boolean deleteFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700684 IFlowPath flowObj,
685 FlowEntry flowEntry) {
686 IFlowEntry flowEntryObj = null;
687 try {
688 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
689 } catch (Exception e) {
690 log.error(":deleteFlowEntry FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800691 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700692 return false;
693 }
694 //
695 // TODO: Don't print an error for now, because multiple controller
696 // instances might be deleting the same flow entry.
697 //
698 /*
699 if (flowEntryObj == null) {
700 log.error(":deleteFlowEntry FlowEntryId:{} failed: FlowEntry object not found",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800701 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700702 return false;
703 }
704 */
705 if (flowEntryObj == null)
706 return true;
707
708 flowObj.removeFlowEntry(flowEntryObj);
709 dbHandler.removeFlowEntry(flowEntryObj);
710 return true;
711 }
712
713 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700714 * Delete all previously added flows.
715 *
716 * @param dbHandler the Graph Database handler to use.
717 * @return true on success, otherwise false.
718 */
yoshitomob292c622013-11-23 14:35:58 -0800719 static boolean deleteAllFlows(DBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700720 Iterable<IFlowPath> allFlowPaths = dbHandler.getAllFlowPaths();
721 for (IFlowPath flowPathObj : allFlowPaths) {
722 if (flowPathObj == null)
723 continue;
Yuta HIGUCHI53794052014-01-10 16:49:41 -0800724 deleteIFlowPath(dbHandler, flowPathObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700725 }
726
727 return true;
728 }
729
730 /**
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800731 * Delete a previously added flow.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700732 *
733 * @param dbHandler the Graph Database handler to use.
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800734 * @param flowId the Flow ID of the flow to delete.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700735 * @return true on success, otherwise false.
736 */
yoshitomob292c622013-11-23 14:35:58 -0800737 static boolean deleteFlow(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700738 IFlowPath flowObj = null;
739 try {
740 flowObj = dbHandler.searchFlowPath(flowId);
741 } catch (Exception e) {
742 // TODO: handle exceptions
743 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800744 log.error(":deleteFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700745 return false;
746 }
747 if (flowObj == null) {
748 dbHandler.commit();
749 return true; // OK: No such flow
750 }
751
Yuta HIGUCHI53794052014-01-10 16:49:41 -0800752 deleteIFlowPath(dbHandler, flowObj);
753
754 return true;
755 }
756
757 private static void deleteIFlowPath(DBOperation dbHandler, IFlowPath flowObj) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700758 //
759 // Remove all Flow Entries
760 //
761 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
762 for (IFlowEntry flowEntryObj : flowEntries) {
763 flowObj.removeFlowEntry(flowEntryObj);
764 dbHandler.removeFlowEntry(flowEntryObj);
765 }
766 // Remove the Flow itself
767 dbHandler.removeFlowPath(flowObj);
768 dbHandler.commit();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700769 }
770
771 /**
772 * Get a previously added flow.
773 *
774 * @param dbHandler the Graph Database handler to use.
775 * @param flowId the Flow ID of the flow to get.
776 * @return the Flow Path if found, otherwise null.
777 */
yoshitomob292c622013-11-23 14:35:58 -0800778 static FlowPath getFlow(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700779 IFlowPath flowObj = null;
780 try {
781 flowObj = dbHandler.searchFlowPath(flowId);
782 } catch (Exception e) {
783 // TODO: handle exceptions
784 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800785 log.error(":getFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700786 return null;
787 }
788 if (flowObj == null) {
789 dbHandler.commit();
790 return null; // Flow not found
791 }
792
793 //
794 // Extract the Flow state
795 //
796 FlowPath flowPath = extractFlowPath(flowObj);
797 dbHandler.commit();
798
799 return flowPath;
800 }
801
802 /**
803 * Get all installed flows by all installers.
804 *
805 * @param dbHandler the Graph Database handler to use.
806 * @return the Flow Paths if found, otherwise null.
807 */
yoshitomob292c622013-11-23 14:35:58 -0800808 static ArrayList<FlowPath> getAllFlows(DBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700809 Iterable<IFlowPath> flowPathsObj = null;
810 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
811
812 try {
813 flowPathsObj = dbHandler.getAllFlowPaths();
814 } catch (Exception e) {
815 // TODO: handle exceptions
816 dbHandler.rollback();
817 log.error(":getAllFlowPaths failed");
818 return flowPaths;
819 }
820 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
821 dbHandler.commit();
822 return flowPaths; // No Flows found
823 }
824
825 for (IFlowPath flowObj : flowPathsObj) {
826 //
827 // Extract the Flow state
828 //
829 FlowPath flowPath = extractFlowPath(flowObj);
830 if (flowPath != null)
831 flowPaths.add(flowPath);
832 }
833
834 dbHandler.commit();
835
836 return flowPaths;
837 }
838
839 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700840 * Extract Flow Path State from a Titan Database Object @ref IFlowPath.
841 *
842 * @param flowObj the object to extract the Flow Path State from.
843 * @return the extracted Flow Path State.
844 */
845 private static FlowPath extractFlowPath(IFlowPath flowObj) {
846 //
847 // Extract the Flow state
848 //
Toshio Koidea9b25142014-01-10 01:15:57 -0800849 log.info("extractFlowPath: start");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700850 String flowIdStr = flowObj.getFlowId();
851 String installerIdStr = flowObj.getInstallerId();
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700852 String flowPathType = flowObj.getFlowPathType();
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700853 String flowPathUserState = flowObj.getFlowPathUserState();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700854 Long flowPathFlags = flowObj.getFlowPathFlags();
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800855 Integer idleTimeout = flowObj.getIdleTimeout();
856 Integer hardTimeout = flowObj.getHardTimeout();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700857 String srcSwitchStr = flowObj.getSrcSwitch();
858 Short srcPortShort = flowObj.getSrcPort();
859 String dstSwitchStr = flowObj.getDstSwitch();
860 Short dstPortShort = flowObj.getDstPort();
861
862 if ((flowIdStr == null) ||
863 (installerIdStr == null) ||
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700864 (flowPathType == null) ||
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700865 (flowPathUserState == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700866 (flowPathFlags == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800867 (idleTimeout == null) ||
868 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700869 (srcSwitchStr == null) ||
870 (srcPortShort == null) ||
871 (dstSwitchStr == null) ||
872 (dstPortShort == null)) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800873 // TODO: A work-around, because of some bogus database objects
874 log.error("extractFlowPath: wrong properties");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700875 return null;
876 }
877
878 FlowPath flowPath = new FlowPath();
879 flowPath.setFlowId(new FlowId(flowIdStr));
880 flowPath.setInstallerId(new CallerId(installerIdStr));
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700881 flowPath.setFlowPathType(FlowPathType.valueOf(flowPathType));
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700882 flowPath.setFlowPathUserState(FlowPathUserState.valueOf(flowPathUserState));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700883 flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800884 flowPath.setIdleTimeout(idleTimeout);
885 flowPath.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700886 flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
887 flowPath.dataPath().srcPort().setPort(new Port(srcPortShort));
888 flowPath.dataPath().dstPort().setDpid(new Dpid(dstSwitchStr));
889 flowPath.dataPath().dstPort().setPort(new Port(dstPortShort));
890 //
891 // Extract the match conditions common for all Flow Entries
892 //
893 {
894 FlowEntryMatch match = new FlowEntryMatch();
895 String matchSrcMac = flowObj.getMatchSrcMac();
896 if (matchSrcMac != null)
897 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
898 String matchDstMac = flowObj.getMatchDstMac();
899 if (matchDstMac != null)
900 match.enableDstMac(MACAddress.valueOf(matchDstMac));
901 Short matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
902 if (matchEthernetFrameType != null)
903 match.enableEthernetFrameType(matchEthernetFrameType);
904 Short matchVlanId = flowObj.getMatchVlanId();
905 if (matchVlanId != null)
906 match.enableVlanId(matchVlanId);
907 Byte matchVlanPriority = flowObj.getMatchVlanPriority();
908 if (matchVlanPriority != null)
909 match.enableVlanPriority(matchVlanPriority);
910 String matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
911 if (matchSrcIPv4Net != null)
912 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
913 String matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
914 if (matchDstIPv4Net != null)
915 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
916 Byte matchIpProto = flowObj.getMatchIpProto();
917 if (matchIpProto != null)
918 match.enableIpProto(matchIpProto);
919 Byte matchIpToS = flowObj.getMatchIpToS();
920 if (matchIpToS != null)
921 match.enableIpToS(matchIpToS);
922 Short matchSrcTcpUdpPort = flowObj.getMatchSrcTcpUdpPort();
923 if (matchSrcTcpUdpPort != null)
924 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
925 Short matchDstTcpUdpPort = flowObj.getMatchDstTcpUdpPort();
926 if (matchDstTcpUdpPort != null)
927 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
928
929 flowPath.setFlowEntryMatch(match);
930 }
931 //
932 // Extract the actions for the first Flow Entry
933 //
934 {
935 String actionsStr = flowObj.getActions();
936 if (actionsStr != null) {
937 FlowEntryActions flowEntryActions = new FlowEntryActions(actionsStr);
938 flowPath.setFlowEntryActions(flowEntryActions);
939 }
940 }
941
942 //
943 // Extract all Flow Entries
944 //
945 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
946 for (IFlowEntry flowEntryObj : flowEntries) {
947 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
948 if (flowEntry == null)
949 continue;
950 flowPath.dataPath().flowEntries().add(flowEntry);
951 }
952
Toshio Koidea9b25142014-01-10 01:15:57 -0800953 log.info("extractFlowPath: end");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700954 return flowPath;
955 }
956
957 /**
958 * Extract Flow Entry State from a Titan Database Object @ref IFlowEntry.
959 *
960 * @param flowEntryObj the object to extract the Flow Entry State from.
961 * @return the extracted Flow Entry State.
962 */
Brian O'Connora8e49802013-10-30 20:49:59 -0700963 public static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800964 log.info("extractFlowEntry: start");
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800965 IFlowPath flowObj = flowEntryObj.getFlow();
Toshio Koidea9b25142014-01-10 01:15:57 -0800966 if (flowObj == null) {
967 log.error("extractFlowEntry: no flowPath exists");
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800968 return null;
Toshio Koidea9b25142014-01-10 01:15:57 -0800969 }
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800970
971 String flowIdStr = flowObj.getFlowId();
972 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700973 String flowEntryIdStr = flowEntryObj.getFlowEntryId();
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800974 Integer idleTimeout = flowEntryObj.getIdleTimeout();
975 Integer hardTimeout = flowEntryObj.getHardTimeout();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700976 String switchDpidStr = flowEntryObj.getSwitchDpid();
977 String userState = flowEntryObj.getUserState();
978 String switchState = flowEntryObj.getSwitchState();
979
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800980 if ((flowIdStr == null) ||
981 (flowEntryIdStr == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800982 (idleTimeout == null) ||
983 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700984 (switchDpidStr == null) ||
985 (userState == null) ||
986 (switchState == null)) {
Brian O'Connora8e49802013-10-30 20:49:59 -0700987 // TODO: A work-around, because of some bogus database objects
Toshio Koidea9b25142014-01-10 01:15:57 -0800988 log.error("extractFlowEntry: wrong properties");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700989 return null;
990 }
991
992 FlowEntry flowEntry = new FlowEntry();
993 flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800994 flowEntry.setFlowId(new FlowId(flowIdStr));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700995 flowEntry.setDpid(new Dpid(switchDpidStr));
yoshia97632b2013-12-17 15:46:08 -0800996 flowEntry.setIdleTimeout(idleTimeout);
997 flowEntry.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700998
999 //
1000 // Extract the match conditions
1001 //
1002 FlowEntryMatch match = new FlowEntryMatch();
1003 Short matchInPort = flowEntryObj.getMatchInPort();
1004 if (matchInPort != null)
1005 match.enableInPort(new Port(matchInPort));
1006 String matchSrcMac = flowEntryObj.getMatchSrcMac();
1007 if (matchSrcMac != null)
1008 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
1009 String matchDstMac = flowEntryObj.getMatchDstMac();
1010 if (matchDstMac != null)
1011 match.enableDstMac(MACAddress.valueOf(matchDstMac));
1012 Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
1013 if (matchEthernetFrameType != null)
1014 match.enableEthernetFrameType(matchEthernetFrameType);
1015 Short matchVlanId = flowEntryObj.getMatchVlanId();
1016 if (matchVlanId != null)
1017 match.enableVlanId(matchVlanId);
1018 Byte matchVlanPriority = flowEntryObj.getMatchVlanPriority();
1019 if (matchVlanPriority != null)
1020 match.enableVlanPriority(matchVlanPriority);
1021 String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
1022 if (matchSrcIPv4Net != null)
1023 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
1024 String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
1025 if (matchDstIPv4Net != null)
1026 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
1027 Byte matchIpProto = flowEntryObj.getMatchIpProto();
1028 if (matchIpProto != null)
1029 match.enableIpProto(matchIpProto);
1030 Byte matchIpToS = flowEntryObj.getMatchIpToS();
1031 if (matchIpToS != null)
1032 match.enableIpToS(matchIpToS);
1033 Short matchSrcTcpUdpPort = flowEntryObj.getMatchSrcTcpUdpPort();
1034 if (matchSrcTcpUdpPort != null)
1035 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
1036 Short matchDstTcpUdpPort = flowEntryObj.getMatchDstTcpUdpPort();
1037 if (matchDstTcpUdpPort != null)
1038 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
1039 flowEntry.setFlowEntryMatch(match);
1040
1041 //
1042 // Extract the actions
1043 //
1044 FlowEntryActions actions = new FlowEntryActions();
1045 String actionsStr = flowEntryObj.getActions();
1046 if (actionsStr != null)
1047 actions = new FlowEntryActions(actionsStr);
1048 flowEntry.setFlowEntryActions(actions);
1049 flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
1050 flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
1051 //
1052 // TODO: Take care of FlowEntryErrorState.
1053 //
Toshio Koidea9b25142014-01-10 01:15:57 -08001054 log.info("extractFlowEntry: end");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001055 return flowEntry;
1056 }
1057}