blob: 2cbadd6ed55d498e9d59012937f81b36e18c499e [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;
10
11import net.onrc.onos.graph.GraphDBOperation;
12
13import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
14import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
15import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
16import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
17import net.onrc.onos.ofcontroller.util.*;
18
19import org.slf4j.Logger;
20import org.slf4j.LoggerFactory;
21
22/**
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);
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 */
Pavlin Radoslavov051abb42013-12-05 17:24:50 -080035 static boolean addFlow(GraphDBOperation dbHandler, FlowPath flowPath) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070036 IFlowPath flowObj = null;
37 boolean found = false;
38 try {
39 if ((flowObj = dbHandler.searchFlowPath(flowPath.flowId())) != null) {
40 found = true;
41 } else {
42 flowObj = dbHandler.newFlowPath();
43 }
44 } catch (Exception e) {
45 dbHandler.rollback();
46
47 StringWriter sw = new StringWriter();
48 e.printStackTrace(new PrintWriter(sw));
49 String stacktrace = sw.toString();
50
51 log.error(":addFlow FlowId:{} failed: {}",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -080052 flowPath.flowId(),
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070053 stacktrace);
54 return false;
55 }
56 if (flowObj == null) {
57 log.error(":addFlow FlowId:{} failed: Flow object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -080058 flowPath.flowId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070059 dbHandler.rollback();
60 return false;
61 }
62
63 //
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -080064 // Remove the old Flow Entries
65 //
66 if (found) {
67 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
68 LinkedList<IFlowEntry> deleteFlowEntries =
69 new LinkedList<IFlowEntry>();
70 for (IFlowEntry flowEntryObj : flowEntries)
71 deleteFlowEntries.add(flowEntryObj);
72 for (IFlowEntry flowEntryObj : deleteFlowEntries) {
73 flowObj.removeFlowEntry(flowEntryObj);
74 dbHandler.removeFlowEntry(flowEntryObj);
75 }
76 }
77
78 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070079 // Set the Flow key:
80 // - flowId
81 //
82 flowObj.setFlowId(flowPath.flowId().toString());
83 flowObj.setType("flow");
84
85 //
86 // Set the Flow attributes:
87 // - flowPath.installerId()
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -070088 // - flowPath.flowPathType()
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -070089 // - flowPath.flowPathUserState()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070090 // - flowPath.flowPathFlags()
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -080091 // - flowPath.idleTimeout()
92 // - flowPath.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070093 // - flowPath.dataPath().srcPort()
94 // - flowPath.dataPath().dstPort()
95 // - flowPath.matchSrcMac()
96 // - flowPath.matchDstMac()
97 // - flowPath.matchEthernetFrameType()
98 // - flowPath.matchVlanId()
99 // - flowPath.matchVlanPriority()
100 // - flowPath.matchSrcIPv4Net()
101 // - flowPath.matchDstIPv4Net()
102 // - flowPath.matchIpProto()
103 // - flowPath.matchIpToS()
104 // - flowPath.matchSrcTcpUdpPort()
105 // - flowPath.matchDstTcpUdpPort()
106 // - flowPath.flowEntryActions()
107 //
108 flowObj.setInstallerId(flowPath.installerId().toString());
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700109 flowObj.setFlowPathType(flowPath.flowPathType().toString());
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700110 flowObj.setFlowPathUserState(flowPath.flowPathUserState().toString());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700111 flowObj.setFlowPathFlags(flowPath.flowPathFlags().flags());
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800112 flowObj.setIdleTimeout(flowPath.idleTimeout());
113 flowObj.setHardTimeout(flowPath.hardTimeout());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700114 flowObj.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
115 flowObj.setSrcPort(flowPath.dataPath().srcPort().port().value());
116 flowObj.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
117 flowObj.setDstPort(flowPath.dataPath().dstPort().port().value());
118 if (flowPath.flowEntryMatch().matchSrcMac()) {
119 flowObj.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
120 }
121 if (flowPath.flowEntryMatch().matchDstMac()) {
122 flowObj.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
123 }
124 if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
125 flowObj.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
126 }
127 if (flowPath.flowEntryMatch().matchVlanId()) {
128 flowObj.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
129 }
130 if (flowPath.flowEntryMatch().matchVlanPriority()) {
131 flowObj.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
132 }
133 if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
134 flowObj.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
135 }
136 if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
137 flowObj.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
138 }
139 if (flowPath.flowEntryMatch().matchIpProto()) {
140 flowObj.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
141 }
142 if (flowPath.flowEntryMatch().matchIpToS()) {
143 flowObj.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
144 }
145 if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
146 flowObj.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
147 }
148 if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
149 flowObj.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
150 }
151 if (! flowPath.flowEntryActions().actions().isEmpty()) {
152 flowObj.setActions(flowPath.flowEntryActions().toString());
153 }
Pavlin Radoslavovbcc86ef2013-10-26 12:06:25 -0700154 flowObj.setDataPathSummary(flowPath.dataPath().dataPathSummary());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700155
156 if (found)
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700157 flowObj.setFlowPathUserState("FP_USER_MODIFY");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700158 else
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700159 flowObj.setFlowPathUserState("FP_USER_ADD");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700160
161 // Flow edges:
162 // HeadFE
163
164
165 //
166 // Flow Entries:
167 // flowPath.dataPath().flowEntries()
168 //
169 for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800170 if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE)
171 continue; // Skip: all Flow Entries were deleted earlier
172
Pavlin Radoslavov67bf7622013-12-04 12:28:23 -0800173 if (addFlowEntry(dbHandler, flowObj, flowEntry) == null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700174 dbHandler.rollback();
175 return false;
176 }
177 }
178 dbHandler.commit();
179
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700180 return true;
181 }
182
183 /**
184 * Add a flow entry to the Network MAP.
185 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700186 * @param dbHandler the Graph Database handler to use.
187 * @param flowObj the corresponding Flow Path object for the Flow Entry.
188 * @param flowEntry the Flow Entry to install.
189 * @return the added Flow Entry object on success, otherwise null.
190 */
Pavlin Radoslavov67bf7622013-12-04 12:28:23 -0800191 static IFlowEntry addFlowEntry(GraphDBOperation dbHandler,
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700192 IFlowPath flowObj,
193 FlowEntry flowEntry) {
194 // Flow edges
195 // HeadFE (TODO)
196
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700197 IFlowEntry flowEntryObj = null;
198 boolean found = false;
199 try {
200 if ((flowEntryObj =
201 dbHandler.searchFlowEntry(flowEntry.flowEntryId())) != null) {
202 found = true;
203 } else {
204 flowEntryObj = dbHandler.newFlowEntry();
205 }
206 } catch (Exception e) {
207 log.error(":addFlow FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800208 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700209 return null;
210 }
211 if (flowEntryObj == null) {
212 log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800213 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700214 return null;
215 }
216
217 //
218 // Set the Flow Entry key:
219 // - flowEntry.flowEntryId()
220 //
221 flowEntryObj.setFlowEntryId(flowEntry.flowEntryId().toString());
222 flowEntryObj.setType("flow_entry");
223
224 //
225 // Set the Flow Entry Edges and attributes:
226 // - Switch edge
227 // - InPort edge
228 // - OutPort edge
229 //
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800230 // - flowEntry.idleTimeout()
231 // - flowEntry.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700232 // - flowEntry.dpid()
233 // - flowEntry.flowEntryUserState()
234 // - flowEntry.flowEntrySwitchState()
235 // - flowEntry.flowEntryErrorState()
236 // - flowEntry.matchInPort()
237 // - flowEntry.matchSrcMac()
238 // - flowEntry.matchDstMac()
239 // - flowEntry.matchEthernetFrameType()
240 // - flowEntry.matchVlanId()
241 // - flowEntry.matchVlanPriority()
242 // - flowEntry.matchSrcIPv4Net()
243 // - flowEntry.matchDstIPv4Net()
244 // - flowEntry.matchIpProto()
245 // - flowEntry.matchIpToS()
246 // - flowEntry.matchSrcTcpUdpPort()
247 // - flowEntry.matchDstTcpUdpPort()
248 // - flowEntry.actionOutputPort()
249 // - flowEntry.actions()
250 //
251 ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString());
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800252 flowEntryObj.setIdleTimeout(flowEntry.idleTimeout());
253 flowEntryObj.setHardTimeout(flowEntry.hardTimeout());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700254 flowEntryObj.setSwitchDpid(flowEntry.dpid().toString());
255 flowEntryObj.setSwitch(sw);
256 if (flowEntry.flowEntryMatch().matchInPort()) {
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800257 IPortObject inport =
258 dbHandler.searchPort(flowEntry.dpid().toString(),
259 flowEntry.flowEntryMatch().inPort().value());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700260 flowEntryObj.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800261 flowEntryObj.setInPort(inport);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700262 }
263 if (flowEntry.flowEntryMatch().matchSrcMac()) {
264 flowEntryObj.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
265 }
266 if (flowEntry.flowEntryMatch().matchDstMac()) {
267 flowEntryObj.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
268 }
269 if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
270 flowEntryObj.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
271 }
272 if (flowEntry.flowEntryMatch().matchVlanId()) {
273 flowEntryObj.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
274 }
275 if (flowEntry.flowEntryMatch().matchVlanPriority()) {
276 flowEntryObj.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
277 }
278 if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
279 flowEntryObj.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
280 }
281 if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
282 flowEntryObj.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
283 }
284 if (flowEntry.flowEntryMatch().matchIpProto()) {
285 flowEntryObj.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
286 }
287 if (flowEntry.flowEntryMatch().matchIpToS()) {
288 flowEntryObj.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
289 }
290 if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
291 flowEntryObj.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
292 }
293 if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
294 flowEntryObj.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
295 }
296
297 for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
298 if (fa.actionOutput() != null) {
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800299 IPortObject outport =
300 dbHandler.searchPort(flowEntry.dpid().toString(),
301 fa.actionOutput().port().value());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700302 flowEntryObj.setActionOutputPort(fa.actionOutput().port().value());
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800303 flowEntryObj.setOutPort(outport);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700304 }
305 }
306 if (! flowEntry.flowEntryActions().isEmpty()) {
307 flowEntryObj.setActions(flowEntry.flowEntryActions().toString());
308 }
309
310 // TODO: Hacks with hard-coded state names!
311 if (found)
312 flowEntryObj.setUserState("FE_USER_MODIFY");
313 else
314 flowEntryObj.setUserState("FE_USER_ADD");
Pavlin Radoslavovebc8b192013-10-29 15:35:35 -0700315 flowEntryObj.setSwitchState(flowEntry.flowEntrySwitchState().toString());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700316 //
317 // TODO: Take care of the FlowEntryErrorState.
318 //
319
320 // Flow Entries edges:
321 // Flow
322 // NextFE (TODO)
323 if (! found) {
324 flowObj.addFlowEntry(flowEntryObj);
325 flowEntryObj.setFlow(flowObj);
326 }
327
328 return flowEntryObj;
329 }
330
331 /**
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700332 * Delete a flow entry from the Network MAP.
333 *
334 * @param dbHandler the Graph Database handler to use.
335 * @param flowObj the corresponding Flow Path object for the Flow Entry.
336 * @param flowEntry the Flow Entry to delete.
337 * @return true on success, otherwise false.
338 */
339 static boolean deleteFlowEntry(GraphDBOperation dbHandler,
340 IFlowPath flowObj,
341 FlowEntry flowEntry) {
342 IFlowEntry flowEntryObj = null;
343 try {
344 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
345 } catch (Exception e) {
346 log.error(":deleteFlowEntry FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800347 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700348 return false;
349 }
350 //
351 // TODO: Don't print an error for now, because multiple controller
352 // instances might be deleting the same flow entry.
353 //
354 /*
355 if (flowEntryObj == null) {
356 log.error(":deleteFlowEntry FlowEntryId:{} failed: FlowEntry object not found",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800357 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700358 return false;
359 }
360 */
361 if (flowEntryObj == null)
362 return true;
363
364 flowObj.removeFlowEntry(flowEntryObj);
365 dbHandler.removeFlowEntry(flowEntryObj);
366 return true;
367 }
368
369 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700370 * Delete all previously added flows.
371 *
372 * @param dbHandler the Graph Database handler to use.
373 * @return true on success, otherwise false.
374 */
375 static boolean deleteAllFlows(GraphDBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700376 List<FlowId> allFlowIds = new LinkedList<FlowId>();
377
378 // Get all Flow IDs
379 Iterable<IFlowPath> allFlowPaths = dbHandler.getAllFlowPaths();
380 for (IFlowPath flowPathObj : allFlowPaths) {
381 if (flowPathObj == null)
382 continue;
383 String flowIdStr = flowPathObj.getFlowId();
384 if (flowIdStr == null)
385 continue;
386 FlowId flowId = new FlowId(flowIdStr);
387 allFlowIds.add(flowId);
388 }
389
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800390 // Delete all flows one-by-one
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700391 for (FlowId flowId : allFlowIds) {
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800392 deleteFlow(dbHandler, flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700393 }
394
395 return true;
396 }
397
398 /**
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800399 * Delete a previously added flow.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700400 *
401 * @param dbHandler the Graph Database handler to use.
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800402 * @param flowId the Flow ID of the flow to delete.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700403 * @return true on success, otherwise false.
404 */
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800405 static boolean deleteFlow(GraphDBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700406 IFlowPath flowObj = null;
407 try {
408 flowObj = dbHandler.searchFlowPath(flowId);
409 } catch (Exception e) {
410 // TODO: handle exceptions
411 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800412 log.error(":deleteFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700413 return false;
414 }
415 if (flowObj == null) {
416 dbHandler.commit();
417 return true; // OK: No such flow
418 }
419
420 //
421 // Remove all Flow Entries
422 //
423 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
424 for (IFlowEntry flowEntryObj : flowEntries) {
425 flowObj.removeFlowEntry(flowEntryObj);
426 dbHandler.removeFlowEntry(flowEntryObj);
427 }
428 // Remove the Flow itself
429 dbHandler.removeFlowPath(flowObj);
430 dbHandler.commit();
431
432 return true;
433 }
434
435 /**
436 * Get a previously added flow.
437 *
438 * @param dbHandler the Graph Database handler to use.
439 * @param flowId the Flow ID of the flow to get.
440 * @return the Flow Path if found, otherwise null.
441 */
442 static FlowPath getFlow(GraphDBOperation dbHandler, FlowId flowId) {
443 IFlowPath flowObj = null;
444 try {
445 flowObj = dbHandler.searchFlowPath(flowId);
446 } catch (Exception e) {
447 // TODO: handle exceptions
448 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800449 log.error(":getFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700450 return null;
451 }
452 if (flowObj == null) {
453 dbHandler.commit();
454 return null; // Flow not found
455 }
456
457 //
458 // Extract the Flow state
459 //
460 FlowPath flowPath = extractFlowPath(flowObj);
461 dbHandler.commit();
462
463 return flowPath;
464 }
465
466 /**
Pavlin Radoslavov8252fee2014-01-07 17:24:29 -0800467 * Get the source switch DPID of a previously added flow.
468 *
469 * @param dbHandler the Graph Database handler to use.
470 * @param flowId the Flow ID of the flow to get.
471 * @return the source switch DPID if found, otherwise null.
472 */
473 static Dpid getFlowSourceDpid(GraphDBOperation dbHandler, FlowId flowId) {
474 IFlowPath flowObj = null;
475 try {
476 flowObj = dbHandler.searchFlowPath(flowId);
477 } catch (Exception e) {
478 // TODO: handle exceptions
479 dbHandler.rollback();
480 log.error(":getFlowSourceDpid FlowId:{} failed", flowId);
481 return null;
482 }
483 if (flowObj == null) {
484 dbHandler.commit();
485 return null; // Flow not found
486 }
487
488 //
489 // Extract the Flow Source DPID
490 //
491 String srcSwitchStr = flowObj.getSrcSwitch();
492 if (srcSwitchStr == null) {
493 // TODO: A work-around, becauuse of some bogus database objects
494 dbHandler.commit();
495 return null;
496 }
497
498 Dpid dpid = new Dpid(srcSwitchStr);
499
500 dbHandler.commit();
501
502 return dpid;
503 }
504
505 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700506 * Get all installed flows by all installers.
507 *
508 * @param dbHandler the Graph Database handler to use.
509 * @return the Flow Paths if found, otherwise null.
510 */
511 static ArrayList<FlowPath> getAllFlows(GraphDBOperation dbHandler) {
512 Iterable<IFlowPath> flowPathsObj = null;
513 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
514
515 try {
516 flowPathsObj = dbHandler.getAllFlowPaths();
517 } catch (Exception e) {
518 // TODO: handle exceptions
519 dbHandler.rollback();
520 log.error(":getAllFlowPaths failed");
521 return flowPaths;
522 }
523 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
524 dbHandler.commit();
525 return flowPaths; // No Flows found
526 }
527
528 for (IFlowPath flowObj : flowPathsObj) {
529 //
530 // Extract the Flow state
531 //
532 FlowPath flowPath = extractFlowPath(flowObj);
533 if (flowPath != null)
534 flowPaths.add(flowPath);
535 }
536
537 dbHandler.commit();
538
539 return flowPaths;
540 }
541
542 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700543 * Extract Flow Path State from a Titan Database Object @ref IFlowPath.
544 *
545 * @param flowObj the object to extract the Flow Path State from.
546 * @return the extracted Flow Path State.
547 */
548 private static FlowPath extractFlowPath(IFlowPath flowObj) {
549 //
550 // Extract the Flow state
551 //
552 String flowIdStr = flowObj.getFlowId();
553 String installerIdStr = flowObj.getInstallerId();
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700554 String flowPathType = flowObj.getFlowPathType();
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700555 String flowPathUserState = flowObj.getFlowPathUserState();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700556 Long flowPathFlags = flowObj.getFlowPathFlags();
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800557 Integer idleTimeout = flowObj.getIdleTimeout();
558 Integer hardTimeout = flowObj.getHardTimeout();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700559 String srcSwitchStr = flowObj.getSrcSwitch();
560 Short srcPortShort = flowObj.getSrcPort();
561 String dstSwitchStr = flowObj.getDstSwitch();
562 Short dstPortShort = flowObj.getDstPort();
563
564 if ((flowIdStr == null) ||
565 (installerIdStr == null) ||
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700566 (flowPathType == null) ||
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700567 (flowPathUserState == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700568 (flowPathFlags == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800569 (idleTimeout == null) ||
570 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700571 (srcSwitchStr == null) ||
572 (srcPortShort == null) ||
573 (dstSwitchStr == null) ||
574 (dstPortShort == null)) {
575 // TODO: A work-around, becauuse of some bogus database objects
576 return null;
577 }
578
579 FlowPath flowPath = new FlowPath();
580 flowPath.setFlowId(new FlowId(flowIdStr));
581 flowPath.setInstallerId(new CallerId(installerIdStr));
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700582 flowPath.setFlowPathType(FlowPathType.valueOf(flowPathType));
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700583 flowPath.setFlowPathUserState(FlowPathUserState.valueOf(flowPathUserState));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700584 flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800585 flowPath.setIdleTimeout(idleTimeout);
586 flowPath.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700587 flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
588 flowPath.dataPath().srcPort().setPort(new Port(srcPortShort));
589 flowPath.dataPath().dstPort().setDpid(new Dpid(dstSwitchStr));
590 flowPath.dataPath().dstPort().setPort(new Port(dstPortShort));
591 //
592 // Extract the match conditions common for all Flow Entries
593 //
594 {
595 FlowEntryMatch match = new FlowEntryMatch();
596 String matchSrcMac = flowObj.getMatchSrcMac();
597 if (matchSrcMac != null)
598 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
599 String matchDstMac = flowObj.getMatchDstMac();
600 if (matchDstMac != null)
601 match.enableDstMac(MACAddress.valueOf(matchDstMac));
602 Short matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
603 if (matchEthernetFrameType != null)
604 match.enableEthernetFrameType(matchEthernetFrameType);
605 Short matchVlanId = flowObj.getMatchVlanId();
606 if (matchVlanId != null)
607 match.enableVlanId(matchVlanId);
608 Byte matchVlanPriority = flowObj.getMatchVlanPriority();
609 if (matchVlanPriority != null)
610 match.enableVlanPriority(matchVlanPriority);
611 String matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
612 if (matchSrcIPv4Net != null)
613 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
614 String matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
615 if (matchDstIPv4Net != null)
616 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
617 Byte matchIpProto = flowObj.getMatchIpProto();
618 if (matchIpProto != null)
619 match.enableIpProto(matchIpProto);
620 Byte matchIpToS = flowObj.getMatchIpToS();
621 if (matchIpToS != null)
622 match.enableIpToS(matchIpToS);
623 Short matchSrcTcpUdpPort = flowObj.getMatchSrcTcpUdpPort();
624 if (matchSrcTcpUdpPort != null)
625 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
626 Short matchDstTcpUdpPort = flowObj.getMatchDstTcpUdpPort();
627 if (matchDstTcpUdpPort != null)
628 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
629
630 flowPath.setFlowEntryMatch(match);
631 }
632 //
633 // Extract the actions for the first Flow Entry
634 //
635 {
636 String actionsStr = flowObj.getActions();
637 if (actionsStr != null) {
638 FlowEntryActions flowEntryActions = new FlowEntryActions(actionsStr);
639 flowPath.setFlowEntryActions(flowEntryActions);
640 }
641 }
642
643 //
644 // Extract all Flow Entries
645 //
646 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
647 for (IFlowEntry flowEntryObj : flowEntries) {
648 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
649 if (flowEntry == null)
650 continue;
651 flowPath.dataPath().flowEntries().add(flowEntry);
652 }
653
654 return flowPath;
655 }
656
657 /**
658 * Extract Flow Entry State from a Titan Database Object @ref IFlowEntry.
659 *
660 * @param flowEntryObj the object to extract the Flow Entry State from.
661 * @return the extracted Flow Entry State.
662 */
Brian O'Connora8e49802013-10-30 20:49:59 -0700663 public static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800664 IFlowPath flowObj = flowEntryObj.getFlow();
665 if (flowObj == null)
666 return null;
667
668 String flowIdStr = flowObj.getFlowId();
669 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700670 String flowEntryIdStr = flowEntryObj.getFlowEntryId();
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800671 Integer idleTimeout = flowEntryObj.getIdleTimeout();
672 Integer hardTimeout = flowEntryObj.getHardTimeout();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700673 String switchDpidStr = flowEntryObj.getSwitchDpid();
674 String userState = flowEntryObj.getUserState();
675 String switchState = flowEntryObj.getSwitchState();
676
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800677 if ((flowIdStr == null) ||
678 (flowEntryIdStr == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800679 (idleTimeout == null) ||
680 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700681 (switchDpidStr == null) ||
682 (userState == null) ||
683 (switchState == null)) {
Brian O'Connora8e49802013-10-30 20:49:59 -0700684 // TODO: A work-around, because of some bogus database objects
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700685 return null;
686 }
687
688 FlowEntry flowEntry = new FlowEntry();
689 flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800690 flowEntry.setFlowId(new FlowId(flowIdStr));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700691 flowEntry.setDpid(new Dpid(switchDpidStr));
Pavlin Radoslavovce93a032013-12-13 11:03:02 -0800692 flowEntry.setIdleTimeout(idleTimeout);
693 flowEntry.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700694
695 //
696 // Extract the match conditions
697 //
698 FlowEntryMatch match = new FlowEntryMatch();
699 Short matchInPort = flowEntryObj.getMatchInPort();
700 if (matchInPort != null)
701 match.enableInPort(new Port(matchInPort));
702 String matchSrcMac = flowEntryObj.getMatchSrcMac();
703 if (matchSrcMac != null)
704 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
705 String matchDstMac = flowEntryObj.getMatchDstMac();
706 if (matchDstMac != null)
707 match.enableDstMac(MACAddress.valueOf(matchDstMac));
708 Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
709 if (matchEthernetFrameType != null)
710 match.enableEthernetFrameType(matchEthernetFrameType);
711 Short matchVlanId = flowEntryObj.getMatchVlanId();
712 if (matchVlanId != null)
713 match.enableVlanId(matchVlanId);
714 Byte matchVlanPriority = flowEntryObj.getMatchVlanPriority();
715 if (matchVlanPriority != null)
716 match.enableVlanPriority(matchVlanPriority);
717 String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
718 if (matchSrcIPv4Net != null)
719 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
720 String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
721 if (matchDstIPv4Net != null)
722 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
723 Byte matchIpProto = flowEntryObj.getMatchIpProto();
724 if (matchIpProto != null)
725 match.enableIpProto(matchIpProto);
726 Byte matchIpToS = flowEntryObj.getMatchIpToS();
727 if (matchIpToS != null)
728 match.enableIpToS(matchIpToS);
729 Short matchSrcTcpUdpPort = flowEntryObj.getMatchSrcTcpUdpPort();
730 if (matchSrcTcpUdpPort != null)
731 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
732 Short matchDstTcpUdpPort = flowEntryObj.getMatchDstTcpUdpPort();
733 if (matchDstTcpUdpPort != null)
734 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
735 flowEntry.setFlowEntryMatch(match);
736
737 //
738 // Extract the actions
739 //
740 FlowEntryActions actions = new FlowEntryActions();
741 String actionsStr = flowEntryObj.getActions();
742 if (actionsStr != null)
743 actions = new FlowEntryActions(actionsStr);
744 flowEntry.setFlowEntryActions(actions);
745 flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
746 flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
747 //
748 // TODO: Take care of FlowEntryErrorState.
749 //
750 return flowEntry;
751 }
752}