blob: 1fc70ec73f3b6fde70c9bffa9ae0f32d0575f86f [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
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -080020import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
21
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070022/**
23 * Class for performing Flow-related operations on the Database.
24 */
Pavlin Radoslavov6bfaea62013-12-03 14:55:57 -080025public class FlowDatabaseOperation {
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070026 private final static Logger log = LoggerFactory.getLogger(FlowDatabaseOperation.class);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -080027 private static final boolean measureONOSFlowTimeProp = Long.valueOf(System.getProperty("benchmark.measureONOSFlow", "0")) != 0;
28 private static final boolean measureONOSFlowEntryTimeProp = Long.valueOf(System.getProperty("benchmark.measureONOSFlowEntry", "0")) != 0;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070029
30 /**
31 * Add a flow.
32 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070033 * @param dbHandler the Graph Database handler to use.
34 * @param flowPath the Flow Path to install.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070035 * @return true on success, otherwise false.
36 */
onlab-qa38805cd2013-12-06 20:08:54 -080037 static boolean addFlow(DBOperation dbHandler, FlowPath flowPath) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070038 IFlowPath flowObj = null;
39 boolean found = false;
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080040 long startAddFlow = 0;
41 long endAddFlow = 0;
42 long endSearchExistingFlowPathTime = 0;
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -080043 long startCreateNewFlowPathTime = 0;
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080044 long endCreateNewFlowPathTime = 0;
45 long startFollowExistingFlowEntries = 0;
46 long endFollowExistingFlowEntries = 0;
47 long accTimeRemovingFlowEntriesFromFlowPath = 0;
48 long accTimeRemovingFlowEntriesFromDB = 0;
49 long startSettingFlowPathProps = 0;
50 long endSettingFlowPathProps = 0;
51 int numPropsSet = 0;
52 long accTimeAddFlowEntries = 0;
53 int numNewFlowEntries = 0;
54 LinkedList<long[]> flowEntryTimes = new LinkedList<>();
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -080055 PerfMon pm = PerfMon.getInstance();
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080056
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -080057 pm.addflowpath_start();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070058 try {
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080059 if ( measureONOSFlowTimeProp ) {
60 startAddFlow = System.nanoTime();
61 }
yoshi40210942013-12-03 08:21:02 -080062 flowObj = dbHandler.searchFlowPath(flowPath.flowId());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080063 if ( measureONOSFlowTimeProp ) {
64 endSearchExistingFlowPathTime = System.nanoTime();
65 }
yoshi40210942013-12-03 08:21:02 -080066 if (flowObj != null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070067 found = true;
68 } else {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -080069 if ( measureONOSFlowTimeProp ) {
70 startCreateNewFlowPathTime = System.nanoTime();
71 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070072 flowObj = dbHandler.newFlowPath();
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080073 if ( measureONOSFlowTimeProp ) {
74 endCreateNewFlowPathTime = System.nanoTime();
75 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070076 }
77 } catch (Exception e) {
78 dbHandler.rollback();
79
80 StringWriter sw = new StringWriter();
81 e.printStackTrace(new PrintWriter(sw));
82 String stacktrace = sw.toString();
83
84 log.error(":addFlow FlowId:{} failed: {}",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -080085 flowPath.flowId(),
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070086 stacktrace);
87 return false;
88 }
89 if (flowObj == null) {
90 log.error(":addFlow FlowId:{} failed: Flow object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -080091 flowPath.flowId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070092 dbHandler.rollback();
93 return false;
94 }
95
96 //
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -080097 // Remove the old Flow Entries
98 //
99 if (found) {
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800100 if ( measureONOSFlowTimeProp ) {
101 startFollowExistingFlowEntries = System.nanoTime();
102 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800103 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800104 if ( measureONOSFlowTimeProp ) {
105 endFollowExistingFlowEntries = System.nanoTime();
106 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800107 LinkedList<IFlowEntry> deleteFlowEntries =
108 new LinkedList<IFlowEntry>();
109 for (IFlowEntry flowEntryObj : flowEntries)
110 deleteFlowEntries.add(flowEntryObj);
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800111 if( measureONOSFlowTimeProp ) {
112 for (IFlowEntry flowEntryObj : deleteFlowEntries) {
113 long start = System.nanoTime();
114 flowObj.removeFlowEntry(flowEntryObj);
115 accTimeRemovingFlowEntriesFromFlowPath += System.nanoTime() - start;
116 start = System.nanoTime();
117 dbHandler.removeFlowEntry(flowEntryObj);
118 accTimeRemovingFlowEntriesFromDB += System.nanoTime() - start;
119 }
120 } else {
121 for (IFlowEntry flowEntryObj : deleteFlowEntries) {
122 flowObj.removeFlowEntry(flowEntryObj);
123 dbHandler.removeFlowEntry(flowEntryObj);
124 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800125 }
126 }
127
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800128 if ( measureONOSFlowTimeProp ) {
129 startSettingFlowPathProps = System.nanoTime();
130 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800131 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700132 // Set the Flow key:
133 // - flowId
134 //
135 flowObj.setFlowId(flowPath.flowId().toString());
136 flowObj.setType("flow");
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 //
164 flowObj.setInstallerId(flowPath.installerId().toString());
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700165 flowObj.setFlowPathType(flowPath.flowPathType().toString());
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700166 flowObj.setFlowPathUserState(flowPath.flowPathUserState().toString());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700167 flowObj.setFlowPathFlags(flowPath.flowPathFlags().flags());
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800168 flowObj.setIdleTimeout(flowPath.idleTimeout());
169 flowObj.setHardTimeout(flowPath.hardTimeout());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700170 flowObj.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
171 flowObj.setSrcPort(flowPath.dataPath().srcPort().port().value());
172 flowObj.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
173 flowObj.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()) {
179 flowObj.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()) {
185 flowObj.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()) {
191 flowObj.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()) {
197 flowObj.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()) {
203 flowObj.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()) {
209 flowObj.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()) {
215 flowObj.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()) {
221 flowObj.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()) {
227 flowObj.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()) {
233 flowObj.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()) {
239 flowObj.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()) {
245 flowObj.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 }
Pavlin Radoslavovbcc86ef2013-10-26 12:06:25 -0700250 flowObj.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)
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700256 flowObj.setFlowPathUserState("FP_USER_MODIFY");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700257 else
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700258 flowObj.setFlowPathUserState("FP_USER_ADD");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700259
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800260 if ( measureONOSFlowTimeProp ) {
261 ++numPropsSet;
262 }
263
264 if ( measureONOSFlowTimeProp ) {
265 endSettingFlowPathProps = System.nanoTime();
266 }
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800267 pm.addflowpath_end();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700268 // Flow edges:
269 // HeadFE
270
271
272 //
273 // Flow Entries:
274 // flowPath.dataPath().flowEntries()
275 //
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800276 pm.addflowentry_start();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700277 for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800278 if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE)
279 continue; // Skip: all Flow Entries were deleted earlier
280
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800281 pm.addflowentry_incr();
282
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800283 long startAddFlowEntry = 0, endAddFlowEntry;
284 if( measureONOSFlowTimeProp ) {
285 startAddFlowEntry = System.nanoTime();
286 }
287 IFlowEntry iFlowEntry = addFlowEntry(dbHandler, flowObj, flowEntry);
288 if( measureONOSFlowTimeProp ) {
289 endAddFlowEntry = System.nanoTime();
290 accTimeAddFlowEntries += endAddFlowEntry - startAddFlowEntry;
291
292 flowEntryTimes.addLast( new long[]{flowEntry.flowId().value(), endAddFlowEntry - startAddFlowEntry} );
293 }
294 if ( iFlowEntry == null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700295 dbHandler.rollback();
296 return false;
297 }
298 }
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800299 pm.addflowentry_end();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700300 dbHandler.commit();
301
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800302
303 if ( measureONOSFlowTimeProp ) {
304 endAddFlow = System.nanoTime();
305
Yuta HIGUCHI0b4fbaf2014-01-04 22:23:05 -0800306 log.error("Performance addFlow(_,{}) -- "
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800307 + "GrandTotal: {} "
308 + "only FlowPathTotal: {} "
309 + "searchExistingFlowPath: {} "
310 + "createNewFlowPathTime: {}"
311 + "followExistingFlowEntries: {} "
312 + "accTimeRemovingFlowEntriesFromFlowPath: {} "
313 + "accTimeRemovingFlowEntriesFromDB: {} "
314 + "settingFlowPathProps: {} #Props: {} "
315 + "accFlowEntries: {} #FEs: {}",
316 flowPath.flowId(),
317 (endAddFlow - startAddFlow),
318 (endSettingFlowPathProps - startAddFlow),
319 (endSearchExistingFlowPathTime - startAddFlow),
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800320 (endCreateNewFlowPathTime - startCreateNewFlowPathTime),
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800321 (endFollowExistingFlowEntries - startFollowExistingFlowEntries),
322 (accTimeRemovingFlowEntriesFromFlowPath),
323 (accTimeRemovingFlowEntriesFromDB),
324 (endSettingFlowPathProps - startSettingFlowPathProps), numPropsSet,
325 accTimeAddFlowEntries, numNewFlowEntries
326 );
327
328 // Each FlowEntries
329 final String strFlowId = flowPath.flowId().toString();
330 for ( long[] idFE_Time : flowEntryTimes ) {
Yuta HIGUCHI0b4fbaf2014-01-04 22:23:05 -0800331 log.error("Performance addFlowEntry(_,{},{})@addFlow -- FlowEntryTotal: {}",
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800332 strFlowId,
333 "0x" + Long.toHexString(idFE_Time[0]),
334 idFE_Time[1]);
335 }
336 }
337
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700338 return true;
339 }
340
341 /**
342 * Add a flow entry to the Network MAP.
343 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700344 * @param dbHandler the Graph Database handler to use.
345 * @param flowObj the corresponding Flow Path object for the Flow Entry.
346 * @param flowEntry the Flow Entry to install.
347 * @return the added Flow Entry object on success, otherwise null.
348 */
onlab-qa38805cd2013-12-06 20:08:54 -0800349 static IFlowEntry addFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700350 IFlowPath flowObj,
351 FlowEntry flowEntry) {
352 // Flow edges
353 // HeadFE (TODO)
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800354 long startAddFlowEntry = 0;
355 long endAddFlowEntry = 0;
356
357 long endSearchFlowEntry = 0;
358
359 long startCreateNewFlowEntry = 0;
360 long endCreateNewFlowEntry = 0;
361
362 long startSetProperties = 0;
363 long endSetProperties = 0;
364 int numProperties = 0;
365
366 long startSearchSwitch = 0;
367 long endSearchSwitch = 0;
368
369 long startAddEdgeToSwitch =0;
370 long endAddEdgeToSwitch =0;
371
372 long startSearchInPort = 0;
373 long endSearchInPort = 0;
374
375 long startAddEdgeToInPort =0;
376 long endAddEdgeToInPort =0;
377
378 long startSearchOutPort = 0;
379 long endSearchOutPort = 0;
380
381 long startAddEdgeToOutPort =0;
382 long endAddEdgeToOutPort =0;
383
384 long startAddEdgeBetweenFlowPath = 0;
385 long endAddEdgeBetweenFlowPath = 0;
386
387 if (measureONOSFlowEntryTimeProp) {
388 startAddFlowEntry = System.nanoTime();
389 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700390
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700391 IFlowEntry flowEntryObj = null;
392 boolean found = false;
393 try {
Yuta HIGUCHIc27a6c92014-01-07 11:51:11 -0800394 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
395 if (measureONOSFlowEntryTimeProp) {
396 endSearchFlowEntry = System.nanoTime();
397 }
398 if (flowEntryObj != null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700399 found = true;
400 } else {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800401 if (measureONOSFlowEntryTimeProp) {
402 startCreateNewFlowEntry = System.nanoTime();
403 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700404 flowEntryObj = dbHandler.newFlowEntry();
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800405 if (measureONOSFlowEntryTimeProp) {
406 endCreateNewFlowEntry = System.nanoTime();
407 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700408 }
409 } catch (Exception e) {
410 log.error(":addFlow FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800411 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700412 return null;
413 }
414 if (flowEntryObj == null) {
415 log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800416 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700417 return null;
418 }
419
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800420 if (measureONOSFlowEntryTimeProp) {
421 startSetProperties = System.nanoTime();
422 }
Yuta HIGUCHI8685f9c2014-01-07 15:53:28 -0800423
Toshio Koide3f233542014-01-07 14:19:09 -0800424 FlowProperty flowProp = new FlowProperty(dbHandler, flowEntryObj);
Yuta HIGUCHI8685f9c2014-01-07 15:53:28 -0800425
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700426 //
427 // Set the Flow Entry key:
428 // - flowEntry.flowEntryId()
429 //
Toshio Koide3f233542014-01-07 14:19:09 -0800430 flowProp.setFlowEntryId(flowEntry.flowEntryId().toString());
431 flowProp.setType("flow_entry");
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800432 if (measureONOSFlowEntryTimeProp) {
433 numProperties += 2;
434 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700435
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800436 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700437 // Set the Flow Entry Edges and attributes:
438 // - Switch edge
439 // - InPort edge
440 // - OutPort edge
441 //
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800442 // - flowEntry.idleTimeout()
443 // - flowEntry.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700444 // - flowEntry.dpid()
445 // - flowEntry.flowEntryUserState()
446 // - flowEntry.flowEntrySwitchState()
447 // - flowEntry.flowEntryErrorState()
448 // - flowEntry.matchInPort()
449 // - flowEntry.matchSrcMac()
450 // - flowEntry.matchDstMac()
451 // - flowEntry.matchEthernetFrameType()
452 // - flowEntry.matchVlanId()
453 // - flowEntry.matchVlanPriority()
454 // - flowEntry.matchSrcIPv4Net()
455 // - flowEntry.matchDstIPv4Net()
456 // - flowEntry.matchIpProto()
457 // - flowEntry.matchIpToS()
458 // - flowEntry.matchSrcTcpUdpPort()
459 // - flowEntry.matchDstTcpUdpPort()
460 // - flowEntry.actionOutputPort()
461 // - flowEntry.actions()
462 //
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800463 if (measureONOSFlowEntryTimeProp) {
464 startSearchSwitch = System.nanoTime();
465 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700466 ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800467 if (measureONOSFlowEntryTimeProp) {
468 endSearchSwitch = System.nanoTime();
469 }
470
Toshio Koide3f233542014-01-07 14:19:09 -0800471 flowProp.setIdleTimeout(flowEntry.idleTimeout());
472 flowProp.setHardTimeout(flowEntry.hardTimeout());
473 flowProp.setSwitchDpid(flowEntry.dpid().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800474 if (measureONOSFlowEntryTimeProp) {
475 numProperties += 3;
476 }
477
478 if (measureONOSFlowEntryTimeProp) {
479 startAddEdgeToSwitch = System.nanoTime();
480 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700481 flowEntryObj.setSwitch(sw);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800482 if (measureONOSFlowEntryTimeProp) {
483 endAddEdgeToSwitch = System.nanoTime();
484 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700485 if (flowEntry.flowEntryMatch().matchInPort()) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800486 if (measureONOSFlowEntryTimeProp) {
487 startSearchInPort = System.nanoTime();
488 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700489 IPortObject inport =
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800490 dbHandler.searchPort(flowEntry.dpid().toString(),
491 flowEntry.flowEntryMatch().inPort().value());
492 if (measureONOSFlowEntryTimeProp) {
493 endSearchInPort = System.nanoTime();
494 }
495
Toshio Koide3f233542014-01-07 14:19:09 -0800496 flowProp.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800497 if (measureONOSFlowEntryTimeProp) {
498 ++numProperties;
499 }
500
501 if (measureONOSFlowEntryTimeProp) {
502 startAddEdgeToInPort = System.nanoTime();
503 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700504 flowEntryObj.setInPort(inport);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800505 if (measureONOSFlowEntryTimeProp) {
506 endAddEdgeToInPort = System.nanoTime();
507 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700508 }
509 if (flowEntry.flowEntryMatch().matchSrcMac()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800510 flowProp.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
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().matchDstMac()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800516 flowProp.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800517 if (measureONOSFlowEntryTimeProp) {
518 ++numProperties;
519 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700520 }
521 if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800522 flowProp.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
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().matchVlanId()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800528 flowProp.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
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().matchVlanPriority()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800534 flowProp.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
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().matchSrcIPv4Net()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800540 flowProp.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
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().matchDstIPv4Net()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800546 flowProp.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800547 if (measureONOSFlowEntryTimeProp) {
548 ++numProperties;
549 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700550 }
551 if (flowEntry.flowEntryMatch().matchIpProto()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800552 flowProp.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
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().matchIpToS()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800558 flowProp.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800559 if (measureONOSFlowEntryTimeProp) {
560 ++numProperties;
561 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700562 }
563 if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800564 flowProp.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800565 if (measureONOSFlowEntryTimeProp) {
566 ++numProperties;
567 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700568 }
569 if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800570 flowProp.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800571 if (measureONOSFlowEntryTimeProp) {
572 ++numProperties;
573 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700574 }
575
576 for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
577 if (fa.actionOutput() != null) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800578 if (measureONOSFlowEntryTimeProp) {
579 if ( startSearchOutPort != 0 ) log.error("Performance addFlowEntry(_,{},{}) -- Multiple output port action unexpected.", flowEntry.flowId(), flowEntry.flowEntryId());
580 startSearchOutPort = System.nanoTime();
581 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700582 IPortObject outport =
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800583 dbHandler.searchPort(flowEntry.dpid().toString(),
584 fa.actionOutput().port().value());
585 if (measureONOSFlowEntryTimeProp) {
586 endSearchOutPort = System.nanoTime();
587 }
588
Toshio Koide3f233542014-01-07 14:19:09 -0800589 flowProp.setActionOutputPort(fa.actionOutput().port().value());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800590 if (measureONOSFlowEntryTimeProp) {
591 ++numProperties;
592 }
593
594 if (measureONOSFlowEntryTimeProp) {
595 startAddEdgeToOutPort = System.nanoTime();
596 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700597 flowEntryObj.setOutPort(outport);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800598 if (measureONOSFlowEntryTimeProp) {
599 endAddEdgeToOutPort = System.nanoTime();
600 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700601 }
602 }
603 if (! flowEntry.flowEntryActions().isEmpty()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800604 flowProp.setActions(flowEntry.flowEntryActions().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800605 if (measureONOSFlowEntryTimeProp) {
606 ++numProperties;
607 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700608 }
609
610 // TODO: Hacks with hard-coded state names!
611 if (found)
Toshio Koide3f233542014-01-07 14:19:09 -0800612 flowProp.setUserState("FE_USER_MODIFY");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700613 else
Toshio Koide3f233542014-01-07 14:19:09 -0800614 flowProp.setUserState("FE_USER_ADD");
615 flowProp.setSwitchState(flowEntry.flowEntrySwitchState().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800616 if (measureONOSFlowEntryTimeProp) {
617 numProperties += 2;
618 }
Yuta HIGUCHI8685f9c2014-01-07 15:53:28 -0800619 flowProp.commitProperties();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700620 //
621 // TODO: Take care of the FlowEntryErrorState.
622 //
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800623 if (measureONOSFlowEntryTimeProp) {
624 endSetProperties = System.nanoTime();
625 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700626
627 // Flow Entries edges:
628 // Flow
629 // NextFE (TODO)
630 if (! found) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800631 if (measureONOSFlowEntryTimeProp) {
632 startAddEdgeBetweenFlowPath = System.nanoTime();
633 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700634 flowObj.addFlowEntry(flowEntryObj);
635 flowEntryObj.setFlow(flowObj);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800636 if (measureONOSFlowEntryTimeProp) {
637 endAddEdgeBetweenFlowPath = System.nanoTime();
638 }
639 }
640 if (measureONOSFlowEntryTimeProp) {
641 endAddFlowEntry = System.nanoTime();
642
643 log.error("Performance addFlowEntry(_,{},{}) -- "
644 + "GrandTotal: {} "
645 + "SearchExistingFE: {} "
646 + "CreateNewFE: {} "
647 + "SetProp+Edge: {} #Props: {} "
648 + "SearchSwitch: {} "
649 + "AddEdgeToSwitch: {} "
650 + "SearchInPort: {} "
651 + "AddEdgeToInPort: {} "
652 + "SearchOutPort: {} "
653 + "AddEdgeToOutPort: {} "
654 + "AddEdgeBetweenFlowPath: {} "
655 , flowEntry.flowId(), flowEntry.flowEntryId()
656 , endAddFlowEntry - startAddFlowEntry
657 , endSearchFlowEntry - startAddFlowEntry
658 , endCreateNewFlowEntry - startCreateNewFlowEntry
659 , endSetProperties - startSetProperties, numProperties
660 , endSearchSwitch - startSearchSwitch
661 , endAddEdgeToSwitch - startAddEdgeToSwitch
662 , endSearchInPort - startSearchInPort
663 , endAddEdgeToInPort - startAddEdgeToInPort
664 , endSearchOutPort - startSearchOutPort
665 , endAddEdgeToOutPort - startAddEdgeToOutPort
666 , endAddEdgeBetweenFlowPath - startAddEdgeBetweenFlowPath
667 );
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700668 }
669
670 return flowEntryObj;
671 }
672
673 /**
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700674 * Delete a flow entry from the Network MAP.
675 *
676 * @param dbHandler the Graph Database handler to use.
677 * @param flowObj the corresponding Flow Path object for the Flow Entry.
678 * @param flowEntry the Flow Entry to delete.
679 * @return true on success, otherwise false.
680 */
yoshitomob292c622013-11-23 14:35:58 -0800681 static boolean deleteFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700682 IFlowPath flowObj,
683 FlowEntry flowEntry) {
684 IFlowEntry flowEntryObj = null;
685 try {
686 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
687 } catch (Exception e) {
688 log.error(":deleteFlowEntry FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800689 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700690 return false;
691 }
692 //
693 // TODO: Don't print an error for now, because multiple controller
694 // instances might be deleting the same flow entry.
695 //
696 /*
697 if (flowEntryObj == null) {
698 log.error(":deleteFlowEntry FlowEntryId:{} failed: FlowEntry object not found",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800699 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700700 return false;
701 }
702 */
703 if (flowEntryObj == null)
704 return true;
705
706 flowObj.removeFlowEntry(flowEntryObj);
707 dbHandler.removeFlowEntry(flowEntryObj);
708 return true;
709 }
710
711 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700712 * Delete all previously added flows.
713 *
714 * @param dbHandler the Graph Database handler to use.
715 * @return true on success, otherwise false.
716 */
yoshitomob292c622013-11-23 14:35:58 -0800717 static boolean deleteAllFlows(DBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700718 List<FlowId> allFlowIds = new LinkedList<FlowId>();
719
720 // Get all Flow IDs
721 Iterable<IFlowPath> allFlowPaths = dbHandler.getAllFlowPaths();
722 for (IFlowPath flowPathObj : allFlowPaths) {
723 if (flowPathObj == null)
724 continue;
725 String flowIdStr = flowPathObj.getFlowId();
726 if (flowIdStr == null)
727 continue;
728 FlowId flowId = new FlowId(flowIdStr);
729 allFlowIds.add(flowId);
730 }
731
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800732 // Delete all flows one-by-one
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700733 for (FlowId flowId : allFlowIds) {
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800734 deleteFlow(dbHandler, flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700735 }
736
737 return true;
738 }
739
740 /**
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800741 * Delete a previously added flow.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700742 *
743 * @param dbHandler the Graph Database handler to use.
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800744 * @param flowId the Flow ID of the flow to delete.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700745 * @return true on success, otherwise false.
746 */
yoshitomob292c622013-11-23 14:35:58 -0800747 static boolean deleteFlow(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700748 IFlowPath flowObj = null;
749 try {
750 flowObj = dbHandler.searchFlowPath(flowId);
751 } catch (Exception e) {
752 // TODO: handle exceptions
753 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800754 log.error(":deleteFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700755 return false;
756 }
757 if (flowObj == null) {
758 dbHandler.commit();
759 return true; // OK: No such flow
760 }
761
762 //
763 // Remove all Flow Entries
764 //
765 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
766 for (IFlowEntry flowEntryObj : flowEntries) {
767 flowObj.removeFlowEntry(flowEntryObj);
768 dbHandler.removeFlowEntry(flowEntryObj);
769 }
770 // Remove the Flow itself
771 dbHandler.removeFlowPath(flowObj);
772 dbHandler.commit();
773
774 return true;
775 }
776
777 /**
778 * Get a previously added flow.
779 *
780 * @param dbHandler the Graph Database handler to use.
781 * @param flowId the Flow ID of the flow to get.
782 * @return the Flow Path if found, otherwise null.
783 */
yoshitomob292c622013-11-23 14:35:58 -0800784 static FlowPath getFlow(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700785 IFlowPath flowObj = null;
786 try {
787 flowObj = dbHandler.searchFlowPath(flowId);
788 } catch (Exception e) {
789 // TODO: handle exceptions
790 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800791 log.error(":getFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700792 return null;
793 }
794 if (flowObj == null) {
795 dbHandler.commit();
796 return null; // Flow not found
797 }
798
799 //
800 // Extract the Flow state
801 //
802 FlowPath flowPath = extractFlowPath(flowObj);
803 dbHandler.commit();
804
805 return flowPath;
806 }
807
808 /**
809 * Get all installed flows by all installers.
810 *
811 * @param dbHandler the Graph Database handler to use.
812 * @return the Flow Paths if found, otherwise null.
813 */
yoshitomob292c622013-11-23 14:35:58 -0800814 static ArrayList<FlowPath> getAllFlows(DBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700815 Iterable<IFlowPath> flowPathsObj = null;
816 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
817
818 try {
819 flowPathsObj = dbHandler.getAllFlowPaths();
820 } catch (Exception e) {
821 // TODO: handle exceptions
822 dbHandler.rollback();
823 log.error(":getAllFlowPaths failed");
824 return flowPaths;
825 }
826 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
827 dbHandler.commit();
828 return flowPaths; // No Flows found
829 }
830
831 for (IFlowPath flowObj : flowPathsObj) {
832 //
833 // Extract the Flow state
834 //
835 FlowPath flowPath = extractFlowPath(flowObj);
836 if (flowPath != null)
837 flowPaths.add(flowPath);
838 }
839
840 dbHandler.commit();
841
842 return flowPaths;
843 }
844
845 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700846 * Extract Flow Path State from a Titan Database Object @ref IFlowPath.
847 *
848 * @param flowObj the object to extract the Flow Path State from.
849 * @return the extracted Flow Path State.
850 */
851 private static FlowPath extractFlowPath(IFlowPath flowObj) {
852 //
853 // Extract the Flow state
854 //
855 String flowIdStr = flowObj.getFlowId();
856 String installerIdStr = flowObj.getInstallerId();
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700857 String flowPathType = flowObj.getFlowPathType();
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700858 String flowPathUserState = flowObj.getFlowPathUserState();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700859 Long flowPathFlags = flowObj.getFlowPathFlags();
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800860 Integer idleTimeout = flowObj.getIdleTimeout();
861 Integer hardTimeout = flowObj.getHardTimeout();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700862 String srcSwitchStr = flowObj.getSrcSwitch();
863 Short srcPortShort = flowObj.getSrcPort();
864 String dstSwitchStr = flowObj.getDstSwitch();
865 Short dstPortShort = flowObj.getDstPort();
866
867 if ((flowIdStr == null) ||
868 (installerIdStr == null) ||
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700869 (flowPathType == null) ||
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700870 (flowPathUserState == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700871 (flowPathFlags == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800872 (idleTimeout == null) ||
873 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700874 (srcSwitchStr == null) ||
875 (srcPortShort == null) ||
876 (dstSwitchStr == null) ||
877 (dstPortShort == null)) {
878 // TODO: A work-around, becauuse of some bogus database objects
879 return null;
880 }
881
882 FlowPath flowPath = new FlowPath();
883 flowPath.setFlowId(new FlowId(flowIdStr));
884 flowPath.setInstallerId(new CallerId(installerIdStr));
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700885 flowPath.setFlowPathType(FlowPathType.valueOf(flowPathType));
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700886 flowPath.setFlowPathUserState(FlowPathUserState.valueOf(flowPathUserState));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700887 flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800888 flowPath.setIdleTimeout(idleTimeout);
889 flowPath.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700890 flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
891 flowPath.dataPath().srcPort().setPort(new Port(srcPortShort));
892 flowPath.dataPath().dstPort().setDpid(new Dpid(dstSwitchStr));
893 flowPath.dataPath().dstPort().setPort(new Port(dstPortShort));
894 //
895 // Extract the match conditions common for all Flow Entries
896 //
897 {
898 FlowEntryMatch match = new FlowEntryMatch();
899 String matchSrcMac = flowObj.getMatchSrcMac();
900 if (matchSrcMac != null)
901 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
902 String matchDstMac = flowObj.getMatchDstMac();
903 if (matchDstMac != null)
904 match.enableDstMac(MACAddress.valueOf(matchDstMac));
905 Short matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
906 if (matchEthernetFrameType != null)
907 match.enableEthernetFrameType(matchEthernetFrameType);
908 Short matchVlanId = flowObj.getMatchVlanId();
909 if (matchVlanId != null)
910 match.enableVlanId(matchVlanId);
911 Byte matchVlanPriority = flowObj.getMatchVlanPriority();
912 if (matchVlanPriority != null)
913 match.enableVlanPriority(matchVlanPriority);
914 String matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
915 if (matchSrcIPv4Net != null)
916 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
917 String matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
918 if (matchDstIPv4Net != null)
919 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
920 Byte matchIpProto = flowObj.getMatchIpProto();
921 if (matchIpProto != null)
922 match.enableIpProto(matchIpProto);
923 Byte matchIpToS = flowObj.getMatchIpToS();
924 if (matchIpToS != null)
925 match.enableIpToS(matchIpToS);
926 Short matchSrcTcpUdpPort = flowObj.getMatchSrcTcpUdpPort();
927 if (matchSrcTcpUdpPort != null)
928 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
929 Short matchDstTcpUdpPort = flowObj.getMatchDstTcpUdpPort();
930 if (matchDstTcpUdpPort != null)
931 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
932
933 flowPath.setFlowEntryMatch(match);
934 }
935 //
936 // Extract the actions for the first Flow Entry
937 //
938 {
939 String actionsStr = flowObj.getActions();
940 if (actionsStr != null) {
941 FlowEntryActions flowEntryActions = new FlowEntryActions(actionsStr);
942 flowPath.setFlowEntryActions(flowEntryActions);
943 }
944 }
945
946 //
947 // Extract all Flow Entries
948 //
949 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
950 for (IFlowEntry flowEntryObj : flowEntries) {
951 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
952 if (flowEntry == null)
953 continue;
954 flowPath.dataPath().flowEntries().add(flowEntry);
955 }
956
957 return flowPath;
958 }
959
960 /**
961 * Extract Flow Entry State from a Titan Database Object @ref IFlowEntry.
962 *
963 * @param flowEntryObj the object to extract the Flow Entry State from.
964 * @return the extracted Flow Entry State.
965 */
Brian O'Connora8e49802013-10-30 20:49:59 -0700966 public static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800967 IFlowPath flowObj = flowEntryObj.getFlow();
968 if (flowObj == null)
969 return null;
970
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
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700988 return null;
989 }
990
991 FlowEntry flowEntry = new FlowEntry();
992 flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800993 flowEntry.setFlowId(new FlowId(flowIdStr));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700994 flowEntry.setDpid(new Dpid(switchDpidStr));
yoshia97632b2013-12-17 15:46:08 -0800995 flowEntry.setIdleTimeout(idleTimeout);
996 flowEntry.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700997
998 //
999 // Extract the match conditions
1000 //
1001 FlowEntryMatch match = new FlowEntryMatch();
1002 Short matchInPort = flowEntryObj.getMatchInPort();
1003 if (matchInPort != null)
1004 match.enableInPort(new Port(matchInPort));
1005 String matchSrcMac = flowEntryObj.getMatchSrcMac();
1006 if (matchSrcMac != null)
1007 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
1008 String matchDstMac = flowEntryObj.getMatchDstMac();
1009 if (matchDstMac != null)
1010 match.enableDstMac(MACAddress.valueOf(matchDstMac));
1011 Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
1012 if (matchEthernetFrameType != null)
1013 match.enableEthernetFrameType(matchEthernetFrameType);
1014 Short matchVlanId = flowEntryObj.getMatchVlanId();
1015 if (matchVlanId != null)
1016 match.enableVlanId(matchVlanId);
1017 Byte matchVlanPriority = flowEntryObj.getMatchVlanPriority();
1018 if (matchVlanPriority != null)
1019 match.enableVlanPriority(matchVlanPriority);
1020 String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
1021 if (matchSrcIPv4Net != null)
1022 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
1023 String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
1024 if (matchDstIPv4Net != null)
1025 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
1026 Byte matchIpProto = flowEntryObj.getMatchIpProto();
1027 if (matchIpProto != null)
1028 match.enableIpProto(matchIpProto);
1029 Byte matchIpToS = flowEntryObj.getMatchIpToS();
1030 if (matchIpToS != null)
1031 match.enableIpToS(matchIpToS);
1032 Short matchSrcTcpUdpPort = flowEntryObj.getMatchSrcTcpUdpPort();
1033 if (matchSrcTcpUdpPort != null)
1034 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
1035 Short matchDstTcpUdpPort = flowEntryObj.getMatchDstTcpUdpPort();
1036 if (matchDstTcpUdpPort != null)
1037 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
1038 flowEntry.setFlowEntryMatch(match);
1039
1040 //
1041 // Extract the actions
1042 //
1043 FlowEntryActions actions = new FlowEntryActions();
1044 String actionsStr = flowEntryObj.getActions();
1045 if (actionsStr != null)
1046 actions = new FlowEntryActions(actionsStr);
1047 flowEntry.setFlowEntryActions(actions);
1048 flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
1049 flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
1050 //
1051 // TODO: Take care of FlowEntryErrorState.
1052 //
1053 return flowEntry;
1054 }
1055}