blob: a96f5dcdd18572d40a96629528e4f86c8dca6d06 [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;
6import java.util.Collections;
7import java.util.Comparator;
8import java.util.LinkedList;
9import java.util.List;
10import java.util.concurrent.ConcurrentLinkedQueue;
11
12import net.floodlightcontroller.util.MACAddress;
13
14import net.onrc.onos.graph.GraphDBOperation;
15
16import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
17import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
18import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
19import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
20import net.onrc.onos.ofcontroller.util.*;
21
22import org.slf4j.Logger;
23import org.slf4j.LoggerFactory;
24
25/**
26 * Class for performing Flow-related operations on the Database.
27 */
Pavlin Radoslavov6bfaea62013-12-03 14:55:57 -080028public class FlowDatabaseOperation {
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070029 private final static Logger log = LoggerFactory.getLogger(FlowDatabaseOperation.class);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070030
31 /**
32 * Add a flow.
33 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070034 * @param dbHandler the Graph Database handler to use.
35 * @param flowPath the Flow Path to install.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070036 * @return true on success, otherwise false.
37 */
Pavlin Radoslavov051abb42013-12-05 17:24:50 -080038 static boolean addFlow(GraphDBOperation dbHandler, FlowPath flowPath) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070039 IFlowPath flowObj = null;
40 boolean found = false;
41 try {
42 if ((flowObj = dbHandler.searchFlowPath(flowPath.flowId())) != null) {
43 found = true;
44 } else {
45 flowObj = dbHandler.newFlowPath();
46 }
47 } catch (Exception e) {
48 dbHandler.rollback();
49
50 StringWriter sw = new StringWriter();
51 e.printStackTrace(new PrintWriter(sw));
52 String stacktrace = sw.toString();
53
54 log.error(":addFlow FlowId:{} failed: {}",
55 flowPath.flowId().toString(),
56 stacktrace);
57 return false;
58 }
59 if (flowObj == null) {
60 log.error(":addFlow FlowId:{} failed: Flow object not created",
61 flowPath.flowId().toString());
62 dbHandler.rollback();
63 return false;
64 }
65
66 //
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -080067 // Remove the old Flow Entries
68 //
69 if (found) {
70 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
71 LinkedList<IFlowEntry> deleteFlowEntries =
72 new LinkedList<IFlowEntry>();
73 for (IFlowEntry flowEntryObj : flowEntries)
74 deleteFlowEntries.add(flowEntryObj);
75 for (IFlowEntry flowEntryObj : deleteFlowEntries) {
76 flowObj.removeFlowEntry(flowEntryObj);
77 dbHandler.removeFlowEntry(flowEntryObj);
78 }
79 }
80
81 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070082 // Set the Flow key:
83 // - flowId
84 //
85 flowObj.setFlowId(flowPath.flowId().toString());
86 flowObj.setType("flow");
87
88 //
89 // Set the Flow attributes:
90 // - flowPath.installerId()
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -070091 // - flowPath.flowPathType()
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -070092 // - flowPath.flowPathUserState()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070093 // - flowPath.flowPathFlags()
94 // - flowPath.dataPath().srcPort()
95 // - flowPath.dataPath().dstPort()
96 // - flowPath.matchSrcMac()
97 // - flowPath.matchDstMac()
98 // - flowPath.matchEthernetFrameType()
99 // - flowPath.matchVlanId()
100 // - flowPath.matchVlanPriority()
101 // - flowPath.matchSrcIPv4Net()
102 // - flowPath.matchDstIPv4Net()
103 // - flowPath.matchIpProto()
104 // - flowPath.matchIpToS()
105 // - flowPath.matchSrcTcpUdpPort()
106 // - flowPath.matchDstTcpUdpPort()
107 // - flowPath.flowEntryActions()
108 //
109 flowObj.setInstallerId(flowPath.installerId().toString());
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700110 flowObj.setFlowPathType(flowPath.flowPathType().toString());
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700111 flowObj.setFlowPathUserState(flowPath.flowPathUserState().toString());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700112 flowObj.setFlowPathFlags(flowPath.flowPathFlags().flags());
113 flowObj.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
114 flowObj.setSrcPort(flowPath.dataPath().srcPort().port().value());
115 flowObj.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
116 flowObj.setDstPort(flowPath.dataPath().dstPort().port().value());
117 if (flowPath.flowEntryMatch().matchSrcMac()) {
118 flowObj.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
119 }
120 if (flowPath.flowEntryMatch().matchDstMac()) {
121 flowObj.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
122 }
123 if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
124 flowObj.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
125 }
126 if (flowPath.flowEntryMatch().matchVlanId()) {
127 flowObj.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
128 }
129 if (flowPath.flowEntryMatch().matchVlanPriority()) {
130 flowObj.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
131 }
132 if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
133 flowObj.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
134 }
135 if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
136 flowObj.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
137 }
138 if (flowPath.flowEntryMatch().matchIpProto()) {
139 flowObj.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
140 }
141 if (flowPath.flowEntryMatch().matchIpToS()) {
142 flowObj.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
143 }
144 if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
145 flowObj.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
146 }
147 if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
148 flowObj.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
149 }
150 if (! flowPath.flowEntryActions().actions().isEmpty()) {
151 flowObj.setActions(flowPath.flowEntryActions().toString());
152 }
Pavlin Radoslavovbcc86ef2013-10-26 12:06:25 -0700153 flowObj.setDataPathSummary(flowPath.dataPath().dataPathSummary());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700154
155 if (found)
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700156 flowObj.setFlowPathUserState("FP_USER_MODIFY");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700157 else
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700158 flowObj.setFlowPathUserState("FP_USER_ADD");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700159
160 // Flow edges:
161 // HeadFE
162
163
164 //
165 // Flow Entries:
166 // flowPath.dataPath().flowEntries()
167 //
168 for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800169 if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE)
170 continue; // Skip: all Flow Entries were deleted earlier
171
Pavlin Radoslavov67bf7622013-12-04 12:28:23 -0800172 if (addFlowEntry(dbHandler, flowObj, flowEntry) == null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700173 dbHandler.rollback();
174 return false;
175 }
176 }
177 dbHandler.commit();
178
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700179 return true;
180 }
181
182 /**
183 * Add a flow entry to the Network MAP.
184 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700185 * @param dbHandler the Graph Database handler to use.
186 * @param flowObj the corresponding Flow Path object for the Flow Entry.
187 * @param flowEntry the Flow Entry to install.
188 * @return the added Flow Entry object on success, otherwise null.
189 */
Pavlin Radoslavov67bf7622013-12-04 12:28:23 -0800190 static IFlowEntry addFlowEntry(GraphDBOperation dbHandler,
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700191 IFlowPath flowObj,
192 FlowEntry flowEntry) {
193 // Flow edges
194 // HeadFE (TODO)
195
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700196 IFlowEntry flowEntryObj = null;
197 boolean found = false;
198 try {
199 if ((flowEntryObj =
200 dbHandler.searchFlowEntry(flowEntry.flowEntryId())) != null) {
201 found = true;
202 } else {
203 flowEntryObj = dbHandler.newFlowEntry();
204 }
205 } catch (Exception e) {
206 log.error(":addFlow FlowEntryId:{} failed",
207 flowEntry.flowEntryId().toString());
208 return null;
209 }
210 if (flowEntryObj == null) {
211 log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created",
212 flowEntry.flowEntryId().toString());
213 return null;
214 }
215
216 //
217 // Set the Flow Entry key:
218 // - flowEntry.flowEntryId()
219 //
220 flowEntryObj.setFlowEntryId(flowEntry.flowEntryId().toString());
221 flowEntryObj.setType("flow_entry");
222
223 //
224 // Set the Flow Entry Edges and attributes:
225 // - Switch edge
226 // - InPort edge
227 // - OutPort edge
228 //
229 // - flowEntry.dpid()
230 // - flowEntry.flowEntryUserState()
231 // - flowEntry.flowEntrySwitchState()
232 // - flowEntry.flowEntryErrorState()
233 // - flowEntry.matchInPort()
234 // - flowEntry.matchSrcMac()
235 // - flowEntry.matchDstMac()
236 // - flowEntry.matchEthernetFrameType()
237 // - flowEntry.matchVlanId()
238 // - flowEntry.matchVlanPriority()
239 // - flowEntry.matchSrcIPv4Net()
240 // - flowEntry.matchDstIPv4Net()
241 // - flowEntry.matchIpProto()
242 // - flowEntry.matchIpToS()
243 // - flowEntry.matchSrcTcpUdpPort()
244 // - flowEntry.matchDstTcpUdpPort()
245 // - flowEntry.actionOutputPort()
246 // - flowEntry.actions()
247 //
248 ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString());
249 flowEntryObj.setSwitchDpid(flowEntry.dpid().toString());
250 flowEntryObj.setSwitch(sw);
251 if (flowEntry.flowEntryMatch().matchInPort()) {
Jonathan Hartcc1eb8a2013-12-05 11:34:27 -0800252 //IPortObject inport =
253 //dbHandler.searchPort(flowEntry.dpid().toString(),
254 //flowEntry.flowEntryMatch().inPort().value());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700255 flowEntryObj.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
Jonathan Hartcc1eb8a2013-12-05 11:34:27 -0800256 //flowEntryObj.setInPort(inport);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700257 }
258 if (flowEntry.flowEntryMatch().matchSrcMac()) {
259 flowEntryObj.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
260 }
261 if (flowEntry.flowEntryMatch().matchDstMac()) {
262 flowEntryObj.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
263 }
264 if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
265 flowEntryObj.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
266 }
267 if (flowEntry.flowEntryMatch().matchVlanId()) {
268 flowEntryObj.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
269 }
270 if (flowEntry.flowEntryMatch().matchVlanPriority()) {
271 flowEntryObj.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
272 }
273 if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
274 flowEntryObj.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
275 }
276 if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
277 flowEntryObj.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
278 }
279 if (flowEntry.flowEntryMatch().matchIpProto()) {
280 flowEntryObj.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
281 }
282 if (flowEntry.flowEntryMatch().matchIpToS()) {
283 flowEntryObj.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
284 }
285 if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
286 flowEntryObj.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
287 }
288 if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
289 flowEntryObj.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
290 }
291
292 for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
293 if (fa.actionOutput() != null) {
Jonathan Hartcc1eb8a2013-12-05 11:34:27 -0800294 //IPortObject outport =
295 //dbHandler.searchPort(flowEntry.dpid().toString(),
296 //fa.actionOutput().port().value());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700297 flowEntryObj.setActionOutputPort(fa.actionOutput().port().value());
Jonathan Hartcc1eb8a2013-12-05 11:34:27 -0800298 //flowEntryObj.setOutPort(outport);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700299 }
300 }
301 if (! flowEntry.flowEntryActions().isEmpty()) {
302 flowEntryObj.setActions(flowEntry.flowEntryActions().toString());
303 }
304
305 // TODO: Hacks with hard-coded state names!
306 if (found)
307 flowEntryObj.setUserState("FE_USER_MODIFY");
308 else
309 flowEntryObj.setUserState("FE_USER_ADD");
Pavlin Radoslavovebc8b192013-10-29 15:35:35 -0700310 flowEntryObj.setSwitchState(flowEntry.flowEntrySwitchState().toString());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700311 //
312 // TODO: Take care of the FlowEntryErrorState.
313 //
314
315 // Flow Entries edges:
316 // Flow
317 // NextFE (TODO)
318 if (! found) {
319 flowObj.addFlowEntry(flowEntryObj);
320 flowEntryObj.setFlow(flowObj);
321 }
322
323 return flowEntryObj;
324 }
325
326 /**
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700327 * Delete a flow entry from the Network MAP.
328 *
329 * @param dbHandler the Graph Database handler to use.
330 * @param flowObj the corresponding Flow Path object for the Flow Entry.
331 * @param flowEntry the Flow Entry to delete.
332 * @return true on success, otherwise false.
333 */
334 static boolean deleteFlowEntry(GraphDBOperation dbHandler,
335 IFlowPath flowObj,
336 FlowEntry flowEntry) {
337 IFlowEntry flowEntryObj = null;
338 try {
339 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
340 } catch (Exception e) {
341 log.error(":deleteFlowEntry FlowEntryId:{} failed",
342 flowEntry.flowEntryId().toString());
343 return false;
344 }
345 //
346 // TODO: Don't print an error for now, because multiple controller
347 // instances might be deleting the same flow entry.
348 //
349 /*
350 if (flowEntryObj == null) {
351 log.error(":deleteFlowEntry FlowEntryId:{} failed: FlowEntry object not found",
352 flowEntry.flowEntryId().toString());
353 return false;
354 }
355 */
356 if (flowEntryObj == null)
357 return true;
358
359 flowObj.removeFlowEntry(flowEntryObj);
360 dbHandler.removeFlowEntry(flowEntryObj);
361 return true;
362 }
363
364 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700365 * Delete all previously added flows.
366 *
367 * @param dbHandler the Graph Database handler to use.
368 * @return true on success, otherwise false.
369 */
370 static boolean deleteAllFlows(GraphDBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700371 List<FlowId> allFlowIds = new LinkedList<FlowId>();
372
373 // Get all Flow IDs
374 Iterable<IFlowPath> allFlowPaths = dbHandler.getAllFlowPaths();
375 for (IFlowPath flowPathObj : allFlowPaths) {
376 if (flowPathObj == null)
377 continue;
378 String flowIdStr = flowPathObj.getFlowId();
379 if (flowIdStr == null)
380 continue;
381 FlowId flowId = new FlowId(flowIdStr);
382 allFlowIds.add(flowId);
383 }
384
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800385 // Delete all flows one-by-one
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700386 for (FlowId flowId : allFlowIds) {
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800387 deleteFlow(dbHandler, flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700388 }
389
390 return true;
391 }
392
393 /**
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800394 * Delete a previously added flow.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700395 *
396 * @param dbHandler the Graph Database handler to use.
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800397 * @param flowId the Flow ID of the flow to delete.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700398 * @return true on success, otherwise false.
399 */
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800400 static boolean deleteFlow(GraphDBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700401 IFlowPath flowObj = null;
402 try {
403 flowObj = dbHandler.searchFlowPath(flowId);
404 } catch (Exception e) {
405 // TODO: handle exceptions
406 dbHandler.rollback();
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800407 log.error(":deleteFlow FlowId:{} failed", flowId.toString());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700408 return false;
409 }
410 if (flowObj == null) {
411 dbHandler.commit();
412 return true; // OK: No such flow
413 }
414
415 //
416 // Remove all Flow Entries
417 //
418 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
419 for (IFlowEntry flowEntryObj : flowEntries) {
420 flowObj.removeFlowEntry(flowEntryObj);
421 dbHandler.removeFlowEntry(flowEntryObj);
422 }
423 // Remove the Flow itself
424 dbHandler.removeFlowPath(flowObj);
425 dbHandler.commit();
426
427 return true;
428 }
429
430 /**
431 * Get a previously added flow.
432 *
433 * @param dbHandler the Graph Database handler to use.
434 * @param flowId the Flow ID of the flow to get.
435 * @return the Flow Path if found, otherwise null.
436 */
437 static FlowPath getFlow(GraphDBOperation dbHandler, FlowId flowId) {
438 IFlowPath flowObj = null;
439 try {
440 flowObj = dbHandler.searchFlowPath(flowId);
441 } catch (Exception e) {
442 // TODO: handle exceptions
443 dbHandler.rollback();
444 log.error(":getFlow FlowId:{} failed", flowId.toString());
445 return null;
446 }
447 if (flowObj == null) {
448 dbHandler.commit();
449 return null; // Flow not found
450 }
451
452 //
453 // Extract the Flow state
454 //
455 FlowPath flowPath = extractFlowPath(flowObj);
456 dbHandler.commit();
457
458 return flowPath;
459 }
460
461 /**
462 * Get all installed flows by all installers.
463 *
464 * @param dbHandler the Graph Database handler to use.
465 * @return the Flow Paths if found, otherwise null.
466 */
467 static ArrayList<FlowPath> getAllFlows(GraphDBOperation dbHandler) {
468 Iterable<IFlowPath> flowPathsObj = null;
469 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
470
471 try {
472 flowPathsObj = dbHandler.getAllFlowPaths();
473 } catch (Exception e) {
474 // TODO: handle exceptions
475 dbHandler.rollback();
476 log.error(":getAllFlowPaths failed");
477 return flowPaths;
478 }
479 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
480 dbHandler.commit();
481 return flowPaths; // No Flows found
482 }
483
484 for (IFlowPath flowObj : flowPathsObj) {
485 //
486 // Extract the Flow state
487 //
488 FlowPath flowPath = extractFlowPath(flowObj);
489 if (flowPath != null)
490 flowPaths.add(flowPath);
491 }
492
493 dbHandler.commit();
494
495 return flowPaths;
496 }
497
498 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700499 * Get summary of all installed flows by all installers in a given range.
500 *
501 * @param dbHandler the Graph Database handler to use.
502 * @param flowId the Flow ID of the first flow in the flow range to get.
503 * @param maxFlows the maximum number of flows to be returned.
504 * @return the Flow Paths if found, otherwise null.
505 */
Pavlin Radoslavov4ef6ba22013-11-22 19:32:58 -0800506 static ArrayList<FlowPath> getAllFlowsSummary(GraphDBOperation dbHandler,
507 FlowId flowId,
508 int maxFlows) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700509 //
510 // TODO: The implementation below is not optimal:
511 // We fetch all flows, and then return only the subset that match
512 // the query conditions.
513 // We should use the appropriate Titan/Gremlin query to filter-out
514 // the flows as appropriate.
515 //
Pavlin Radoslavov4ef6ba22013-11-22 19:32:58 -0800516 ArrayList<FlowPath> flowPaths = getAllFlowsWithDataPathSummary(dbHandler);
517 Collections.sort(flowPaths);
518 return flowPaths;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700519 }
520
521 /**
Pavlin Radoslavov4ef6ba22013-11-22 19:32:58 -0800522 * Get all Flows information, with Data Path summary for the Flow Entries.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700523 *
524 * @param dbHandler the Graph Database handler to use.
Pavlin Radoslavov4ef6ba22013-11-22 19:32:58 -0800525 * @return all Flows information, with Data Path summary for the Flow
526 * Entries.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700527 */
Pavlin Radoslavov4ef6ba22013-11-22 19:32:58 -0800528 static ArrayList<FlowPath> getAllFlowsWithDataPathSummary(GraphDBOperation dbHandler) {
529 ArrayList<FlowPath> flowPaths = getAllFlows(dbHandler);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700530
Pavlin Radoslavov4ef6ba22013-11-22 19:32:58 -0800531 // Truncate each Flow Path and Flow Entry
532 for (FlowPath flowPath : flowPaths) {
533 flowPath.setFlowEntryMatch(null);
534 flowPath.setFlowEntryActions(null);
535 for (FlowEntry flowEntry : flowPath.flowEntries()) {
536 flowEntry.setFlowEntryMatch(null);
537 flowEntry.setFlowEntryActions(null);
538 }
539 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700540
Pavlin Radoslavov4ef6ba22013-11-22 19:32:58 -0800541 return flowPaths;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700542 }
543
544 /**
545 * Extract Flow Path State from a Titan Database Object @ref IFlowPath.
546 *
547 * @param flowObj the object to extract the Flow Path State from.
548 * @return the extracted Flow Path State.
549 */
550 private static FlowPath extractFlowPath(IFlowPath flowObj) {
551 //
552 // Extract the Flow state
553 //
554 String flowIdStr = flowObj.getFlowId();
555 String installerIdStr = flowObj.getInstallerId();
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700556 String flowPathType = flowObj.getFlowPathType();
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700557 String flowPathUserState = flowObj.getFlowPathUserState();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700558 Long flowPathFlags = flowObj.getFlowPathFlags();
559 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) ||
569 (srcSwitchStr == null) ||
570 (srcPortShort == null) ||
571 (dstSwitchStr == null) ||
572 (dstPortShort == null)) {
573 // TODO: A work-around, becauuse of some bogus database objects
574 return null;
575 }
576
577 FlowPath flowPath = new FlowPath();
578 flowPath.setFlowId(new FlowId(flowIdStr));
579 flowPath.setInstallerId(new CallerId(installerIdStr));
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700580 flowPath.setFlowPathType(FlowPathType.valueOf(flowPathType));
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700581 flowPath.setFlowPathUserState(FlowPathUserState.valueOf(flowPathUserState));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700582 flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
583 flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
584 flowPath.dataPath().srcPort().setPort(new Port(srcPortShort));
585 flowPath.dataPath().dstPort().setDpid(new Dpid(dstSwitchStr));
586 flowPath.dataPath().dstPort().setPort(new Port(dstPortShort));
587 //
588 // Extract the match conditions common for all Flow Entries
589 //
590 {
591 FlowEntryMatch match = new FlowEntryMatch();
592 String matchSrcMac = flowObj.getMatchSrcMac();
593 if (matchSrcMac != null)
594 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
595 String matchDstMac = flowObj.getMatchDstMac();
596 if (matchDstMac != null)
597 match.enableDstMac(MACAddress.valueOf(matchDstMac));
598 Short matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
599 if (matchEthernetFrameType != null)
600 match.enableEthernetFrameType(matchEthernetFrameType);
601 Short matchVlanId = flowObj.getMatchVlanId();
602 if (matchVlanId != null)
603 match.enableVlanId(matchVlanId);
604 Byte matchVlanPriority = flowObj.getMatchVlanPriority();
605 if (matchVlanPriority != null)
606 match.enableVlanPriority(matchVlanPriority);
607 String matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
608 if (matchSrcIPv4Net != null)
609 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
610 String matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
611 if (matchDstIPv4Net != null)
612 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
613 Byte matchIpProto = flowObj.getMatchIpProto();
614 if (matchIpProto != null)
615 match.enableIpProto(matchIpProto);
616 Byte matchIpToS = flowObj.getMatchIpToS();
617 if (matchIpToS != null)
618 match.enableIpToS(matchIpToS);
619 Short matchSrcTcpUdpPort = flowObj.getMatchSrcTcpUdpPort();
620 if (matchSrcTcpUdpPort != null)
621 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
622 Short matchDstTcpUdpPort = flowObj.getMatchDstTcpUdpPort();
623 if (matchDstTcpUdpPort != null)
624 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
625
626 flowPath.setFlowEntryMatch(match);
627 }
628 //
629 // Extract the actions for the first Flow Entry
630 //
631 {
632 String actionsStr = flowObj.getActions();
633 if (actionsStr != null) {
634 FlowEntryActions flowEntryActions = new FlowEntryActions(actionsStr);
635 flowPath.setFlowEntryActions(flowEntryActions);
636 }
637 }
638
639 //
640 // Extract all Flow Entries
641 //
642 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
643 for (IFlowEntry flowEntryObj : flowEntries) {
644 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
645 if (flowEntry == null)
646 continue;
647 flowPath.dataPath().flowEntries().add(flowEntry);
648 }
649
650 return flowPath;
651 }
652
653 /**
654 * Extract Flow Entry State from a Titan Database Object @ref IFlowEntry.
655 *
656 * @param flowEntryObj the object to extract the Flow Entry State from.
657 * @return the extracted Flow Entry State.
658 */
Brian O'Connora8e49802013-10-30 20:49:59 -0700659 public static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700660 String flowEntryIdStr = flowEntryObj.getFlowEntryId();
661 String switchDpidStr = flowEntryObj.getSwitchDpid();
662 String userState = flowEntryObj.getUserState();
663 String switchState = flowEntryObj.getSwitchState();
664
665 if ((flowEntryIdStr == null) ||
666 (switchDpidStr == null) ||
667 (userState == null) ||
668 (switchState == null)) {
Brian O'Connora8e49802013-10-30 20:49:59 -0700669 // TODO: A work-around, because of some bogus database objects
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700670 return null;
671 }
672
673 FlowEntry flowEntry = new FlowEntry();
674 flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
675 flowEntry.setDpid(new Dpid(switchDpidStr));
676
677 //
678 // Extract the match conditions
679 //
680 FlowEntryMatch match = new FlowEntryMatch();
681 Short matchInPort = flowEntryObj.getMatchInPort();
682 if (matchInPort != null)
683 match.enableInPort(new Port(matchInPort));
684 String matchSrcMac = flowEntryObj.getMatchSrcMac();
685 if (matchSrcMac != null)
686 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
687 String matchDstMac = flowEntryObj.getMatchDstMac();
688 if (matchDstMac != null)
689 match.enableDstMac(MACAddress.valueOf(matchDstMac));
690 Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
691 if (matchEthernetFrameType != null)
692 match.enableEthernetFrameType(matchEthernetFrameType);
693 Short matchVlanId = flowEntryObj.getMatchVlanId();
694 if (matchVlanId != null)
695 match.enableVlanId(matchVlanId);
696 Byte matchVlanPriority = flowEntryObj.getMatchVlanPriority();
697 if (matchVlanPriority != null)
698 match.enableVlanPriority(matchVlanPriority);
699 String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
700 if (matchSrcIPv4Net != null)
701 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
702 String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
703 if (matchDstIPv4Net != null)
704 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
705 Byte matchIpProto = flowEntryObj.getMatchIpProto();
706 if (matchIpProto != null)
707 match.enableIpProto(matchIpProto);
708 Byte matchIpToS = flowEntryObj.getMatchIpToS();
709 if (matchIpToS != null)
710 match.enableIpToS(matchIpToS);
711 Short matchSrcTcpUdpPort = flowEntryObj.getMatchSrcTcpUdpPort();
712 if (matchSrcTcpUdpPort != null)
713 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
714 Short matchDstTcpUdpPort = flowEntryObj.getMatchDstTcpUdpPort();
715 if (matchDstTcpUdpPort != null)
716 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
717 flowEntry.setFlowEntryMatch(match);
718
719 //
720 // Extract the actions
721 //
722 FlowEntryActions actions = new FlowEntryActions();
723 String actionsStr = flowEntryObj.getActions();
724 if (actionsStr != null)
725 actions = new FlowEntryActions(actionsStr);
726 flowEntry.setFlowEntryActions(actions);
727 flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
728 flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
729 //
730 // TODO: Take care of FlowEntryErrorState.
731 //
732 return flowEntry;
733 }
734}