blob: 3cb026e5a3e6d6467484b4bfec81afdc38fbd03a [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 Radoslavov16b761d2014-01-08 09:47:14 -08008import java.util.Map;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07009
Pavlin Radoslavov16b761d2014-01-08 09:47:14 -080010import net.floodlightcontroller.core.IOFSwitch;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070011import net.floodlightcontroller.util.MACAddress;
12
13import net.onrc.onos.graph.GraphDBOperation;
14
15import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
16import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
17import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
18import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
19import net.onrc.onos.ofcontroller.util.*;
20
21import org.slf4j.Logger;
22import org.slf4j.LoggerFactory;
23
24/**
25 * Class for performing Flow-related operations on the Database.
26 */
Pavlin Radoslavov6bfaea62013-12-03 14:55:57 -080027public class FlowDatabaseOperation {
Pavlin Radoslavov909da3c2014-01-09 04:04:33 -080028 static private boolean enableOnrc2014MeasurementsFlows = true;
29
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070030 private final static Logger log = LoggerFactory.getLogger(FlowDatabaseOperation.class);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070031
32 /**
33 * Add a flow.
34 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070035 * @param dbHandler the Graph Database handler to use.
36 * @param flowPath the Flow Path to install.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070037 * @return true on success, otherwise false.
38 */
Pavlin Radoslavov051abb42013-12-05 17:24:50 -080039 static boolean addFlow(GraphDBOperation dbHandler, FlowPath flowPath) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070040 IFlowPath flowObj = null;
41 boolean found = false;
42 try {
43 if ((flowObj = dbHandler.searchFlowPath(flowPath.flowId())) != null) {
44 found = true;
45 } else {
46 flowObj = dbHandler.newFlowPath();
47 }
48 } catch (Exception e) {
49 dbHandler.rollback();
50
51 StringWriter sw = new StringWriter();
52 e.printStackTrace(new PrintWriter(sw));
53 String stacktrace = sw.toString();
54
55 log.error(":addFlow FlowId:{} failed: {}",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -080056 flowPath.flowId(),
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070057 stacktrace);
58 return false;
59 }
60 if (flowObj == null) {
61 log.error(":addFlow FlowId:{} failed: Flow object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -080062 flowPath.flowId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070063 dbHandler.rollback();
64 return false;
65 }
66
67 //
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -080068 // Remove the old Flow Entries
69 //
70 if (found) {
71 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
72 LinkedList<IFlowEntry> deleteFlowEntries =
73 new LinkedList<IFlowEntry>();
74 for (IFlowEntry flowEntryObj : flowEntries)
75 deleteFlowEntries.add(flowEntryObj);
76 for (IFlowEntry flowEntryObj : deleteFlowEntries) {
77 flowObj.removeFlowEntry(flowEntryObj);
78 dbHandler.removeFlowEntry(flowEntryObj);
79 }
80 }
81
82 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070083 // Set the Flow key:
84 // - flowId
85 //
86 flowObj.setFlowId(flowPath.flowId().toString());
87 flowObj.setType("flow");
88
89 //
90 // Set the Flow attributes:
91 // - flowPath.installerId()
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -070092 // - flowPath.flowPathType()
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -070093 // - flowPath.flowPathUserState()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070094 // - flowPath.flowPathFlags()
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -080095 // - flowPath.idleTimeout()
96 // - flowPath.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070097 // - flowPath.dataPath().srcPort()
98 // - flowPath.dataPath().dstPort()
99 // - flowPath.matchSrcMac()
100 // - flowPath.matchDstMac()
101 // - flowPath.matchEthernetFrameType()
102 // - flowPath.matchVlanId()
103 // - flowPath.matchVlanPriority()
104 // - flowPath.matchSrcIPv4Net()
105 // - flowPath.matchDstIPv4Net()
106 // - flowPath.matchIpProto()
107 // - flowPath.matchIpToS()
108 // - flowPath.matchSrcTcpUdpPort()
109 // - flowPath.matchDstTcpUdpPort()
110 // - flowPath.flowEntryActions()
111 //
112 flowObj.setInstallerId(flowPath.installerId().toString());
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700113 flowObj.setFlowPathType(flowPath.flowPathType().toString());
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700114 flowObj.setFlowPathUserState(flowPath.flowPathUserState().toString());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700115 flowObj.setFlowPathFlags(flowPath.flowPathFlags().flags());
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800116 flowObj.setIdleTimeout(flowPath.idleTimeout());
117 flowObj.setHardTimeout(flowPath.hardTimeout());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700118 flowObj.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
119 flowObj.setSrcPort(flowPath.dataPath().srcPort().port().value());
120 flowObj.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
121 flowObj.setDstPort(flowPath.dataPath().dstPort().port().value());
122 if (flowPath.flowEntryMatch().matchSrcMac()) {
123 flowObj.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
124 }
125 if (flowPath.flowEntryMatch().matchDstMac()) {
126 flowObj.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
127 }
128 if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
129 flowObj.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
130 }
131 if (flowPath.flowEntryMatch().matchVlanId()) {
132 flowObj.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
133 }
134 if (flowPath.flowEntryMatch().matchVlanPriority()) {
135 flowObj.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
136 }
137 if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
138 flowObj.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
139 }
140 if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
141 flowObj.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
142 }
143 if (flowPath.flowEntryMatch().matchIpProto()) {
144 flowObj.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
145 }
146 if (flowPath.flowEntryMatch().matchIpToS()) {
147 flowObj.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
148 }
149 if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
150 flowObj.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
151 }
152 if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
153 flowObj.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
154 }
155 if (! flowPath.flowEntryActions().actions().isEmpty()) {
156 flowObj.setActions(flowPath.flowEntryActions().toString());
157 }
Pavlin Radoslavovbcc86ef2013-10-26 12:06:25 -0700158 flowObj.setDataPathSummary(flowPath.dataPath().dataPathSummary());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700159
160 if (found)
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700161 flowObj.setFlowPathUserState("FP_USER_MODIFY");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700162 else
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700163 flowObj.setFlowPathUserState("FP_USER_ADD");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700164
165 // Flow edges:
166 // HeadFE
167
168
169 //
170 // Flow Entries:
171 // flowPath.dataPath().flowEntries()
172 //
173 for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
Pavlin Radoslavov909da3c2014-01-09 04:04:33 -0800174 if (! enableOnrc2014MeasurementsFlows) {
175 if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE)
176 continue; // Skip: all Flow Entries were deleted earlier
177 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800178
Pavlin Radoslavov67bf7622013-12-04 12:28:23 -0800179 if (addFlowEntry(dbHandler, flowObj, flowEntry) == null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700180 dbHandler.rollback();
181 return false;
182 }
183 }
184 dbHandler.commit();
185
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700186 return true;
187 }
188
189 /**
190 * Add a flow entry to the Network MAP.
191 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700192 * @param dbHandler the Graph Database handler to use.
193 * @param flowObj the corresponding Flow Path object for the Flow Entry.
194 * @param flowEntry the Flow Entry to install.
195 * @return the added Flow Entry object on success, otherwise null.
196 */
Pavlin Radoslavov67bf7622013-12-04 12:28:23 -0800197 static IFlowEntry addFlowEntry(GraphDBOperation dbHandler,
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700198 IFlowPath flowObj,
199 FlowEntry flowEntry) {
200 // Flow edges
201 // HeadFE (TODO)
202
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700203 IFlowEntry flowEntryObj = null;
204 boolean found = false;
205 try {
206 if ((flowEntryObj =
207 dbHandler.searchFlowEntry(flowEntry.flowEntryId())) != null) {
208 found = true;
209 } else {
210 flowEntryObj = dbHandler.newFlowEntry();
211 }
212 } catch (Exception e) {
213 log.error(":addFlow FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800214 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700215 return null;
216 }
217 if (flowEntryObj == null) {
218 log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800219 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700220 return null;
221 }
222
223 //
224 // Set the Flow Entry key:
225 // - flowEntry.flowEntryId()
226 //
227 flowEntryObj.setFlowEntryId(flowEntry.flowEntryId().toString());
228 flowEntryObj.setType("flow_entry");
229
230 //
231 // Set the Flow Entry Edges and attributes:
232 // - Switch edge
233 // - InPort edge
234 // - OutPort edge
235 //
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800236 // - flowEntry.idleTimeout()
237 // - flowEntry.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700238 // - flowEntry.dpid()
239 // - flowEntry.flowEntryUserState()
240 // - flowEntry.flowEntrySwitchState()
241 // - flowEntry.flowEntryErrorState()
242 // - flowEntry.matchInPort()
243 // - flowEntry.matchSrcMac()
244 // - flowEntry.matchDstMac()
245 // - flowEntry.matchEthernetFrameType()
246 // - flowEntry.matchVlanId()
247 // - flowEntry.matchVlanPriority()
248 // - flowEntry.matchSrcIPv4Net()
249 // - flowEntry.matchDstIPv4Net()
250 // - flowEntry.matchIpProto()
251 // - flowEntry.matchIpToS()
252 // - flowEntry.matchSrcTcpUdpPort()
253 // - flowEntry.matchDstTcpUdpPort()
254 // - flowEntry.actionOutputPort()
255 // - flowEntry.actions()
256 //
257 ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString());
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800258 flowEntryObj.setIdleTimeout(flowEntry.idleTimeout());
259 flowEntryObj.setHardTimeout(flowEntry.hardTimeout());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700260 flowEntryObj.setSwitchDpid(flowEntry.dpid().toString());
261 flowEntryObj.setSwitch(sw);
262 if (flowEntry.flowEntryMatch().matchInPort()) {
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800263 IPortObject inport =
264 dbHandler.searchPort(flowEntry.dpid().toString(),
265 flowEntry.flowEntryMatch().inPort().value());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700266 flowEntryObj.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800267 flowEntryObj.setInPort(inport);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700268 }
269 if (flowEntry.flowEntryMatch().matchSrcMac()) {
270 flowEntryObj.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
271 }
272 if (flowEntry.flowEntryMatch().matchDstMac()) {
273 flowEntryObj.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
274 }
275 if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
276 flowEntryObj.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
277 }
278 if (flowEntry.flowEntryMatch().matchVlanId()) {
279 flowEntryObj.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
280 }
281 if (flowEntry.flowEntryMatch().matchVlanPriority()) {
282 flowEntryObj.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
283 }
284 if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
285 flowEntryObj.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
286 }
287 if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
288 flowEntryObj.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
289 }
290 if (flowEntry.flowEntryMatch().matchIpProto()) {
291 flowEntryObj.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
292 }
293 if (flowEntry.flowEntryMatch().matchIpToS()) {
294 flowEntryObj.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
295 }
296 if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
297 flowEntryObj.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
298 }
299 if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
300 flowEntryObj.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
301 }
302
303 for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
304 if (fa.actionOutput() != null) {
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800305 IPortObject outport =
306 dbHandler.searchPort(flowEntry.dpid().toString(),
307 fa.actionOutput().port().value());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700308 flowEntryObj.setActionOutputPort(fa.actionOutput().port().value());
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800309 flowEntryObj.setOutPort(outport);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700310 }
311 }
312 if (! flowEntry.flowEntryActions().isEmpty()) {
313 flowEntryObj.setActions(flowEntry.flowEntryActions().toString());
314 }
315
316 // TODO: Hacks with hard-coded state names!
Pavlin Radoslavov9fde9b22014-01-09 14:03:52 -0800317 if (enableOnrc2014MeasurementsFlows) {
318 flowEntryObj.setUserState(flowEntry.flowEntryUserState().toString());
319 } else {
320 if (found)
321 flowEntryObj.setUserState("FE_USER_MODIFY");
322 else
323 flowEntryObj.setUserState("FE_USER_ADD");
324 }
Pavlin Radoslavovebc8b192013-10-29 15:35:35 -0700325 flowEntryObj.setSwitchState(flowEntry.flowEntrySwitchState().toString());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700326 //
327 // TODO: Take care of the FlowEntryErrorState.
328 //
329
330 // Flow Entries edges:
331 // Flow
332 // NextFE (TODO)
333 if (! found) {
334 flowObj.addFlowEntry(flowEntryObj);
335 flowEntryObj.setFlow(flowObj);
336 }
337
338 return flowEntryObj;
339 }
340
341 /**
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700342 * Delete a flow entry from the Network MAP.
343 *
344 * @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 delete.
347 * @return true on success, otherwise false.
348 */
349 static boolean deleteFlowEntry(GraphDBOperation dbHandler,
350 IFlowPath flowObj,
351 FlowEntry flowEntry) {
352 IFlowEntry flowEntryObj = null;
353 try {
354 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
355 } catch (Exception e) {
356 log.error(":deleteFlowEntry FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800357 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700358 return false;
359 }
360 //
361 // TODO: Don't print an error for now, because multiple controller
362 // instances might be deleting the same flow entry.
363 //
364 /*
365 if (flowEntryObj == null) {
366 log.error(":deleteFlowEntry FlowEntryId:{} failed: FlowEntry object not found",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800367 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700368 return false;
369 }
370 */
371 if (flowEntryObj == null)
372 return true;
373
374 flowObj.removeFlowEntry(flowEntryObj);
375 dbHandler.removeFlowEntry(flowEntryObj);
376 return true;
377 }
378
379 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700380 * Delete all previously added flows.
381 *
382 * @param dbHandler the Graph Database handler to use.
383 * @return true on success, otherwise false.
384 */
385 static boolean deleteAllFlows(GraphDBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700386 List<FlowId> allFlowIds = new LinkedList<FlowId>();
387
388 // Get all Flow IDs
389 Iterable<IFlowPath> allFlowPaths = dbHandler.getAllFlowPaths();
390 for (IFlowPath flowPathObj : allFlowPaths) {
391 if (flowPathObj == null)
392 continue;
393 String flowIdStr = flowPathObj.getFlowId();
394 if (flowIdStr == null)
395 continue;
396 FlowId flowId = new FlowId(flowIdStr);
397 allFlowIds.add(flowId);
398 }
399
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800400 // Delete all flows one-by-one
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700401 for (FlowId flowId : allFlowIds) {
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800402 deleteFlow(dbHandler, flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700403 }
404
405 return true;
406 }
407
408 /**
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800409 * Delete a previously added flow.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700410 *
411 * @param dbHandler the Graph Database handler to use.
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800412 * @param flowId the Flow ID of the flow to delete.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700413 * @return true on success, otherwise false.
414 */
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800415 static boolean deleteFlow(GraphDBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700416 IFlowPath flowObj = null;
417 try {
418 flowObj = dbHandler.searchFlowPath(flowId);
419 } catch (Exception e) {
420 // TODO: handle exceptions
421 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800422 log.error(":deleteFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700423 return false;
424 }
425 if (flowObj == null) {
426 dbHandler.commit();
427 return true; // OK: No such flow
428 }
429
430 //
431 // Remove all Flow Entries
432 //
433 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
434 for (IFlowEntry flowEntryObj : flowEntries) {
435 flowObj.removeFlowEntry(flowEntryObj);
436 dbHandler.removeFlowEntry(flowEntryObj);
437 }
438 // Remove the Flow itself
439 dbHandler.removeFlowPath(flowObj);
440 dbHandler.commit();
441
442 return true;
443 }
444
445 /**
446 * Get a previously added flow.
447 *
448 * @param dbHandler the Graph Database handler to use.
449 * @param flowId the Flow ID of the flow to get.
450 * @return the Flow Path if found, otherwise null.
451 */
452 static FlowPath getFlow(GraphDBOperation dbHandler, FlowId flowId) {
453 IFlowPath flowObj = null;
454 try {
455 flowObj = dbHandler.searchFlowPath(flowId);
456 } catch (Exception e) {
457 // TODO: handle exceptions
458 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800459 log.error(":getFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700460 return null;
461 }
462 if (flowObj == null) {
463 dbHandler.commit();
464 return null; // Flow not found
465 }
466
467 //
468 // Extract the Flow state
469 //
470 FlowPath flowPath = extractFlowPath(flowObj);
471 dbHandler.commit();
472
473 return flowPath;
474 }
475
476 /**
Pavlin Radoslavov52119fa2014-01-09 13:37:52 -0800477 * Get a previously added flow entry.
478 *
479 * @param dbHandler the Graph Database handler to use.
480 * @param flowEntryId the Flow Entry ID of the flow entry to get.
481 * @return the Flow Entry if found, otherwise null.
482 */
483 static FlowEntry getFlowEntry(GraphDBOperation dbHandler,
484 FlowEntryId flowEntryId) {
485 IFlowEntry flowEntryObj = null;
486 try {
487 flowEntryObj = dbHandler.searchFlowEntry(flowEntryId);
488 } catch (Exception e) {
489 // TODO: handle exceptions
490 dbHandler.rollback();
491 log.error(":getFlowEntry FlowEntryId:{} failed", flowEntryId);
492 return null;
493 }
494 if (flowEntryObj == null) {
495 dbHandler.commit();
496 return null; // Flow not found
497 }
498
499 //
500 // Extract the Flow Entry state
501 //
502 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
503 dbHandler.commit();
504
505 return flowEntry;
506 }
507
508 /**
Pavlin Radoslavov8252fee2014-01-07 17:24:29 -0800509 * Get the source switch DPID of a previously added flow.
510 *
511 * @param dbHandler the Graph Database handler to use.
512 * @param flowId the Flow ID of the flow to get.
513 * @return the source switch DPID if found, otherwise null.
514 */
515 static Dpid getFlowSourceDpid(GraphDBOperation dbHandler, FlowId flowId) {
516 IFlowPath flowObj = null;
517 try {
518 flowObj = dbHandler.searchFlowPath(flowId);
519 } catch (Exception e) {
520 // TODO: handle exceptions
521 dbHandler.rollback();
522 log.error(":getFlowSourceDpid FlowId:{} failed", flowId);
523 return null;
524 }
525 if (flowObj == null) {
526 dbHandler.commit();
527 return null; // Flow not found
528 }
529
530 //
531 // Extract the Flow Source DPID
532 //
533 String srcSwitchStr = flowObj.getSrcSwitch();
534 if (srcSwitchStr == null) {
535 // TODO: A work-around, becauuse of some bogus database objects
536 dbHandler.commit();
537 return null;
538 }
539
540 Dpid dpid = new Dpid(srcSwitchStr);
541
542 dbHandler.commit();
543
544 return dpid;
545 }
546
547 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700548 * Get all installed flows by all installers.
549 *
550 * @param dbHandler the Graph Database handler to use.
551 * @return the Flow Paths if found, otherwise null.
552 */
553 static ArrayList<FlowPath> getAllFlows(GraphDBOperation dbHandler) {
554 Iterable<IFlowPath> flowPathsObj = null;
555 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
556
557 try {
558 flowPathsObj = dbHandler.getAllFlowPaths();
559 } catch (Exception e) {
560 // TODO: handle exceptions
561 dbHandler.rollback();
562 log.error(":getAllFlowPaths failed");
563 return flowPaths;
564 }
565 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
566 dbHandler.commit();
567 return flowPaths; // No Flows found
568 }
569
570 for (IFlowPath flowObj : flowPathsObj) {
571 //
572 // Extract the Flow state
573 //
574 FlowPath flowPath = extractFlowPath(flowObj);
575 if (flowPath != null)
576 flowPaths.add(flowPath);
577 }
578
579 dbHandler.commit();
580
581 return flowPaths;
582 }
583
584 /**
Pavlin Radoslavov16b761d2014-01-08 09:47:14 -0800585 * Get all installed flows whose Source Switch is controlled by this
586 * instance.
587 *
588 * @param dbHandler the Graph Database handler to use.
589 * @param mySwitches the collection of the switches controlled by this
590 * instance.
591 * @return the Flow Paths if found, otherwise null.
592 */
593 static ArrayList<FlowPath> getAllMyFlows(GraphDBOperation dbHandler,
594 Map<Long, IOFSwitch> mySwitches) {
595 Iterable<IFlowPath> flowPathsObj = null;
596 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
597
598 try {
599 flowPathsObj = dbHandler.getAllFlowPaths();
600 } catch (Exception e) {
601 // TODO: handle exceptions
602 dbHandler.rollback();
603 log.error(":getAllMyFlowPaths failed");
604 return flowPaths;
605 }
606 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
607 dbHandler.commit();
608 return flowPaths; // No Flows found
609 }
610
611 for (IFlowPath flowObj : flowPathsObj) {
612 //
613 // Extract the Source Switch DPID and ignore if the switch
614 // is not controlled by this instance.
615 //
616 String srcSwitchStr = flowObj.getSrcSwitch();
617 if (srcSwitchStr == null) {
618 // TODO: A work-around, becauuse of some bogus database objects
619 continue;
620 }
621 Dpid dpid = new Dpid(srcSwitchStr);
622 if (mySwitches.get(dpid.value()) == null)
623 continue;
624
625 //
626 // Extract the Flow state
627 //
628 FlowPath flowPath = extractFlowPath(flowObj);
629 if (flowPath != null)
630 flowPaths.add(flowPath);
631 }
632
633 dbHandler.commit();
634
635 return flowPaths;
636 }
637
638 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700639 * Extract Flow Path State from a Titan Database Object @ref IFlowPath.
640 *
641 * @param flowObj the object to extract the Flow Path State from.
642 * @return the extracted Flow Path State.
643 */
644 private static FlowPath extractFlowPath(IFlowPath flowObj) {
645 //
646 // Extract the Flow state
647 //
648 String flowIdStr = flowObj.getFlowId();
649 String installerIdStr = flowObj.getInstallerId();
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700650 String flowPathType = flowObj.getFlowPathType();
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700651 String flowPathUserState = flowObj.getFlowPathUserState();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700652 Long flowPathFlags = flowObj.getFlowPathFlags();
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800653 Integer idleTimeout = flowObj.getIdleTimeout();
654 Integer hardTimeout = flowObj.getHardTimeout();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700655 String srcSwitchStr = flowObj.getSrcSwitch();
656 Short srcPortShort = flowObj.getSrcPort();
657 String dstSwitchStr = flowObj.getDstSwitch();
658 Short dstPortShort = flowObj.getDstPort();
659
660 if ((flowIdStr == null) ||
661 (installerIdStr == null) ||
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700662 (flowPathType == null) ||
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700663 (flowPathUserState == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700664 (flowPathFlags == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800665 (idleTimeout == null) ||
666 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700667 (srcSwitchStr == null) ||
668 (srcPortShort == null) ||
669 (dstSwitchStr == null) ||
670 (dstPortShort == null)) {
671 // TODO: A work-around, becauuse of some bogus database objects
672 return null;
673 }
674
675 FlowPath flowPath = new FlowPath();
676 flowPath.setFlowId(new FlowId(flowIdStr));
677 flowPath.setInstallerId(new CallerId(installerIdStr));
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700678 flowPath.setFlowPathType(FlowPathType.valueOf(flowPathType));
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700679 flowPath.setFlowPathUserState(FlowPathUserState.valueOf(flowPathUserState));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700680 flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800681 flowPath.setIdleTimeout(idleTimeout);
682 flowPath.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700683 flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
684 flowPath.dataPath().srcPort().setPort(new Port(srcPortShort));
685 flowPath.dataPath().dstPort().setDpid(new Dpid(dstSwitchStr));
686 flowPath.dataPath().dstPort().setPort(new Port(dstPortShort));
687 //
688 // Extract the match conditions common for all Flow Entries
689 //
690 {
691 FlowEntryMatch match = new FlowEntryMatch();
692 String matchSrcMac = flowObj.getMatchSrcMac();
693 if (matchSrcMac != null)
694 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
695 String matchDstMac = flowObj.getMatchDstMac();
696 if (matchDstMac != null)
697 match.enableDstMac(MACAddress.valueOf(matchDstMac));
698 Short matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
699 if (matchEthernetFrameType != null)
700 match.enableEthernetFrameType(matchEthernetFrameType);
701 Short matchVlanId = flowObj.getMatchVlanId();
702 if (matchVlanId != null)
703 match.enableVlanId(matchVlanId);
704 Byte matchVlanPriority = flowObj.getMatchVlanPriority();
705 if (matchVlanPriority != null)
706 match.enableVlanPriority(matchVlanPriority);
707 String matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
708 if (matchSrcIPv4Net != null)
709 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
710 String matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
711 if (matchDstIPv4Net != null)
712 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
713 Byte matchIpProto = flowObj.getMatchIpProto();
714 if (matchIpProto != null)
715 match.enableIpProto(matchIpProto);
716 Byte matchIpToS = flowObj.getMatchIpToS();
717 if (matchIpToS != null)
718 match.enableIpToS(matchIpToS);
719 Short matchSrcTcpUdpPort = flowObj.getMatchSrcTcpUdpPort();
720 if (matchSrcTcpUdpPort != null)
721 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
722 Short matchDstTcpUdpPort = flowObj.getMatchDstTcpUdpPort();
723 if (matchDstTcpUdpPort != null)
724 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
725
726 flowPath.setFlowEntryMatch(match);
727 }
728 //
729 // Extract the actions for the first Flow Entry
730 //
731 {
732 String actionsStr = flowObj.getActions();
733 if (actionsStr != null) {
734 FlowEntryActions flowEntryActions = new FlowEntryActions(actionsStr);
735 flowPath.setFlowEntryActions(flowEntryActions);
736 }
737 }
738
739 //
740 // Extract all Flow Entries
741 //
742 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
743 for (IFlowEntry flowEntryObj : flowEntries) {
744 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
745 if (flowEntry == null)
746 continue;
747 flowPath.dataPath().flowEntries().add(flowEntry);
748 }
749
750 return flowPath;
751 }
752
753 /**
754 * Extract Flow Entry State from a Titan Database Object @ref IFlowEntry.
755 *
756 * @param flowEntryObj the object to extract the Flow Entry State from.
757 * @return the extracted Flow Entry State.
758 */
Brian O'Connora8e49802013-10-30 20:49:59 -0700759 public static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800760 IFlowPath flowObj = flowEntryObj.getFlow();
761 if (flowObj == null)
762 return null;
763
764 String flowIdStr = flowObj.getFlowId();
765 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700766 String flowEntryIdStr = flowEntryObj.getFlowEntryId();
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800767 Integer idleTimeout = flowEntryObj.getIdleTimeout();
768 Integer hardTimeout = flowEntryObj.getHardTimeout();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700769 String switchDpidStr = flowEntryObj.getSwitchDpid();
770 String userState = flowEntryObj.getUserState();
771 String switchState = flowEntryObj.getSwitchState();
772
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800773 if ((flowIdStr == null) ||
774 (flowEntryIdStr == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800775 (idleTimeout == null) ||
776 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700777 (switchDpidStr == null) ||
778 (userState == null) ||
779 (switchState == null)) {
Brian O'Connora8e49802013-10-30 20:49:59 -0700780 // TODO: A work-around, because of some bogus database objects
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700781 return null;
782 }
783
784 FlowEntry flowEntry = new FlowEntry();
785 flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800786 flowEntry.setFlowId(new FlowId(flowIdStr));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700787 flowEntry.setDpid(new Dpid(switchDpidStr));
Pavlin Radoslavovce93a032013-12-13 11:03:02 -0800788 flowEntry.setIdleTimeout(idleTimeout);
789 flowEntry.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700790
791 //
792 // Extract the match conditions
793 //
794 FlowEntryMatch match = new FlowEntryMatch();
795 Short matchInPort = flowEntryObj.getMatchInPort();
796 if (matchInPort != null)
797 match.enableInPort(new Port(matchInPort));
798 String matchSrcMac = flowEntryObj.getMatchSrcMac();
799 if (matchSrcMac != null)
800 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
801 String matchDstMac = flowEntryObj.getMatchDstMac();
802 if (matchDstMac != null)
803 match.enableDstMac(MACAddress.valueOf(matchDstMac));
804 Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
805 if (matchEthernetFrameType != null)
806 match.enableEthernetFrameType(matchEthernetFrameType);
807 Short matchVlanId = flowEntryObj.getMatchVlanId();
808 if (matchVlanId != null)
809 match.enableVlanId(matchVlanId);
810 Byte matchVlanPriority = flowEntryObj.getMatchVlanPriority();
811 if (matchVlanPriority != null)
812 match.enableVlanPriority(matchVlanPriority);
813 String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
814 if (matchSrcIPv4Net != null)
815 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
816 String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
817 if (matchDstIPv4Net != null)
818 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
819 Byte matchIpProto = flowEntryObj.getMatchIpProto();
820 if (matchIpProto != null)
821 match.enableIpProto(matchIpProto);
822 Byte matchIpToS = flowEntryObj.getMatchIpToS();
823 if (matchIpToS != null)
824 match.enableIpToS(matchIpToS);
825 Short matchSrcTcpUdpPort = flowEntryObj.getMatchSrcTcpUdpPort();
826 if (matchSrcTcpUdpPort != null)
827 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
828 Short matchDstTcpUdpPort = flowEntryObj.getMatchDstTcpUdpPort();
829 if (matchDstTcpUdpPort != null)
830 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
831 flowEntry.setFlowEntryMatch(match);
832
833 //
834 // Extract the actions
835 //
836 FlowEntryActions actions = new FlowEntryActions();
837 String actionsStr = flowEntryObj.getActions();
838 if (actionsStr != null)
839 actions = new FlowEntryActions(actionsStr);
840 flowEntry.setFlowEntryActions(actions);
841 flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
842 flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
843 //
844 // TODO: Take care of FlowEntryErrorState.
845 //
846 return flowEntry;
847 }
848}