blob: c3d750128e00f1f34303ab911eece7403105652a [file] [log] [blame]
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001package net.onrc.onos.ofcontroller.flowmanager;
2
3import java.io.PrintWriter;
4import java.io.StringWriter;
5import java.util.ArrayList;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07006import java.util.LinkedList;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07007import net.floodlightcontroller.util.MACAddress;
8
9import net.onrc.onos.graph.GraphDBOperation;
10
11import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
12import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
13import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
14import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
15import net.onrc.onos.ofcontroller.util.*;
16
17import org.slf4j.Logger;
18import org.slf4j.LoggerFactory;
19
20/**
21 * Class for performing Flow-related operations on the Database.
22 */
Pavlin Radoslavov6bfaea62013-12-03 14:55:57 -080023public class FlowDatabaseOperation {
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070024 private final static Logger log = LoggerFactory.getLogger(FlowDatabaseOperation.class);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070025
26 /**
27 * Add a flow.
28 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070029 * @param dbHandler the Graph Database handler to use.
30 * @param flowPath the Flow Path to install.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070031 * @return true on success, otherwise false.
32 */
Pavlin Radoslavov051abb42013-12-05 17:24:50 -080033 static boolean addFlow(GraphDBOperation dbHandler, FlowPath flowPath) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070034 IFlowPath flowObj = null;
35 boolean found = false;
36 try {
37 if ((flowObj = dbHandler.searchFlowPath(flowPath.flowId())) != null) {
38 found = true;
39 } else {
40 flowObj = dbHandler.newFlowPath();
41 }
42 } catch (Exception e) {
43 dbHandler.rollback();
44
45 StringWriter sw = new StringWriter();
46 e.printStackTrace(new PrintWriter(sw));
47 String stacktrace = sw.toString();
48
49 log.error(":addFlow FlowId:{} failed: {}",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -080050 flowPath.flowId(),
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070051 stacktrace);
52 return false;
53 }
54 if (flowObj == null) {
55 log.error(":addFlow FlowId:{} failed: Flow object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -080056 flowPath.flowId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070057 dbHandler.rollback();
58 return false;
59 }
60
61 //
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -080062 // Remove the old Flow Entries
63 //
64 if (found) {
65 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
66 LinkedList<IFlowEntry> deleteFlowEntries =
67 new LinkedList<IFlowEntry>();
68 for (IFlowEntry flowEntryObj : flowEntries)
69 deleteFlowEntries.add(flowEntryObj);
70 for (IFlowEntry flowEntryObj : deleteFlowEntries) {
71 flowObj.removeFlowEntry(flowEntryObj);
72 dbHandler.removeFlowEntry(flowEntryObj);
73 }
74 }
75
76 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070077 // Set the Flow key:
78 // - flowId
79 //
80 flowObj.setFlowId(flowPath.flowId().toString());
81 flowObj.setType("flow");
82
83 //
84 // Set the Flow attributes:
85 // - flowPath.installerId()
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -070086 // - flowPath.flowPathType()
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -070087 // - flowPath.flowPathUserState()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070088 // - flowPath.flowPathFlags()
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -080089 // - flowPath.idleTimeout()
90 // - flowPath.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070091 // - flowPath.dataPath().srcPort()
92 // - flowPath.dataPath().dstPort()
93 // - flowPath.matchSrcMac()
94 // - flowPath.matchDstMac()
95 // - flowPath.matchEthernetFrameType()
96 // - flowPath.matchVlanId()
97 // - flowPath.matchVlanPriority()
98 // - flowPath.matchSrcIPv4Net()
99 // - flowPath.matchDstIPv4Net()
100 // - flowPath.matchIpProto()
101 // - flowPath.matchIpToS()
102 // - flowPath.matchSrcTcpUdpPort()
103 // - flowPath.matchDstTcpUdpPort()
104 // - flowPath.flowEntryActions()
105 //
106 flowObj.setInstallerId(flowPath.installerId().toString());
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700107 flowObj.setFlowPathType(flowPath.flowPathType().toString());
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700108 flowObj.setFlowPathUserState(flowPath.flowPathUserState().toString());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700109 flowObj.setFlowPathFlags(flowPath.flowPathFlags().flags());
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800110 flowObj.setIdleTimeout(flowPath.idleTimeout());
111 flowObj.setHardTimeout(flowPath.hardTimeout());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700112 flowObj.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
113 flowObj.setSrcPort(flowPath.dataPath().srcPort().port().value());
114 flowObj.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
115 flowObj.setDstPort(flowPath.dataPath().dstPort().port().value());
116 if (flowPath.flowEntryMatch().matchSrcMac()) {
117 flowObj.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
118 }
119 if (flowPath.flowEntryMatch().matchDstMac()) {
120 flowObj.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
121 }
122 if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
123 flowObj.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
124 }
125 if (flowPath.flowEntryMatch().matchVlanId()) {
126 flowObj.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
127 }
128 if (flowPath.flowEntryMatch().matchVlanPriority()) {
129 flowObj.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
130 }
131 if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
132 flowObj.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
133 }
134 if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
135 flowObj.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
136 }
137 if (flowPath.flowEntryMatch().matchIpProto()) {
138 flowObj.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
139 }
140 if (flowPath.flowEntryMatch().matchIpToS()) {
141 flowObj.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
142 }
143 if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
144 flowObj.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
145 }
146 if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
147 flowObj.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
148 }
149 if (! flowPath.flowEntryActions().actions().isEmpty()) {
150 flowObj.setActions(flowPath.flowEntryActions().toString());
151 }
Pavlin Radoslavovbcc86ef2013-10-26 12:06:25 -0700152 flowObj.setDataPathSummary(flowPath.dataPath().dataPathSummary());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700153
154 if (found)
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700155 flowObj.setFlowPathUserState("FP_USER_MODIFY");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700156 else
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700157 flowObj.setFlowPathUserState("FP_USER_ADD");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700158
159 // Flow edges:
160 // HeadFE
161
162
163 //
164 // Flow Entries:
165 // flowPath.dataPath().flowEntries()
166 //
167 for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800168 if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE)
169 continue; // Skip: all Flow Entries were deleted earlier
170
Pavlin Radoslavov67bf7622013-12-04 12:28:23 -0800171 if (addFlowEntry(dbHandler, flowObj, flowEntry) == null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700172 dbHandler.rollback();
173 return false;
174 }
175 }
176 dbHandler.commit();
177
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700178 return true;
179 }
180
181 /**
182 * Add a flow entry to the Network MAP.
183 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700184 * @param dbHandler the Graph Database handler to use.
185 * @param flowObj the corresponding Flow Path object for the Flow Entry.
186 * @param flowEntry the Flow Entry to install.
187 * @return the added Flow Entry object on success, otherwise null.
188 */
Pavlin Radoslavov67bf7622013-12-04 12:28:23 -0800189 static IFlowEntry addFlowEntry(GraphDBOperation dbHandler,
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700190 IFlowPath flowObj,
191 FlowEntry flowEntry) {
192 // Flow edges
193 // HeadFE (TODO)
194
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700195 IFlowEntry flowEntryObj = null;
196 boolean found = false;
197 try {
198 if ((flowEntryObj =
199 dbHandler.searchFlowEntry(flowEntry.flowEntryId())) != null) {
200 found = true;
201 } else {
202 flowEntryObj = dbHandler.newFlowEntry();
203 }
204 } catch (Exception e) {
205 log.error(":addFlow FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800206 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700207 return null;
208 }
209 if (flowEntryObj == null) {
210 log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800211 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700212 return null;
213 }
214
215 //
216 // Set the Flow Entry key:
217 // - flowEntry.flowEntryId()
218 //
219 flowEntryObj.setFlowEntryId(flowEntry.flowEntryId().toString());
220 flowEntryObj.setType("flow_entry");
221
Yuta HIGUCHIeab1c8b2014-01-15 19:13:28 -0800222 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700223 // Set the Flow Entry Edges and attributes:
224 // - Switch edge
225 // - InPort edge
226 // - OutPort edge
227 //
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800228 // - flowEntry.idleTimeout()
229 // - flowEntry.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700230 // - flowEntry.dpid()
231 // - flowEntry.flowEntryUserState()
232 // - flowEntry.flowEntrySwitchState()
233 // - flowEntry.flowEntryErrorState()
234 // - flowEntry.matchInPort()
235 // - flowEntry.matchSrcMac()
236 // - flowEntry.matchDstMac()
237 // - flowEntry.matchEthernetFrameType()
238 // - flowEntry.matchVlanId()
239 // - flowEntry.matchVlanPriority()
240 // - flowEntry.matchSrcIPv4Net()
241 // - flowEntry.matchDstIPv4Net()
242 // - flowEntry.matchIpProto()
243 // - flowEntry.matchIpToS()
244 // - flowEntry.matchSrcTcpUdpPort()
245 // - flowEntry.matchDstTcpUdpPort()
246 // - flowEntry.actionOutputPort()
247 // - flowEntry.actions()
248 //
249 ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString());
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800250 flowEntryObj.setIdleTimeout(flowEntry.idleTimeout());
251 flowEntryObj.setHardTimeout(flowEntry.hardTimeout());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700252 flowEntryObj.setSwitchDpid(flowEntry.dpid().toString());
253 flowEntryObj.setSwitch(sw);
254 if (flowEntry.flowEntryMatch().matchInPort()) {
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800255 IPortObject inport =
256 dbHandler.searchPort(flowEntry.dpid().toString(),
257 flowEntry.flowEntryMatch().inPort().value());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700258 flowEntryObj.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800259 flowEntryObj.setInPort(inport);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700260 }
261 if (flowEntry.flowEntryMatch().matchSrcMac()) {
262 flowEntryObj.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
263 }
264 if (flowEntry.flowEntryMatch().matchDstMac()) {
265 flowEntryObj.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
266 }
267 if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
268 flowEntryObj.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
269 }
270 if (flowEntry.flowEntryMatch().matchVlanId()) {
271 flowEntryObj.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
272 }
273 if (flowEntry.flowEntryMatch().matchVlanPriority()) {
274 flowEntryObj.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
275 }
276 if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
277 flowEntryObj.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
278 }
279 if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
280 flowEntryObj.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
281 }
282 if (flowEntry.flowEntryMatch().matchIpProto()) {
283 flowEntryObj.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
284 }
285 if (flowEntry.flowEntryMatch().matchIpToS()) {
286 flowEntryObj.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
287 }
288 if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
289 flowEntryObj.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
290 }
291 if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
292 flowEntryObj.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
293 }
294
295 for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
296 if (fa.actionOutput() != null) {
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800297 IPortObject outport =
298 dbHandler.searchPort(flowEntry.dpid().toString(),
299 fa.actionOutput().port().value());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700300 flowEntryObj.setActionOutputPort(fa.actionOutput().port().value());
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800301 flowEntryObj.setOutPort(outport);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700302 }
303 }
304 if (! flowEntry.flowEntryActions().isEmpty()) {
305 flowEntryObj.setActions(flowEntry.flowEntryActions().toString());
306 }
307
308 // TODO: Hacks with hard-coded state names!
309 if (found)
310 flowEntryObj.setUserState("FE_USER_MODIFY");
311 else
312 flowEntryObj.setUserState("FE_USER_ADD");
Pavlin Radoslavovebc8b192013-10-29 15:35:35 -0700313 flowEntryObj.setSwitchState(flowEntry.flowEntrySwitchState().toString());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700314 //
315 // TODO: Take care of the FlowEntryErrorState.
316 //
317
318 // Flow Entries edges:
319 // Flow
320 // NextFE (TODO)
321 if (! found) {
322 flowObj.addFlowEntry(flowEntryObj);
323 flowEntryObj.setFlow(flowObj);
324 }
325
326 return flowEntryObj;
327 }
328
329 /**
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700330 * Delete a flow entry from the Network MAP.
331 *
332 * @param dbHandler the Graph Database handler to use.
333 * @param flowObj the corresponding Flow Path object for the Flow Entry.
334 * @param flowEntry the Flow Entry to delete.
335 * @return true on success, otherwise false.
336 */
337 static boolean deleteFlowEntry(GraphDBOperation dbHandler,
338 IFlowPath flowObj,
339 FlowEntry flowEntry) {
340 IFlowEntry flowEntryObj = null;
341 try {
342 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
343 } catch (Exception e) {
344 log.error(":deleteFlowEntry FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800345 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700346 return false;
347 }
348 //
349 // TODO: Don't print an error for now, because multiple controller
350 // instances might be deleting the same flow entry.
351 //
352 /*
353 if (flowEntryObj == null) {
354 log.error(":deleteFlowEntry FlowEntryId:{} failed: FlowEntry object not found",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800355 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700356 return false;
357 }
358 */
359 if (flowEntryObj == null)
360 return true;
361
362 flowObj.removeFlowEntry(flowEntryObj);
363 dbHandler.removeFlowEntry(flowEntryObj);
364 return true;
365 }
366
367 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700368 * Delete all previously added flows.
369 *
370 * @param dbHandler the Graph Database handler to use.
371 * @return true on success, otherwise false.
372 */
373 static boolean deleteAllFlows(GraphDBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700374 // Get all Flow IDs
375 Iterable<IFlowPath> allFlowPaths = dbHandler.getAllFlowPaths();
376 for (IFlowPath flowPathObj : allFlowPaths) {
377 if (flowPathObj == null)
378 continue;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700379
Yuta HIGUCHIeab1c8b2014-01-15 19:13:28 -0800380 deleteIFlowPath(dbHandler, flowPathObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700381 }
Yuta HIGUCHIeab1c8b2014-01-15 19:13:28 -0800382 dbHandler.commit();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700383
384 return true;
385 }
386
387 /**
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800388 * Delete a previously added flow.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700389 *
390 * @param dbHandler the Graph Database handler to use.
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800391 * @param flowId the Flow ID of the flow to delete.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700392 * @return true on success, otherwise false.
393 */
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800394 static boolean deleteFlow(GraphDBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700395 IFlowPath flowObj = null;
396 try {
397 flowObj = dbHandler.searchFlowPath(flowId);
398 } catch (Exception e) {
399 // TODO: handle exceptions
400 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800401 log.error(":deleteFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700402 return false;
403 }
404 if (flowObj == null) {
405 dbHandler.commit();
406 return true; // OK: No such flow
407 }
408
Yuta HIGUCHIeab1c8b2014-01-15 19:13:28 -0800409 deleteIFlowPath(dbHandler, flowObj);
410 dbHandler.commit();
411 return true;
412 }
413
414 /**
415 * Delete a previously added flow.
416 * @note You need to call commit after calling this method.
417 * @param dbHandler the Graph Database handler to use.
418 * @param flowObj IFlowPath object to delete.
419 */
420 private static void deleteIFlowPath(GraphDBOperation dbHandler, IFlowPath flowObj) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700421 //
422 // Remove all Flow Entries
423 //
424 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
425 for (IFlowEntry flowEntryObj : flowEntries) {
426 flowObj.removeFlowEntry(flowEntryObj);
427 dbHandler.removeFlowEntry(flowEntryObj);
428 }
429 // Remove the Flow itself
430 dbHandler.removeFlowPath(flowObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700431 }
432
433 /**
434 * Get a previously added flow.
435 *
436 * @param dbHandler the Graph Database handler to use.
437 * @param flowId the Flow ID of the flow to get.
438 * @return the Flow Path if found, otherwise null.
439 */
440 static FlowPath getFlow(GraphDBOperation dbHandler, FlowId flowId) {
441 IFlowPath flowObj = null;
442 try {
443 flowObj = dbHandler.searchFlowPath(flowId);
444 } catch (Exception e) {
445 // TODO: handle exceptions
446 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800447 log.error(":getFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700448 return null;
449 }
450 if (flowObj == null) {
451 dbHandler.commit();
452 return null; // Flow not found
453 }
454
455 //
456 // Extract the Flow state
457 //
458 FlowPath flowPath = extractFlowPath(flowObj);
459 dbHandler.commit();
460
461 return flowPath;
462 }
463
464 /**
465 * Get all installed flows by all installers.
466 *
467 * @param dbHandler the Graph Database handler to use.
468 * @return the Flow Paths if found, otherwise null.
469 */
470 static ArrayList<FlowPath> getAllFlows(GraphDBOperation dbHandler) {
471 Iterable<IFlowPath> flowPathsObj = null;
472 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
473
474 try {
475 flowPathsObj = dbHandler.getAllFlowPaths();
476 } catch (Exception e) {
477 // TODO: handle exceptions
478 dbHandler.rollback();
479 log.error(":getAllFlowPaths failed");
480 return flowPaths;
481 }
482 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
483 dbHandler.commit();
484 return flowPaths; // No Flows found
485 }
486
487 for (IFlowPath flowObj : flowPathsObj) {
488 //
489 // Extract the Flow state
490 //
491 FlowPath flowPath = extractFlowPath(flowObj);
492 if (flowPath != null)
493 flowPaths.add(flowPath);
494 }
495
496 dbHandler.commit();
497
498 return flowPaths;
499 }
500
501 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700502 * Extract Flow Path State from a Titan Database Object @ref IFlowPath.
503 *
504 * @param flowObj the object to extract the Flow Path State from.
505 * @return the extracted Flow Path State.
506 */
507 private static FlowPath extractFlowPath(IFlowPath flowObj) {
508 //
509 // Extract the Flow state
510 //
511 String flowIdStr = flowObj.getFlowId();
512 String installerIdStr = flowObj.getInstallerId();
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700513 String flowPathType = flowObj.getFlowPathType();
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700514 String flowPathUserState = flowObj.getFlowPathUserState();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700515 Long flowPathFlags = flowObj.getFlowPathFlags();
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800516 Integer idleTimeout = flowObj.getIdleTimeout();
517 Integer hardTimeout = flowObj.getHardTimeout();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700518 String srcSwitchStr = flowObj.getSrcSwitch();
519 Short srcPortShort = flowObj.getSrcPort();
520 String dstSwitchStr = flowObj.getDstSwitch();
521 Short dstPortShort = flowObj.getDstPort();
522
523 if ((flowIdStr == null) ||
524 (installerIdStr == null) ||
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700525 (flowPathType == null) ||
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700526 (flowPathUserState == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700527 (flowPathFlags == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800528 (idleTimeout == null) ||
529 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700530 (srcSwitchStr == null) ||
531 (srcPortShort == null) ||
532 (dstSwitchStr == null) ||
533 (dstPortShort == null)) {
534 // TODO: A work-around, becauuse of some bogus database objects
535 return null;
536 }
537
538 FlowPath flowPath = new FlowPath();
539 flowPath.setFlowId(new FlowId(flowIdStr));
540 flowPath.setInstallerId(new CallerId(installerIdStr));
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700541 flowPath.setFlowPathType(FlowPathType.valueOf(flowPathType));
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700542 flowPath.setFlowPathUserState(FlowPathUserState.valueOf(flowPathUserState));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700543 flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800544 flowPath.setIdleTimeout(idleTimeout);
545 flowPath.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700546 flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
547 flowPath.dataPath().srcPort().setPort(new Port(srcPortShort));
548 flowPath.dataPath().dstPort().setDpid(new Dpid(dstSwitchStr));
549 flowPath.dataPath().dstPort().setPort(new Port(dstPortShort));
550 //
551 // Extract the match conditions common for all Flow Entries
552 //
553 {
554 FlowEntryMatch match = new FlowEntryMatch();
555 String matchSrcMac = flowObj.getMatchSrcMac();
556 if (matchSrcMac != null)
557 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
558 String matchDstMac = flowObj.getMatchDstMac();
559 if (matchDstMac != null)
560 match.enableDstMac(MACAddress.valueOf(matchDstMac));
561 Short matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
562 if (matchEthernetFrameType != null)
563 match.enableEthernetFrameType(matchEthernetFrameType);
564 Short matchVlanId = flowObj.getMatchVlanId();
565 if (matchVlanId != null)
566 match.enableVlanId(matchVlanId);
567 Byte matchVlanPriority = flowObj.getMatchVlanPriority();
568 if (matchVlanPriority != null)
569 match.enableVlanPriority(matchVlanPriority);
570 String matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
571 if (matchSrcIPv4Net != null)
572 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
573 String matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
574 if (matchDstIPv4Net != null)
575 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
576 Byte matchIpProto = flowObj.getMatchIpProto();
577 if (matchIpProto != null)
578 match.enableIpProto(matchIpProto);
579 Byte matchIpToS = flowObj.getMatchIpToS();
580 if (matchIpToS != null)
581 match.enableIpToS(matchIpToS);
582 Short matchSrcTcpUdpPort = flowObj.getMatchSrcTcpUdpPort();
583 if (matchSrcTcpUdpPort != null)
584 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
585 Short matchDstTcpUdpPort = flowObj.getMatchDstTcpUdpPort();
586 if (matchDstTcpUdpPort != null)
587 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
588
589 flowPath.setFlowEntryMatch(match);
590 }
591 //
592 // Extract the actions for the first Flow Entry
593 //
594 {
595 String actionsStr = flowObj.getActions();
596 if (actionsStr != null) {
597 FlowEntryActions flowEntryActions = new FlowEntryActions(actionsStr);
598 flowPath.setFlowEntryActions(flowEntryActions);
599 }
600 }
601
602 //
603 // Extract all Flow Entries
604 //
605 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
606 for (IFlowEntry flowEntryObj : flowEntries) {
607 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
608 if (flowEntry == null)
609 continue;
610 flowPath.dataPath().flowEntries().add(flowEntry);
611 }
612
613 return flowPath;
614 }
615
616 /**
617 * Extract Flow Entry State from a Titan Database Object @ref IFlowEntry.
618 *
619 * @param flowEntryObj the object to extract the Flow Entry State from.
620 * @return the extracted Flow Entry State.
621 */
Brian O'Connora8e49802013-10-30 20:49:59 -0700622 public static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800623 IFlowPath flowObj = flowEntryObj.getFlow();
624 if (flowObj == null)
625 return null;
626
627 String flowIdStr = flowObj.getFlowId();
628 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700629 String flowEntryIdStr = flowEntryObj.getFlowEntryId();
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800630 Integer idleTimeout = flowEntryObj.getIdleTimeout();
631 Integer hardTimeout = flowEntryObj.getHardTimeout();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700632 String switchDpidStr = flowEntryObj.getSwitchDpid();
633 String userState = flowEntryObj.getUserState();
634 String switchState = flowEntryObj.getSwitchState();
635
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800636 if ((flowIdStr == null) ||
637 (flowEntryIdStr == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800638 (idleTimeout == null) ||
639 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700640 (switchDpidStr == null) ||
641 (userState == null) ||
642 (switchState == null)) {
Brian O'Connora8e49802013-10-30 20:49:59 -0700643 // TODO: A work-around, because of some bogus database objects
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700644 return null;
645 }
646
647 FlowEntry flowEntry = new FlowEntry();
648 flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800649 flowEntry.setFlowId(new FlowId(flowIdStr));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700650 flowEntry.setDpid(new Dpid(switchDpidStr));
Pavlin Radoslavovce93a032013-12-13 11:03:02 -0800651 flowEntry.setIdleTimeout(idleTimeout);
652 flowEntry.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700653
654 //
655 // Extract the match conditions
656 //
657 FlowEntryMatch match = new FlowEntryMatch();
658 Short matchInPort = flowEntryObj.getMatchInPort();
659 if (matchInPort != null)
660 match.enableInPort(new Port(matchInPort));
661 String matchSrcMac = flowEntryObj.getMatchSrcMac();
662 if (matchSrcMac != null)
663 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
664 String matchDstMac = flowEntryObj.getMatchDstMac();
665 if (matchDstMac != null)
666 match.enableDstMac(MACAddress.valueOf(matchDstMac));
667 Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
668 if (matchEthernetFrameType != null)
669 match.enableEthernetFrameType(matchEthernetFrameType);
670 Short matchVlanId = flowEntryObj.getMatchVlanId();
671 if (matchVlanId != null)
672 match.enableVlanId(matchVlanId);
673 Byte matchVlanPriority = flowEntryObj.getMatchVlanPriority();
674 if (matchVlanPriority != null)
675 match.enableVlanPriority(matchVlanPriority);
676 String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
677 if (matchSrcIPv4Net != null)
678 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
679 String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
680 if (matchDstIPv4Net != null)
681 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
682 Byte matchIpProto = flowEntryObj.getMatchIpProto();
683 if (matchIpProto != null)
684 match.enableIpProto(matchIpProto);
685 Byte matchIpToS = flowEntryObj.getMatchIpToS();
686 if (matchIpToS != null)
687 match.enableIpToS(matchIpToS);
688 Short matchSrcTcpUdpPort = flowEntryObj.getMatchSrcTcpUdpPort();
689 if (matchSrcTcpUdpPort != null)
690 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
691 Short matchDstTcpUdpPort = flowEntryObj.getMatchDstTcpUdpPort();
692 if (matchDstTcpUdpPort != null)
693 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
694 flowEntry.setFlowEntryMatch(match);
695
696 //
697 // Extract the actions
698 //
699 FlowEntryActions actions = new FlowEntryActions();
700 String actionsStr = flowEntryObj.getActions();
701 if (actionsStr != null)
702 actions = new FlowEntryActions(actionsStr);
703 flowEntry.setFlowEntryActions(actions);
704 flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
705 flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
706 //
707 // TODO: Take care of FlowEntryErrorState.
708 //
709 return flowEntry;
710 }
711}