blob: 905a9dfcf0bd20bd3ba3cabe049afbcbca9c3e74 [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;
7import java.util.List;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07008
9import net.floodlightcontroller.util.MACAddress;
yoshitomob292c622013-11-23 14:35:58 -080010import net.onrc.onos.graph.DBOperation;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070011import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
12import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
13import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
14import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
15import net.onrc.onos.ofcontroller.util.*;
16
17import org.slf4j.Logger;
18import org.slf4j.LoggerFactory;
19
20/**
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<>();
53
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070054 try {
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080055 if ( measureONOSFlowTimeProp ) {
56 startAddFlow = System.nanoTime();
57 }
yoshi40210942013-12-03 08:21:02 -080058 flowObj = dbHandler.searchFlowPath(flowPath.flowId());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080059 if ( measureONOSFlowTimeProp ) {
60 endSearchExistingFlowPathTime = System.nanoTime();
61 }
yoshi40210942013-12-03 08:21:02 -080062 if (flowObj != null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070063 found = true;
64 } else {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -080065 if ( measureONOSFlowTimeProp ) {
66 startCreateNewFlowPathTime = System.nanoTime();
67 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070068 flowObj = dbHandler.newFlowPath();
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080069 if ( measureONOSFlowTimeProp ) {
70 endCreateNewFlowPathTime = System.nanoTime();
71 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070072 }
73 } catch (Exception e) {
74 dbHandler.rollback();
75
76 StringWriter sw = new StringWriter();
77 e.printStackTrace(new PrintWriter(sw));
78 String stacktrace = sw.toString();
79
80 log.error(":addFlow FlowId:{} failed: {}",
81 flowPath.flowId().toString(),
82 stacktrace);
83 return false;
84 }
85 if (flowObj == null) {
86 log.error(":addFlow FlowId:{} failed: Flow object not created",
87 flowPath.flowId().toString());
88 dbHandler.rollback();
89 return false;
90 }
91
92 //
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -080093 // Remove the old Flow Entries
94 //
95 if (found) {
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080096 if ( measureONOSFlowTimeProp ) {
97 startFollowExistingFlowEntries = System.nanoTime();
98 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -080099 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800100 if ( measureONOSFlowTimeProp ) {
101 endFollowExistingFlowEntries = System.nanoTime();
102 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800103 LinkedList<IFlowEntry> deleteFlowEntries =
104 new LinkedList<IFlowEntry>();
105 for (IFlowEntry flowEntryObj : flowEntries)
106 deleteFlowEntries.add(flowEntryObj);
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800107 if( measureONOSFlowTimeProp ) {
108 for (IFlowEntry flowEntryObj : deleteFlowEntries) {
109 long start = System.nanoTime();
110 flowObj.removeFlowEntry(flowEntryObj);
111 accTimeRemovingFlowEntriesFromFlowPath += System.nanoTime() - start;
112 start = System.nanoTime();
113 dbHandler.removeFlowEntry(flowEntryObj);
114 accTimeRemovingFlowEntriesFromDB += System.nanoTime() - start;
115 }
116 } else {
117 for (IFlowEntry flowEntryObj : deleteFlowEntries) {
118 flowObj.removeFlowEntry(flowEntryObj);
119 dbHandler.removeFlowEntry(flowEntryObj);
120 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800121 }
122 }
123
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800124 if ( measureONOSFlowTimeProp ) {
125 startSettingFlowPathProps = System.nanoTime();
126 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800127 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700128 // Set the Flow key:
129 // - flowId
130 //
131 flowObj.setFlowId(flowPath.flowId().toString());
132 flowObj.setType("flow");
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800133 if ( measureONOSFlowTimeProp ) {
134 numPropsSet += 2;
135 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700136
137 //
138 // Set the Flow attributes:
139 // - flowPath.installerId()
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700140 // - flowPath.flowPathType()
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700141 // - flowPath.flowPathUserState()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700142 // - flowPath.flowPathFlags()
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800143 // - flowPath.idleTimeout()
144 // - flowPath.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700145 // - flowPath.dataPath().srcPort()
146 // - flowPath.dataPath().dstPort()
147 // - flowPath.matchSrcMac()
148 // - flowPath.matchDstMac()
149 // - flowPath.matchEthernetFrameType()
150 // - flowPath.matchVlanId()
151 // - flowPath.matchVlanPriority()
152 // - flowPath.matchSrcIPv4Net()
153 // - flowPath.matchDstIPv4Net()
154 // - flowPath.matchIpProto()
155 // - flowPath.matchIpToS()
156 // - flowPath.matchSrcTcpUdpPort()
157 // - flowPath.matchDstTcpUdpPort()
158 // - flowPath.flowEntryActions()
159 //
160 flowObj.setInstallerId(flowPath.installerId().toString());
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700161 flowObj.setFlowPathType(flowPath.flowPathType().toString());
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700162 flowObj.setFlowPathUserState(flowPath.flowPathUserState().toString());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700163 flowObj.setFlowPathFlags(flowPath.flowPathFlags().flags());
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800164 flowObj.setIdleTimeout(flowPath.idleTimeout());
165 flowObj.setHardTimeout(flowPath.hardTimeout());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700166 flowObj.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
167 flowObj.setSrcPort(flowPath.dataPath().srcPort().port().value());
168 flowObj.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
169 flowObj.setDstPort(flowPath.dataPath().dstPort().port().value());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800170 if ( measureONOSFlowTimeProp ) {
171 numPropsSet += 10;
172 }
173
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700174 if (flowPath.flowEntryMatch().matchSrcMac()) {
175 flowObj.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800176 if ( measureONOSFlowTimeProp ) {
177 ++numPropsSet;
178 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700179 }
180 if (flowPath.flowEntryMatch().matchDstMac()) {
181 flowObj.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800182 if ( measureONOSFlowTimeProp ) {
183 ++numPropsSet;
184 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700185 }
186 if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
187 flowObj.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800188 if ( measureONOSFlowTimeProp ) {
189 ++numPropsSet;
190 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700191 }
192 if (flowPath.flowEntryMatch().matchVlanId()) {
193 flowObj.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800194 if ( measureONOSFlowTimeProp ) {
195 ++numPropsSet;
196 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700197 }
198 if (flowPath.flowEntryMatch().matchVlanPriority()) {
199 flowObj.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800200 if ( measureONOSFlowTimeProp ) {
201 ++numPropsSet;
202 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700203 }
204 if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
205 flowObj.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800206 if ( measureONOSFlowTimeProp ) {
207 ++numPropsSet;
208 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700209 }
210 if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
211 flowObj.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800212 if ( measureONOSFlowTimeProp ) {
213 ++numPropsSet;
214 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700215 }
216 if (flowPath.flowEntryMatch().matchIpProto()) {
217 flowObj.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800218 if ( measureONOSFlowTimeProp ) {
219 ++numPropsSet;
220 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700221 }
222 if (flowPath.flowEntryMatch().matchIpToS()) {
223 flowObj.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800224 if ( measureONOSFlowTimeProp ) {
225 ++numPropsSet;
226 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700227 }
228 if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
229 flowObj.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800230 if ( measureONOSFlowTimeProp ) {
231 ++numPropsSet;
232 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700233 }
234 if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
235 flowObj.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800236 if ( measureONOSFlowTimeProp ) {
237 ++numPropsSet;
238 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700239 }
240 if (! flowPath.flowEntryActions().actions().isEmpty()) {
241 flowObj.setActions(flowPath.flowEntryActions().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800242 if ( measureONOSFlowTimeProp ) {
243 ++numPropsSet;
244 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700245 }
Pavlin Radoslavovbcc86ef2013-10-26 12:06:25 -0700246 flowObj.setDataPathSummary(flowPath.dataPath().dataPathSummary());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800247 if ( measureONOSFlowTimeProp ) {
248 ++numPropsSet;
249 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700250
251 if (found)
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700252 flowObj.setFlowPathUserState("FP_USER_MODIFY");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700253 else
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700254 flowObj.setFlowPathUserState("FP_USER_ADD");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700255
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800256 if ( measureONOSFlowTimeProp ) {
257 ++numPropsSet;
258 }
259
260 if ( measureONOSFlowTimeProp ) {
261 endSettingFlowPathProps = System.nanoTime();
262 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700263 // Flow edges:
264 // HeadFE
265
266
267 //
268 // Flow Entries:
269 // flowPath.dataPath().flowEntries()
270 //
271 for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800272 if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE)
273 continue; // Skip: all Flow Entries were deleted earlier
274
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800275 long startAddFlowEntry = 0, endAddFlowEntry;
276 if( measureONOSFlowTimeProp ) {
277 startAddFlowEntry = System.nanoTime();
278 }
279 IFlowEntry iFlowEntry = addFlowEntry(dbHandler, flowObj, flowEntry);
280 if( measureONOSFlowTimeProp ) {
281 endAddFlowEntry = System.nanoTime();
282 accTimeAddFlowEntries += endAddFlowEntry - startAddFlowEntry;
283
284 flowEntryTimes.addLast( new long[]{flowEntry.flowId().value(), endAddFlowEntry - startAddFlowEntry} );
285 }
286 if ( iFlowEntry == null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700287 dbHandler.rollback();
288 return false;
289 }
290 }
291 dbHandler.commit();
292
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800293
294 if ( measureONOSFlowTimeProp ) {
295 endAddFlow = System.nanoTime();
296
Yuta HIGUCHI0b4fbaf2014-01-04 22:23:05 -0800297 log.error("Performance addFlow(_,{}) -- "
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800298 + "GrandTotal: {} "
299 + "only FlowPathTotal: {} "
300 + "searchExistingFlowPath: {} "
301 + "createNewFlowPathTime: {}"
302 + "followExistingFlowEntries: {} "
303 + "accTimeRemovingFlowEntriesFromFlowPath: {} "
304 + "accTimeRemovingFlowEntriesFromDB: {} "
305 + "settingFlowPathProps: {} #Props: {} "
306 + "accFlowEntries: {} #FEs: {}",
307 flowPath.flowId(),
308 (endAddFlow - startAddFlow),
309 (endSettingFlowPathProps - startAddFlow),
310 (endSearchExistingFlowPathTime - startAddFlow),
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800311 (endCreateNewFlowPathTime - startCreateNewFlowPathTime),
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800312 (endFollowExistingFlowEntries - startFollowExistingFlowEntries),
313 (accTimeRemovingFlowEntriesFromFlowPath),
314 (accTimeRemovingFlowEntriesFromDB),
315 (endSettingFlowPathProps - startSettingFlowPathProps), numPropsSet,
316 accTimeAddFlowEntries, numNewFlowEntries
317 );
318
319 // Each FlowEntries
320 final String strFlowId = flowPath.flowId().toString();
321 for ( long[] idFE_Time : flowEntryTimes ) {
Yuta HIGUCHI0b4fbaf2014-01-04 22:23:05 -0800322 log.error("Performance addFlowEntry(_,{},{})@addFlow -- FlowEntryTotal: {}",
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800323 strFlowId,
324 "0x" + Long.toHexString(idFE_Time[0]),
325 idFE_Time[1]);
326 }
327 }
328
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700329 return true;
330 }
331
332 /**
333 * Add a flow entry to the Network MAP.
334 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700335 * @param dbHandler the Graph Database handler to use.
336 * @param flowObj the corresponding Flow Path object for the Flow Entry.
337 * @param flowEntry the Flow Entry to install.
338 * @return the added Flow Entry object on success, otherwise null.
339 */
onlab-qa38805cd2013-12-06 20:08:54 -0800340 static IFlowEntry addFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700341 IFlowPath flowObj,
342 FlowEntry flowEntry) {
343 // Flow edges
344 // HeadFE (TODO)
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800345 long startAddFlowEntry = 0;
346 long endAddFlowEntry = 0;
347
348 long endSearchFlowEntry = 0;
349
350 long startCreateNewFlowEntry = 0;
351 long endCreateNewFlowEntry = 0;
352
353 long startSetProperties = 0;
354 long endSetProperties = 0;
355 int numProperties = 0;
356
357 long startSearchSwitch = 0;
358 long endSearchSwitch = 0;
359
360 long startAddEdgeToSwitch =0;
361 long endAddEdgeToSwitch =0;
362
363 long startSearchInPort = 0;
364 long endSearchInPort = 0;
365
366 long startAddEdgeToInPort =0;
367 long endAddEdgeToInPort =0;
368
369 long startSearchOutPort = 0;
370 long endSearchOutPort = 0;
371
372 long startAddEdgeToOutPort =0;
373 long endAddEdgeToOutPort =0;
374
375 long startAddEdgeBetweenFlowPath = 0;
376 long endAddEdgeBetweenFlowPath = 0;
377
378 if (measureONOSFlowEntryTimeProp) {
379 startAddFlowEntry = System.nanoTime();
380 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700381
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700382 IFlowEntry flowEntryObj = null;
383 boolean found = false;
384 try {
385 if ((flowEntryObj =
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800386 dbHandler.searchFlowEntry(flowEntry.flowEntryId())) != null) {
387 if (measureONOSFlowEntryTimeProp) {
388 endSearchFlowEntry = System.nanoTime();
389 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700390 found = true;
391 } else {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800392 if (measureONOSFlowEntryTimeProp) {
393 startCreateNewFlowEntry = System.nanoTime();
394 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700395 flowEntryObj = dbHandler.newFlowEntry();
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800396 if (measureONOSFlowEntryTimeProp) {
397 endCreateNewFlowEntry = System.nanoTime();
398 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700399 }
400 } catch (Exception e) {
401 log.error(":addFlow FlowEntryId:{} failed",
402 flowEntry.flowEntryId().toString());
403 return null;
404 }
405 if (flowEntryObj == null) {
406 log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created",
407 flowEntry.flowEntryId().toString());
408 return null;
409 }
410
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800411 if (measureONOSFlowEntryTimeProp) {
412 startSetProperties = System.nanoTime();
413 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700414 //
415 // Set the Flow Entry key:
416 // - flowEntry.flowEntryId()
417 //
418 flowEntryObj.setFlowEntryId(flowEntry.flowEntryId().toString());
419 flowEntryObj.setType("flow_entry");
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800420 if (measureONOSFlowEntryTimeProp) {
421 numProperties += 2;
422 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700423
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800424 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700425 // Set the Flow Entry Edges and attributes:
426 // - Switch edge
427 // - InPort edge
428 // - OutPort edge
429 //
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800430 // - flowEntry.idleTimeout()
431 // - flowEntry.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700432 // - flowEntry.dpid()
433 // - flowEntry.flowEntryUserState()
434 // - flowEntry.flowEntrySwitchState()
435 // - flowEntry.flowEntryErrorState()
436 // - flowEntry.matchInPort()
437 // - flowEntry.matchSrcMac()
438 // - flowEntry.matchDstMac()
439 // - flowEntry.matchEthernetFrameType()
440 // - flowEntry.matchVlanId()
441 // - flowEntry.matchVlanPriority()
442 // - flowEntry.matchSrcIPv4Net()
443 // - flowEntry.matchDstIPv4Net()
444 // - flowEntry.matchIpProto()
445 // - flowEntry.matchIpToS()
446 // - flowEntry.matchSrcTcpUdpPort()
447 // - flowEntry.matchDstTcpUdpPort()
448 // - flowEntry.actionOutputPort()
449 // - flowEntry.actions()
450 //
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800451 if (measureONOSFlowEntryTimeProp) {
452 startSearchSwitch = System.nanoTime();
453 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700454 ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800455 if (measureONOSFlowEntryTimeProp) {
456 endSearchSwitch = System.nanoTime();
457 }
458
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800459 flowEntryObj.setIdleTimeout(flowEntry.idleTimeout());
460 flowEntryObj.setHardTimeout(flowEntry.hardTimeout());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700461 flowEntryObj.setSwitchDpid(flowEntry.dpid().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800462 if (measureONOSFlowEntryTimeProp) {
463 numProperties += 3;
464 }
465
466 if (measureONOSFlowEntryTimeProp) {
467 startAddEdgeToSwitch = System.nanoTime();
468 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700469 flowEntryObj.setSwitch(sw);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800470 if (measureONOSFlowEntryTimeProp) {
471 endAddEdgeToSwitch = System.nanoTime();
472 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700473 if (flowEntry.flowEntryMatch().matchInPort()) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800474 if (measureONOSFlowEntryTimeProp) {
475 startSearchInPort = System.nanoTime();
476 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700477 IPortObject inport =
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800478 dbHandler.searchPort(flowEntry.dpid().toString(),
479 flowEntry.flowEntryMatch().inPort().value());
480 if (measureONOSFlowEntryTimeProp) {
481 endSearchInPort = System.nanoTime();
482 }
483
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700484 flowEntryObj.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800485 if (measureONOSFlowEntryTimeProp) {
486 ++numProperties;
487 }
488
489 if (measureONOSFlowEntryTimeProp) {
490 startAddEdgeToInPort = System.nanoTime();
491 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700492 flowEntryObj.setInPort(inport);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800493 if (measureONOSFlowEntryTimeProp) {
494 endAddEdgeToInPort = System.nanoTime();
495 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700496 }
497 if (flowEntry.flowEntryMatch().matchSrcMac()) {
498 flowEntryObj.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800499 if (measureONOSFlowEntryTimeProp) {
500 ++numProperties;
501 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700502 }
503 if (flowEntry.flowEntryMatch().matchDstMac()) {
504 flowEntryObj.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800505 if (measureONOSFlowEntryTimeProp) {
506 ++numProperties;
507 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700508 }
509 if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
510 flowEntryObj.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800511 if (measureONOSFlowEntryTimeProp) {
512 ++numProperties;
513 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700514 }
515 if (flowEntry.flowEntryMatch().matchVlanId()) {
516 flowEntryObj.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
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().matchVlanPriority()) {
522 flowEntryObj.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
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().matchSrcIPv4Net()) {
528 flowEntryObj.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
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().matchDstIPv4Net()) {
534 flowEntryObj.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
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().matchIpProto()) {
540 flowEntryObj.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
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().matchIpToS()) {
546 flowEntryObj.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
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().matchSrcTcpUdpPort()) {
552 flowEntryObj.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
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().matchDstTcpUdpPort()) {
558 flowEntryObj.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800559 if (measureONOSFlowEntryTimeProp) {
560 ++numProperties;
561 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700562 }
563
564 for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
565 if (fa.actionOutput() != null) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800566 if (measureONOSFlowEntryTimeProp) {
567 if ( startSearchOutPort != 0 ) log.error("Performance addFlowEntry(_,{},{}) -- Multiple output port action unexpected.", flowEntry.flowId(), flowEntry.flowEntryId());
568 startSearchOutPort = System.nanoTime();
569 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700570 IPortObject outport =
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800571 dbHandler.searchPort(flowEntry.dpid().toString(),
572 fa.actionOutput().port().value());
573 if (measureONOSFlowEntryTimeProp) {
574 endSearchOutPort = System.nanoTime();
575 }
576
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700577 flowEntryObj.setActionOutputPort(fa.actionOutput().port().value());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800578 if (measureONOSFlowEntryTimeProp) {
579 ++numProperties;
580 }
581
582 if (measureONOSFlowEntryTimeProp) {
583 startAddEdgeToOutPort = System.nanoTime();
584 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700585 flowEntryObj.setOutPort(outport);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800586 if (measureONOSFlowEntryTimeProp) {
587 endAddEdgeToOutPort = System.nanoTime();
588 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700589 }
590 }
591 if (! flowEntry.flowEntryActions().isEmpty()) {
592 flowEntryObj.setActions(flowEntry.flowEntryActions().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800593 if (measureONOSFlowEntryTimeProp) {
594 ++numProperties;
595 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700596 }
597
598 // TODO: Hacks with hard-coded state names!
599 if (found)
600 flowEntryObj.setUserState("FE_USER_MODIFY");
601 else
602 flowEntryObj.setUserState("FE_USER_ADD");
Pavlin Radoslavovebc8b192013-10-29 15:35:35 -0700603 flowEntryObj.setSwitchState(flowEntry.flowEntrySwitchState().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800604 if (measureONOSFlowEntryTimeProp) {
605 numProperties += 2;
606 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700607 //
608 // TODO: Take care of the FlowEntryErrorState.
609 //
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800610 if (measureONOSFlowEntryTimeProp) {
611 endSetProperties = System.nanoTime();
612 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700613
614 // Flow Entries edges:
615 // Flow
616 // NextFE (TODO)
617 if (! found) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800618 if (measureONOSFlowEntryTimeProp) {
619 startAddEdgeBetweenFlowPath = System.nanoTime();
620 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700621 flowObj.addFlowEntry(flowEntryObj);
622 flowEntryObj.setFlow(flowObj);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800623 if (measureONOSFlowEntryTimeProp) {
624 endAddEdgeBetweenFlowPath = System.nanoTime();
625 }
626 }
627 if (measureONOSFlowEntryTimeProp) {
628 endAddFlowEntry = System.nanoTime();
629
630 log.error("Performance addFlowEntry(_,{},{}) -- "
631 + "GrandTotal: {} "
632 + "SearchExistingFE: {} "
633 + "CreateNewFE: {} "
634 + "SetProp+Edge: {} #Props: {} "
635 + "SearchSwitch: {} "
636 + "AddEdgeToSwitch: {} "
637 + "SearchInPort: {} "
638 + "AddEdgeToInPort: {} "
639 + "SearchOutPort: {} "
640 + "AddEdgeToOutPort: {} "
641 + "AddEdgeBetweenFlowPath: {} "
642 , flowEntry.flowId(), flowEntry.flowEntryId()
643 , endAddFlowEntry - startAddFlowEntry
644 , endSearchFlowEntry - startAddFlowEntry
645 , endCreateNewFlowEntry - startCreateNewFlowEntry
646 , endSetProperties - startSetProperties, numProperties
647 , endSearchSwitch - startSearchSwitch
648 , endAddEdgeToSwitch - startAddEdgeToSwitch
649 , endSearchInPort - startSearchInPort
650 , endAddEdgeToInPort - startAddEdgeToInPort
651 , endSearchOutPort - startSearchOutPort
652 , endAddEdgeToOutPort - startAddEdgeToOutPort
653 , endAddEdgeBetweenFlowPath - startAddEdgeBetweenFlowPath
654 );
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700655 }
656
657 return flowEntryObj;
658 }
659
660 /**
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700661 * Delete a flow entry from the Network MAP.
662 *
663 * @param dbHandler the Graph Database handler to use.
664 * @param flowObj the corresponding Flow Path object for the Flow Entry.
665 * @param flowEntry the Flow Entry to delete.
666 * @return true on success, otherwise false.
667 */
yoshitomob292c622013-11-23 14:35:58 -0800668 static boolean deleteFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700669 IFlowPath flowObj,
670 FlowEntry flowEntry) {
671 IFlowEntry flowEntryObj = null;
672 try {
673 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
674 } catch (Exception e) {
675 log.error(":deleteFlowEntry FlowEntryId:{} failed",
676 flowEntry.flowEntryId().toString());
677 return false;
678 }
679 //
680 // TODO: Don't print an error for now, because multiple controller
681 // instances might be deleting the same flow entry.
682 //
683 /*
684 if (flowEntryObj == null) {
685 log.error(":deleteFlowEntry FlowEntryId:{} failed: FlowEntry object not found",
686 flowEntry.flowEntryId().toString());
687 return false;
688 }
689 */
690 if (flowEntryObj == null)
691 return true;
692
693 flowObj.removeFlowEntry(flowEntryObj);
694 dbHandler.removeFlowEntry(flowEntryObj);
695 return true;
696 }
697
698 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700699 * Delete all previously added flows.
700 *
701 * @param dbHandler the Graph Database handler to use.
702 * @return true on success, otherwise false.
703 */
yoshitomob292c622013-11-23 14:35:58 -0800704 static boolean deleteAllFlows(DBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700705 List<FlowId> allFlowIds = new LinkedList<FlowId>();
706
707 // Get all Flow IDs
708 Iterable<IFlowPath> allFlowPaths = dbHandler.getAllFlowPaths();
709 for (IFlowPath flowPathObj : allFlowPaths) {
710 if (flowPathObj == null)
711 continue;
712 String flowIdStr = flowPathObj.getFlowId();
713 if (flowIdStr == null)
714 continue;
715 FlowId flowId = new FlowId(flowIdStr);
716 allFlowIds.add(flowId);
717 }
718
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800719 // Delete all flows one-by-one
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700720 for (FlowId flowId : allFlowIds) {
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800721 deleteFlow(dbHandler, flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700722 }
723
724 return true;
725 }
726
727 /**
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800728 * Delete a previously added flow.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700729 *
730 * @param dbHandler the Graph Database handler to use.
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800731 * @param flowId the Flow ID of the flow to delete.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700732 * @return true on success, otherwise false.
733 */
yoshitomob292c622013-11-23 14:35:58 -0800734 static boolean deleteFlow(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700735 IFlowPath flowObj = null;
736 try {
737 flowObj = dbHandler.searchFlowPath(flowId);
738 } catch (Exception e) {
739 // TODO: handle exceptions
740 dbHandler.rollback();
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800741 log.error(":deleteFlow FlowId:{} failed", flowId.toString());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700742 return false;
743 }
744 if (flowObj == null) {
745 dbHandler.commit();
746 return true; // OK: No such flow
747 }
748
749 //
750 // Remove all Flow Entries
751 //
752 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
753 for (IFlowEntry flowEntryObj : flowEntries) {
754 flowObj.removeFlowEntry(flowEntryObj);
755 dbHandler.removeFlowEntry(flowEntryObj);
756 }
757 // Remove the Flow itself
758 dbHandler.removeFlowPath(flowObj);
759 dbHandler.commit();
760
761 return true;
762 }
763
764 /**
765 * Get a previously added flow.
766 *
767 * @param dbHandler the Graph Database handler to use.
768 * @param flowId the Flow ID of the flow to get.
769 * @return the Flow Path if found, otherwise null.
770 */
yoshitomob292c622013-11-23 14:35:58 -0800771 static FlowPath getFlow(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700772 IFlowPath flowObj = null;
773 try {
774 flowObj = dbHandler.searchFlowPath(flowId);
775 } catch (Exception e) {
776 // TODO: handle exceptions
777 dbHandler.rollback();
778 log.error(":getFlow FlowId:{} failed", flowId.toString());
779 return null;
780 }
781 if (flowObj == null) {
782 dbHandler.commit();
783 return null; // Flow not found
784 }
785
786 //
787 // Extract the Flow state
788 //
789 FlowPath flowPath = extractFlowPath(flowObj);
790 dbHandler.commit();
791
792 return flowPath;
793 }
794
795 /**
796 * Get all installed flows by all installers.
797 *
798 * @param dbHandler the Graph Database handler to use.
799 * @return the Flow Paths if found, otherwise null.
800 */
yoshitomob292c622013-11-23 14:35:58 -0800801 static ArrayList<FlowPath> getAllFlows(DBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700802 Iterable<IFlowPath> flowPathsObj = null;
803 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
804
805 try {
806 flowPathsObj = dbHandler.getAllFlowPaths();
807 } catch (Exception e) {
808 // TODO: handle exceptions
809 dbHandler.rollback();
810 log.error(":getAllFlowPaths failed");
811 return flowPaths;
812 }
813 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
814 dbHandler.commit();
815 return flowPaths; // No Flows found
816 }
817
818 for (IFlowPath flowObj : flowPathsObj) {
819 //
820 // Extract the Flow state
821 //
822 FlowPath flowPath = extractFlowPath(flowObj);
823 if (flowPath != null)
824 flowPaths.add(flowPath);
825 }
826
827 dbHandler.commit();
828
829 return flowPaths;
830 }
831
832 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700833 * Extract Flow Path State from a Titan Database Object @ref IFlowPath.
834 *
835 * @param flowObj the object to extract the Flow Path State from.
836 * @return the extracted Flow Path State.
837 */
838 private static FlowPath extractFlowPath(IFlowPath flowObj) {
839 //
840 // Extract the Flow state
841 //
842 String flowIdStr = flowObj.getFlowId();
843 String installerIdStr = flowObj.getInstallerId();
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700844 String flowPathType = flowObj.getFlowPathType();
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700845 String flowPathUserState = flowObj.getFlowPathUserState();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700846 Long flowPathFlags = flowObj.getFlowPathFlags();
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800847 Integer idleTimeout = flowObj.getIdleTimeout();
848 Integer hardTimeout = flowObj.getHardTimeout();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700849 String srcSwitchStr = flowObj.getSrcSwitch();
850 Short srcPortShort = flowObj.getSrcPort();
851 String dstSwitchStr = flowObj.getDstSwitch();
852 Short dstPortShort = flowObj.getDstPort();
853
854 if ((flowIdStr == null) ||
855 (installerIdStr == null) ||
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700856 (flowPathType == null) ||
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700857 (flowPathUserState == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700858 (flowPathFlags == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800859 (idleTimeout == null) ||
860 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700861 (srcSwitchStr == null) ||
862 (srcPortShort == null) ||
863 (dstSwitchStr == null) ||
864 (dstPortShort == null)) {
865 // TODO: A work-around, becauuse of some bogus database objects
866 return null;
867 }
868
869 FlowPath flowPath = new FlowPath();
870 flowPath.setFlowId(new FlowId(flowIdStr));
871 flowPath.setInstallerId(new CallerId(installerIdStr));
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700872 flowPath.setFlowPathType(FlowPathType.valueOf(flowPathType));
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700873 flowPath.setFlowPathUserState(FlowPathUserState.valueOf(flowPathUserState));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700874 flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800875 flowPath.setIdleTimeout(idleTimeout);
876 flowPath.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700877 flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
878 flowPath.dataPath().srcPort().setPort(new Port(srcPortShort));
879 flowPath.dataPath().dstPort().setDpid(new Dpid(dstSwitchStr));
880 flowPath.dataPath().dstPort().setPort(new Port(dstPortShort));
881 //
882 // Extract the match conditions common for all Flow Entries
883 //
884 {
885 FlowEntryMatch match = new FlowEntryMatch();
886 String matchSrcMac = flowObj.getMatchSrcMac();
887 if (matchSrcMac != null)
888 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
889 String matchDstMac = flowObj.getMatchDstMac();
890 if (matchDstMac != null)
891 match.enableDstMac(MACAddress.valueOf(matchDstMac));
892 Short matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
893 if (matchEthernetFrameType != null)
894 match.enableEthernetFrameType(matchEthernetFrameType);
895 Short matchVlanId = flowObj.getMatchVlanId();
896 if (matchVlanId != null)
897 match.enableVlanId(matchVlanId);
898 Byte matchVlanPriority = flowObj.getMatchVlanPriority();
899 if (matchVlanPriority != null)
900 match.enableVlanPriority(matchVlanPriority);
901 String matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
902 if (matchSrcIPv4Net != null)
903 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
904 String matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
905 if (matchDstIPv4Net != null)
906 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
907 Byte matchIpProto = flowObj.getMatchIpProto();
908 if (matchIpProto != null)
909 match.enableIpProto(matchIpProto);
910 Byte matchIpToS = flowObj.getMatchIpToS();
911 if (matchIpToS != null)
912 match.enableIpToS(matchIpToS);
913 Short matchSrcTcpUdpPort = flowObj.getMatchSrcTcpUdpPort();
914 if (matchSrcTcpUdpPort != null)
915 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
916 Short matchDstTcpUdpPort = flowObj.getMatchDstTcpUdpPort();
917 if (matchDstTcpUdpPort != null)
918 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
919
920 flowPath.setFlowEntryMatch(match);
921 }
922 //
923 // Extract the actions for the first Flow Entry
924 //
925 {
926 String actionsStr = flowObj.getActions();
927 if (actionsStr != null) {
928 FlowEntryActions flowEntryActions = new FlowEntryActions(actionsStr);
929 flowPath.setFlowEntryActions(flowEntryActions);
930 }
931 }
932
933 //
934 // Extract all Flow Entries
935 //
936 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
937 for (IFlowEntry flowEntryObj : flowEntries) {
938 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
939 if (flowEntry == null)
940 continue;
941 flowPath.dataPath().flowEntries().add(flowEntry);
942 }
943
944 return flowPath;
945 }
946
947 /**
948 * Extract Flow Entry State from a Titan Database Object @ref IFlowEntry.
949 *
950 * @param flowEntryObj the object to extract the Flow Entry State from.
951 * @return the extracted Flow Entry State.
952 */
Brian O'Connora8e49802013-10-30 20:49:59 -0700953 public static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800954 IFlowPath flowObj = flowEntryObj.getFlow();
955 if (flowObj == null)
956 return null;
957
958 String flowIdStr = flowObj.getFlowId();
959 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700960 String flowEntryIdStr = flowEntryObj.getFlowEntryId();
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800961 Integer idleTimeout = flowEntryObj.getIdleTimeout();
962 Integer hardTimeout = flowEntryObj.getHardTimeout();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700963 String switchDpidStr = flowEntryObj.getSwitchDpid();
964 String userState = flowEntryObj.getUserState();
965 String switchState = flowEntryObj.getSwitchState();
966
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800967 if ((flowIdStr == null) ||
968 (flowEntryIdStr == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800969 (idleTimeout == null) ||
970 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700971 (switchDpidStr == null) ||
972 (userState == null) ||
973 (switchState == null)) {
Brian O'Connora8e49802013-10-30 20:49:59 -0700974 // TODO: A work-around, because of some bogus database objects
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700975 return null;
976 }
977
978 FlowEntry flowEntry = new FlowEntry();
979 flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800980 flowEntry.setFlowId(new FlowId(flowIdStr));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700981 flowEntry.setDpid(new Dpid(switchDpidStr));
yoshia97632b2013-12-17 15:46:08 -0800982 flowEntry.setIdleTimeout(idleTimeout);
983 flowEntry.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700984
985 //
986 // Extract the match conditions
987 //
988 FlowEntryMatch match = new FlowEntryMatch();
989 Short matchInPort = flowEntryObj.getMatchInPort();
990 if (matchInPort != null)
991 match.enableInPort(new Port(matchInPort));
992 String matchSrcMac = flowEntryObj.getMatchSrcMac();
993 if (matchSrcMac != null)
994 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
995 String matchDstMac = flowEntryObj.getMatchDstMac();
996 if (matchDstMac != null)
997 match.enableDstMac(MACAddress.valueOf(matchDstMac));
998 Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
999 if (matchEthernetFrameType != null)
1000 match.enableEthernetFrameType(matchEthernetFrameType);
1001 Short matchVlanId = flowEntryObj.getMatchVlanId();
1002 if (matchVlanId != null)
1003 match.enableVlanId(matchVlanId);
1004 Byte matchVlanPriority = flowEntryObj.getMatchVlanPriority();
1005 if (matchVlanPriority != null)
1006 match.enableVlanPriority(matchVlanPriority);
1007 String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
1008 if (matchSrcIPv4Net != null)
1009 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
1010 String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
1011 if (matchDstIPv4Net != null)
1012 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
1013 Byte matchIpProto = flowEntryObj.getMatchIpProto();
1014 if (matchIpProto != null)
1015 match.enableIpProto(matchIpProto);
1016 Byte matchIpToS = flowEntryObj.getMatchIpToS();
1017 if (matchIpToS != null)
1018 match.enableIpToS(matchIpToS);
1019 Short matchSrcTcpUdpPort = flowEntryObj.getMatchSrcTcpUdpPort();
1020 if (matchSrcTcpUdpPort != null)
1021 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
1022 Short matchDstTcpUdpPort = flowEntryObj.getMatchDstTcpUdpPort();
1023 if (matchDstTcpUdpPort != null)
1024 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
1025 flowEntry.setFlowEntryMatch(match);
1026
1027 //
1028 // Extract the actions
1029 //
1030 FlowEntryActions actions = new FlowEntryActions();
1031 String actionsStr = flowEntryObj.getActions();
1032 if (actionsStr != null)
1033 actions = new FlowEntryActions(actionsStr);
1034 flowEntry.setFlowEntryActions(actions);
1035 flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
1036 flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
1037 //
1038 // TODO: Take care of FlowEntryErrorState.
1039 //
1040 return flowEntry;
1041 }
1042}