blob: c04d8ad949dfb12d621e6260d69abc951bfee98b [file] [log] [blame]
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001package net.onrc.onos.ofcontroller.flowmanager;
2
3import java.io.PrintWriter;
4import java.io.StringWriter;
5import java.util.ArrayList;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07006import java.util.LinkedList;
7import java.util.List;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07008
9import net.floodlightcontroller.util.MACAddress;
yoshitomob292c622013-11-23 14:35:58 -080010import net.onrc.onos.graph.DBOperation;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070011import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
12import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
13import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
14import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
15import net.onrc.onos.ofcontroller.util.*;
16
17import org.slf4j.Logger;
18import org.slf4j.LoggerFactory;
19
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -080020import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
21
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070022/**
23 * Class for performing Flow-related operations on the Database.
24 */
Pavlin Radoslavov6bfaea62013-12-03 14:55:57 -080025public class FlowDatabaseOperation {
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070026 private final static Logger log = LoggerFactory.getLogger(FlowDatabaseOperation.class);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -080027 private static final boolean measureONOSFlowTimeProp = Long.valueOf(System.getProperty("benchmark.measureONOSFlow", "0")) != 0;
28 private static final boolean measureONOSFlowEntryTimeProp = Long.valueOf(System.getProperty("benchmark.measureONOSFlowEntry", "0")) != 0;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070029
30 /**
31 * Add a flow.
32 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070033 * @param dbHandler the Graph Database handler to use.
34 * @param flowPath the Flow Path to install.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070035 * @return true on success, otherwise false.
36 */
onlab-qa38805cd2013-12-06 20:08:54 -080037 static boolean addFlow(DBOperation dbHandler, FlowPath flowPath) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070038 IFlowPath flowObj = null;
39 boolean found = false;
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080040 long startAddFlow = 0;
41 long endAddFlow = 0;
42 long endSearchExistingFlowPathTime = 0;
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -080043 long startCreateNewFlowPathTime = 0;
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080044 long endCreateNewFlowPathTime = 0;
45 long startFollowExistingFlowEntries = 0;
46 long endFollowExistingFlowEntries = 0;
47 long accTimeRemovingFlowEntriesFromFlowPath = 0;
48 long accTimeRemovingFlowEntriesFromDB = 0;
49 long startSettingFlowPathProps = 0;
50 long endSettingFlowPathProps = 0;
51 int numPropsSet = 0;
52 long accTimeAddFlowEntries = 0;
53 int numNewFlowEntries = 0;
54 LinkedList<long[]> flowEntryTimes = new LinkedList<>();
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -080055 PerfMon pm = PerfMon.getInstance();
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080056
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -080057 pm.addflowpath_start();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070058 try {
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080059 if ( measureONOSFlowTimeProp ) {
60 startAddFlow = System.nanoTime();
61 }
yoshi40210942013-12-03 08:21:02 -080062 flowObj = dbHandler.searchFlowPath(flowPath.flowId());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080063 if ( measureONOSFlowTimeProp ) {
64 endSearchExistingFlowPathTime = System.nanoTime();
65 }
yoshi40210942013-12-03 08:21:02 -080066 if (flowObj != null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070067 found = true;
68 } else {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -080069 if ( measureONOSFlowTimeProp ) {
70 startCreateNewFlowPathTime = System.nanoTime();
71 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070072 flowObj = dbHandler.newFlowPath();
Yuta HIGUCHI37c55472014-01-03 11:42:27 -080073 if ( measureONOSFlowTimeProp ) {
74 endCreateNewFlowPathTime = System.nanoTime();
75 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070076 }
77 } catch (Exception e) {
78 dbHandler.rollback();
79
80 StringWriter sw = new StringWriter();
81 e.printStackTrace(new PrintWriter(sw));
82 String stacktrace = sw.toString();
83
84 log.error(":addFlow FlowId:{} failed: {}",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -080085 flowPath.flowId(),
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070086 stacktrace);
87 return false;
88 }
89 if (flowObj == null) {
90 log.error(":addFlow FlowId:{} failed: Flow object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -080091 flowPath.flowId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070092 dbHandler.rollback();
93 return false;
94 }
95
96 //
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -080097 // Remove the old Flow Entries
98 //
99 if (found) {
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800100 if ( measureONOSFlowTimeProp ) {
101 startFollowExistingFlowEntries = System.nanoTime();
102 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800103 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800104 if ( measureONOSFlowTimeProp ) {
105 endFollowExistingFlowEntries = System.nanoTime();
106 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800107 LinkedList<IFlowEntry> deleteFlowEntries =
108 new LinkedList<IFlowEntry>();
109 for (IFlowEntry flowEntryObj : flowEntries)
110 deleteFlowEntries.add(flowEntryObj);
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800111 if( measureONOSFlowTimeProp ) {
112 for (IFlowEntry flowEntryObj : deleteFlowEntries) {
113 long start = System.nanoTime();
114 flowObj.removeFlowEntry(flowEntryObj);
115 accTimeRemovingFlowEntriesFromFlowPath += System.nanoTime() - start;
116 start = System.nanoTime();
117 dbHandler.removeFlowEntry(flowEntryObj);
118 accTimeRemovingFlowEntriesFromDB += System.nanoTime() - start;
119 }
120 } else {
121 for (IFlowEntry flowEntryObj : deleteFlowEntries) {
122 flowObj.removeFlowEntry(flowEntryObj);
123 dbHandler.removeFlowEntry(flowEntryObj);
124 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800125 }
126 }
127
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800128 if ( measureONOSFlowTimeProp ) {
129 startSettingFlowPathProps = System.nanoTime();
130 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800131 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700132 // Set the Flow key:
133 // - flowId
134 //
135 flowObj.setFlowId(flowPath.flowId().toString());
136 flowObj.setType("flow");
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800137 if ( measureONOSFlowTimeProp ) {
138 numPropsSet += 2;
139 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700140
141 //
142 // Set the Flow attributes:
143 // - flowPath.installerId()
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700144 // - flowPath.flowPathType()
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700145 // - flowPath.flowPathUserState()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700146 // - flowPath.flowPathFlags()
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800147 // - flowPath.idleTimeout()
148 // - flowPath.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700149 // - flowPath.dataPath().srcPort()
150 // - flowPath.dataPath().dstPort()
151 // - flowPath.matchSrcMac()
152 // - flowPath.matchDstMac()
153 // - flowPath.matchEthernetFrameType()
154 // - flowPath.matchVlanId()
155 // - flowPath.matchVlanPriority()
156 // - flowPath.matchSrcIPv4Net()
157 // - flowPath.matchDstIPv4Net()
158 // - flowPath.matchIpProto()
159 // - flowPath.matchIpToS()
160 // - flowPath.matchSrcTcpUdpPort()
161 // - flowPath.matchDstTcpUdpPort()
162 // - flowPath.flowEntryActions()
163 //
164 flowObj.setInstallerId(flowPath.installerId().toString());
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700165 flowObj.setFlowPathType(flowPath.flowPathType().toString());
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700166 flowObj.setFlowPathUserState(flowPath.flowPathUserState().toString());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700167 flowObj.setFlowPathFlags(flowPath.flowPathFlags().flags());
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800168 flowObj.setIdleTimeout(flowPath.idleTimeout());
169 flowObj.setHardTimeout(flowPath.hardTimeout());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700170 flowObj.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
171 flowObj.setSrcPort(flowPath.dataPath().srcPort().port().value());
172 flowObj.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
173 flowObj.setDstPort(flowPath.dataPath().dstPort().port().value());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800174 if ( measureONOSFlowTimeProp ) {
175 numPropsSet += 10;
176 }
177
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700178 if (flowPath.flowEntryMatch().matchSrcMac()) {
179 flowObj.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800180 if ( measureONOSFlowTimeProp ) {
181 ++numPropsSet;
182 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700183 }
184 if (flowPath.flowEntryMatch().matchDstMac()) {
185 flowObj.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800186 if ( measureONOSFlowTimeProp ) {
187 ++numPropsSet;
188 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700189 }
190 if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
191 flowObj.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800192 if ( measureONOSFlowTimeProp ) {
193 ++numPropsSet;
194 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700195 }
196 if (flowPath.flowEntryMatch().matchVlanId()) {
197 flowObj.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800198 if ( measureONOSFlowTimeProp ) {
199 ++numPropsSet;
200 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700201 }
202 if (flowPath.flowEntryMatch().matchVlanPriority()) {
203 flowObj.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800204 if ( measureONOSFlowTimeProp ) {
205 ++numPropsSet;
206 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700207 }
208 if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
209 flowObj.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800210 if ( measureONOSFlowTimeProp ) {
211 ++numPropsSet;
212 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700213 }
214 if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
215 flowObj.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800216 if ( measureONOSFlowTimeProp ) {
217 ++numPropsSet;
218 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700219 }
220 if (flowPath.flowEntryMatch().matchIpProto()) {
221 flowObj.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800222 if ( measureONOSFlowTimeProp ) {
223 ++numPropsSet;
224 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700225 }
226 if (flowPath.flowEntryMatch().matchIpToS()) {
227 flowObj.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800228 if ( measureONOSFlowTimeProp ) {
229 ++numPropsSet;
230 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700231 }
232 if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
233 flowObj.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800234 if ( measureONOSFlowTimeProp ) {
235 ++numPropsSet;
236 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700237 }
238 if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
239 flowObj.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800240 if ( measureONOSFlowTimeProp ) {
241 ++numPropsSet;
242 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700243 }
244 if (! flowPath.flowEntryActions().actions().isEmpty()) {
245 flowObj.setActions(flowPath.flowEntryActions().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800246 if ( measureONOSFlowTimeProp ) {
247 ++numPropsSet;
248 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700249 }
Pavlin Radoslavovbcc86ef2013-10-26 12:06:25 -0700250 flowObj.setDataPathSummary(flowPath.dataPath().dataPathSummary());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800251 if ( measureONOSFlowTimeProp ) {
252 ++numPropsSet;
253 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700254
255 if (found)
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700256 flowObj.setFlowPathUserState("FP_USER_MODIFY");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700257 else
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700258 flowObj.setFlowPathUserState("FP_USER_ADD");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700259
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800260 if ( measureONOSFlowTimeProp ) {
261 ++numPropsSet;
262 }
263
264 if ( measureONOSFlowTimeProp ) {
265 endSettingFlowPathProps = System.nanoTime();
266 }
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800267 pm.addflowpath_end();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700268 // Flow edges:
269 // HeadFE
270
271
272 //
273 // Flow Entries:
274 // flowPath.dataPath().flowEntries()
275 //
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800276 pm.addflowentry_start();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700277 for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800278 if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE)
279 continue; // Skip: all Flow Entries were deleted earlier
280
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800281 pm.addflowentry_incr();
282
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800283 long startAddFlowEntry = 0, endAddFlowEntry;
284 if( measureONOSFlowTimeProp ) {
285 startAddFlowEntry = System.nanoTime();
286 }
287 IFlowEntry iFlowEntry = addFlowEntry(dbHandler, flowObj, flowEntry);
288 if( measureONOSFlowTimeProp ) {
289 endAddFlowEntry = System.nanoTime();
290 accTimeAddFlowEntries += endAddFlowEntry - startAddFlowEntry;
291
292 flowEntryTimes.addLast( new long[]{flowEntry.flowId().value(), endAddFlowEntry - startAddFlowEntry} );
293 }
294 if ( iFlowEntry == null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700295 dbHandler.rollback();
296 return false;
297 }
298 }
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800299 pm.addflowentry_end();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700300 dbHandler.commit();
301
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800302
303 if ( measureONOSFlowTimeProp ) {
304 endAddFlow = System.nanoTime();
305
Yuta HIGUCHI0b4fbaf2014-01-04 22:23:05 -0800306 log.error("Performance addFlow(_,{}) -- "
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800307 + "GrandTotal: {} "
308 + "only FlowPathTotal: {} "
309 + "searchExistingFlowPath: {} "
310 + "createNewFlowPathTime: {}"
311 + "followExistingFlowEntries: {} "
312 + "accTimeRemovingFlowEntriesFromFlowPath: {} "
313 + "accTimeRemovingFlowEntriesFromDB: {} "
314 + "settingFlowPathProps: {} #Props: {} "
315 + "accFlowEntries: {} #FEs: {}",
316 flowPath.flowId(),
317 (endAddFlow - startAddFlow),
318 (endSettingFlowPathProps - startAddFlow),
319 (endSearchExistingFlowPathTime - startAddFlow),
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800320 (endCreateNewFlowPathTime - startCreateNewFlowPathTime),
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800321 (endFollowExistingFlowEntries - startFollowExistingFlowEntries),
322 (accTimeRemovingFlowEntriesFromFlowPath),
323 (accTimeRemovingFlowEntriesFromDB),
324 (endSettingFlowPathProps - startSettingFlowPathProps), numPropsSet,
325 accTimeAddFlowEntries, numNewFlowEntries
326 );
327
328 // Each FlowEntries
329 final String strFlowId = flowPath.flowId().toString();
330 for ( long[] idFE_Time : flowEntryTimes ) {
Yuta HIGUCHI0b4fbaf2014-01-04 22:23:05 -0800331 log.error("Performance addFlowEntry(_,{},{})@addFlow -- FlowEntryTotal: {}",
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800332 strFlowId,
333 "0x" + Long.toHexString(idFE_Time[0]),
334 idFE_Time[1]);
335 }
336 }
337
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700338 return true;
339 }
340
341 /**
342 * Add a flow entry to the Network MAP.
343 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700344 * @param dbHandler the Graph Database handler to use.
345 * @param flowObj the corresponding Flow Path object for the Flow Entry.
346 * @param flowEntry the Flow Entry to install.
347 * @return the added Flow Entry object on success, otherwise null.
348 */
onlab-qa38805cd2013-12-06 20:08:54 -0800349 static IFlowEntry addFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700350 IFlowPath flowObj,
351 FlowEntry flowEntry) {
352 // Flow edges
353 // HeadFE (TODO)
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800354 long startAddFlowEntry = 0;
355 long endAddFlowEntry = 0;
356
357 long endSearchFlowEntry = 0;
358
359 long startCreateNewFlowEntry = 0;
360 long endCreateNewFlowEntry = 0;
361
362 long startSetProperties = 0;
363 long endSetProperties = 0;
364 int numProperties = 0;
365
366 long startSearchSwitch = 0;
367 long endSearchSwitch = 0;
368
369 long startAddEdgeToSwitch =0;
370 long endAddEdgeToSwitch =0;
371
372 long startSearchInPort = 0;
373 long endSearchInPort = 0;
374
375 long startAddEdgeToInPort =0;
376 long endAddEdgeToInPort =0;
377
378 long startSearchOutPort = 0;
379 long endSearchOutPort = 0;
380
381 long startAddEdgeToOutPort =0;
382 long endAddEdgeToOutPort =0;
383
384 long startAddEdgeBetweenFlowPath = 0;
385 long endAddEdgeBetweenFlowPath = 0;
386
387 if (measureONOSFlowEntryTimeProp) {
388 startAddFlowEntry = System.nanoTime();
389 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700390
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700391 IFlowEntry flowEntryObj = null;
392 boolean found = false;
393 try {
Yuta HIGUCHIc27a6c92014-01-07 11:51:11 -0800394 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
395 if (measureONOSFlowEntryTimeProp) {
396 endSearchFlowEntry = System.nanoTime();
397 }
398 if (flowEntryObj != null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700399 found = true;
400 } else {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800401 if (measureONOSFlowEntryTimeProp) {
402 startCreateNewFlowEntry = System.nanoTime();
403 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700404 flowEntryObj = dbHandler.newFlowEntry();
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800405 if (measureONOSFlowEntryTimeProp) {
406 endCreateNewFlowEntry = System.nanoTime();
407 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700408 }
409 } catch (Exception e) {
410 log.error(":addFlow FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800411 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700412 return null;
413 }
414 if (flowEntryObj == null) {
415 log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800416 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700417 return null;
418 }
419
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800420 if (measureONOSFlowEntryTimeProp) {
421 startSetProperties = System.nanoTime();
422 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700423 //
424 // Set the Flow Entry key:
425 // - flowEntry.flowEntryId()
426 //
427 flowEntryObj.setFlowEntryId(flowEntry.flowEntryId().toString());
428 flowEntryObj.setType("flow_entry");
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800429 if (measureONOSFlowEntryTimeProp) {
430 numProperties += 2;
431 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700432
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800433 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700434 // Set the Flow Entry Edges and attributes:
435 // - Switch edge
436 // - InPort edge
437 // - OutPort edge
438 //
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800439 // - flowEntry.idleTimeout()
440 // - flowEntry.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700441 // - flowEntry.dpid()
442 // - flowEntry.flowEntryUserState()
443 // - flowEntry.flowEntrySwitchState()
444 // - flowEntry.flowEntryErrorState()
445 // - flowEntry.matchInPort()
446 // - flowEntry.matchSrcMac()
447 // - flowEntry.matchDstMac()
448 // - flowEntry.matchEthernetFrameType()
449 // - flowEntry.matchVlanId()
450 // - flowEntry.matchVlanPriority()
451 // - flowEntry.matchSrcIPv4Net()
452 // - flowEntry.matchDstIPv4Net()
453 // - flowEntry.matchIpProto()
454 // - flowEntry.matchIpToS()
455 // - flowEntry.matchSrcTcpUdpPort()
456 // - flowEntry.matchDstTcpUdpPort()
457 // - flowEntry.actionOutputPort()
458 // - flowEntry.actions()
459 //
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800460 if (measureONOSFlowEntryTimeProp) {
461 startSearchSwitch = System.nanoTime();
462 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700463 ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800464 if (measureONOSFlowEntryTimeProp) {
465 endSearchSwitch = System.nanoTime();
466 }
467
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800468 flowEntryObj.setIdleTimeout(flowEntry.idleTimeout());
469 flowEntryObj.setHardTimeout(flowEntry.hardTimeout());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700470 flowEntryObj.setSwitchDpid(flowEntry.dpid().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800471 if (measureONOSFlowEntryTimeProp) {
472 numProperties += 3;
473 }
474
475 if (measureONOSFlowEntryTimeProp) {
476 startAddEdgeToSwitch = System.nanoTime();
477 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700478 flowEntryObj.setSwitch(sw);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800479 if (measureONOSFlowEntryTimeProp) {
480 endAddEdgeToSwitch = System.nanoTime();
481 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700482 if (flowEntry.flowEntryMatch().matchInPort()) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800483 if (measureONOSFlowEntryTimeProp) {
484 startSearchInPort = System.nanoTime();
485 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700486 IPortObject inport =
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800487 dbHandler.searchPort(flowEntry.dpid().toString(),
488 flowEntry.flowEntryMatch().inPort().value());
489 if (measureONOSFlowEntryTimeProp) {
490 endSearchInPort = System.nanoTime();
491 }
492
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700493 flowEntryObj.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800494 if (measureONOSFlowEntryTimeProp) {
495 ++numProperties;
496 }
497
498 if (measureONOSFlowEntryTimeProp) {
499 startAddEdgeToInPort = System.nanoTime();
500 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700501 flowEntryObj.setInPort(inport);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800502 if (measureONOSFlowEntryTimeProp) {
503 endAddEdgeToInPort = System.nanoTime();
504 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700505 }
506 if (flowEntry.flowEntryMatch().matchSrcMac()) {
507 flowEntryObj.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800508 if (measureONOSFlowEntryTimeProp) {
509 ++numProperties;
510 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700511 }
512 if (flowEntry.flowEntryMatch().matchDstMac()) {
513 flowEntryObj.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800514 if (measureONOSFlowEntryTimeProp) {
515 ++numProperties;
516 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700517 }
518 if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
519 flowEntryObj.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800520 if (measureONOSFlowEntryTimeProp) {
521 ++numProperties;
522 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700523 }
524 if (flowEntry.flowEntryMatch().matchVlanId()) {
525 flowEntryObj.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800526 if (measureONOSFlowEntryTimeProp) {
527 ++numProperties;
528 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700529 }
530 if (flowEntry.flowEntryMatch().matchVlanPriority()) {
531 flowEntryObj.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800532 if (measureONOSFlowEntryTimeProp) {
533 ++numProperties;
534 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700535 }
536 if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
537 flowEntryObj.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800538 if (measureONOSFlowEntryTimeProp) {
539 ++numProperties;
540 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700541 }
542 if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
543 flowEntryObj.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800544 if (measureONOSFlowEntryTimeProp) {
545 ++numProperties;
546 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700547 }
548 if (flowEntry.flowEntryMatch().matchIpProto()) {
549 flowEntryObj.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800550 if (measureONOSFlowEntryTimeProp) {
551 ++numProperties;
552 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700553 }
554 if (flowEntry.flowEntryMatch().matchIpToS()) {
555 flowEntryObj.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800556 if (measureONOSFlowEntryTimeProp) {
557 ++numProperties;
558 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700559 }
560 if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
561 flowEntryObj.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800562 if (measureONOSFlowEntryTimeProp) {
563 ++numProperties;
564 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700565 }
566 if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
567 flowEntryObj.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800568 if (measureONOSFlowEntryTimeProp) {
569 ++numProperties;
570 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700571 }
572
573 for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
574 if (fa.actionOutput() != null) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800575 if (measureONOSFlowEntryTimeProp) {
576 if ( startSearchOutPort != 0 ) log.error("Performance addFlowEntry(_,{},{}) -- Multiple output port action unexpected.", flowEntry.flowId(), flowEntry.flowEntryId());
577 startSearchOutPort = System.nanoTime();
578 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700579 IPortObject outport =
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800580 dbHandler.searchPort(flowEntry.dpid().toString(),
581 fa.actionOutput().port().value());
582 if (measureONOSFlowEntryTimeProp) {
583 endSearchOutPort = System.nanoTime();
584 }
585
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700586 flowEntryObj.setActionOutputPort(fa.actionOutput().port().value());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800587 if (measureONOSFlowEntryTimeProp) {
588 ++numProperties;
589 }
590
591 if (measureONOSFlowEntryTimeProp) {
592 startAddEdgeToOutPort = System.nanoTime();
593 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700594 flowEntryObj.setOutPort(outport);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800595 if (measureONOSFlowEntryTimeProp) {
596 endAddEdgeToOutPort = System.nanoTime();
597 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700598 }
599 }
600 if (! flowEntry.flowEntryActions().isEmpty()) {
601 flowEntryObj.setActions(flowEntry.flowEntryActions().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800602 if (measureONOSFlowEntryTimeProp) {
603 ++numProperties;
604 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700605 }
606
607 // TODO: Hacks with hard-coded state names!
608 if (found)
609 flowEntryObj.setUserState("FE_USER_MODIFY");
610 else
611 flowEntryObj.setUserState("FE_USER_ADD");
Pavlin Radoslavovebc8b192013-10-29 15:35:35 -0700612 flowEntryObj.setSwitchState(flowEntry.flowEntrySwitchState().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800613 if (measureONOSFlowEntryTimeProp) {
614 numProperties += 2;
615 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700616 //
617 // TODO: Take care of the FlowEntryErrorState.
618 //
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800619 if (measureONOSFlowEntryTimeProp) {
620 endSetProperties = System.nanoTime();
621 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700622
623 // Flow Entries edges:
624 // Flow
625 // NextFE (TODO)
626 if (! found) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800627 if (measureONOSFlowEntryTimeProp) {
628 startAddEdgeBetweenFlowPath = System.nanoTime();
629 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700630 flowObj.addFlowEntry(flowEntryObj);
631 flowEntryObj.setFlow(flowObj);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800632 if (measureONOSFlowEntryTimeProp) {
633 endAddEdgeBetweenFlowPath = System.nanoTime();
634 }
635 }
636 if (measureONOSFlowEntryTimeProp) {
637 endAddFlowEntry = System.nanoTime();
638
639 log.error("Performance addFlowEntry(_,{},{}) -- "
640 + "GrandTotal: {} "
641 + "SearchExistingFE: {} "
642 + "CreateNewFE: {} "
643 + "SetProp+Edge: {} #Props: {} "
644 + "SearchSwitch: {} "
645 + "AddEdgeToSwitch: {} "
646 + "SearchInPort: {} "
647 + "AddEdgeToInPort: {} "
648 + "SearchOutPort: {} "
649 + "AddEdgeToOutPort: {} "
650 + "AddEdgeBetweenFlowPath: {} "
651 , flowEntry.flowId(), flowEntry.flowEntryId()
652 , endAddFlowEntry - startAddFlowEntry
653 , endSearchFlowEntry - startAddFlowEntry
654 , endCreateNewFlowEntry - startCreateNewFlowEntry
655 , endSetProperties - startSetProperties, numProperties
656 , endSearchSwitch - startSearchSwitch
657 , endAddEdgeToSwitch - startAddEdgeToSwitch
658 , endSearchInPort - startSearchInPort
659 , endAddEdgeToInPort - startAddEdgeToInPort
660 , endSearchOutPort - startSearchOutPort
661 , endAddEdgeToOutPort - startAddEdgeToOutPort
662 , endAddEdgeBetweenFlowPath - startAddEdgeBetweenFlowPath
663 );
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700664 }
665
666 return flowEntryObj;
667 }
668
669 /**
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700670 * Delete a flow entry from the Network MAP.
671 *
672 * @param dbHandler the Graph Database handler to use.
673 * @param flowObj the corresponding Flow Path object for the Flow Entry.
674 * @param flowEntry the Flow Entry to delete.
675 * @return true on success, otherwise false.
676 */
yoshitomob292c622013-11-23 14:35:58 -0800677 static boolean deleteFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700678 IFlowPath flowObj,
679 FlowEntry flowEntry) {
680 IFlowEntry flowEntryObj = null;
681 try {
682 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
683 } catch (Exception e) {
684 log.error(":deleteFlowEntry FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800685 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700686 return false;
687 }
688 //
689 // TODO: Don't print an error for now, because multiple controller
690 // instances might be deleting the same flow entry.
691 //
692 /*
693 if (flowEntryObj == null) {
694 log.error(":deleteFlowEntry FlowEntryId:{} failed: FlowEntry object not found",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800695 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700696 return false;
697 }
698 */
699 if (flowEntryObj == null)
700 return true;
701
702 flowObj.removeFlowEntry(flowEntryObj);
703 dbHandler.removeFlowEntry(flowEntryObj);
704 return true;
705 }
706
707 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700708 * Delete all previously added flows.
709 *
710 * @param dbHandler the Graph Database handler to use.
711 * @return true on success, otherwise false.
712 */
yoshitomob292c622013-11-23 14:35:58 -0800713 static boolean deleteAllFlows(DBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700714 List<FlowId> allFlowIds = new LinkedList<FlowId>();
715
716 // Get all Flow IDs
717 Iterable<IFlowPath> allFlowPaths = dbHandler.getAllFlowPaths();
718 for (IFlowPath flowPathObj : allFlowPaths) {
719 if (flowPathObj == null)
720 continue;
721 String flowIdStr = flowPathObj.getFlowId();
722 if (flowIdStr == null)
723 continue;
724 FlowId flowId = new FlowId(flowIdStr);
725 allFlowIds.add(flowId);
726 }
727
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800728 // Delete all flows one-by-one
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700729 for (FlowId flowId : allFlowIds) {
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800730 deleteFlow(dbHandler, flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700731 }
732
733 return true;
734 }
735
736 /**
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800737 * Delete a previously added flow.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700738 *
739 * @param dbHandler the Graph Database handler to use.
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800740 * @param flowId the Flow ID of the flow to delete.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700741 * @return true on success, otherwise false.
742 */
yoshitomob292c622013-11-23 14:35:58 -0800743 static boolean deleteFlow(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700744 IFlowPath flowObj = null;
745 try {
746 flowObj = dbHandler.searchFlowPath(flowId);
747 } catch (Exception e) {
748 // TODO: handle exceptions
749 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800750 log.error(":deleteFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700751 return false;
752 }
753 if (flowObj == null) {
754 dbHandler.commit();
755 return true; // OK: No such flow
756 }
757
758 //
759 // Remove all Flow Entries
760 //
761 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
762 for (IFlowEntry flowEntryObj : flowEntries) {
763 flowObj.removeFlowEntry(flowEntryObj);
764 dbHandler.removeFlowEntry(flowEntryObj);
765 }
766 // Remove the Flow itself
767 dbHandler.removeFlowPath(flowObj);
768 dbHandler.commit();
769
770 return true;
771 }
772
773 /**
774 * Get a previously added flow.
775 *
776 * @param dbHandler the Graph Database handler to use.
777 * @param flowId the Flow ID of the flow to get.
778 * @return the Flow Path if found, otherwise null.
779 */
yoshitomob292c622013-11-23 14:35:58 -0800780 static FlowPath getFlow(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700781 IFlowPath flowObj = null;
782 try {
783 flowObj = dbHandler.searchFlowPath(flowId);
784 } catch (Exception e) {
785 // TODO: handle exceptions
786 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800787 log.error(":getFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700788 return null;
789 }
790 if (flowObj == null) {
791 dbHandler.commit();
792 return null; // Flow not found
793 }
794
795 //
796 // Extract the Flow state
797 //
798 FlowPath flowPath = extractFlowPath(flowObj);
799 dbHandler.commit();
800
801 return flowPath;
802 }
803
804 /**
805 * Get all installed flows by all installers.
806 *
807 * @param dbHandler the Graph Database handler to use.
808 * @return the Flow Paths if found, otherwise null.
809 */
yoshitomob292c622013-11-23 14:35:58 -0800810 static ArrayList<FlowPath> getAllFlows(DBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700811 Iterable<IFlowPath> flowPathsObj = null;
812 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
813
814 try {
815 flowPathsObj = dbHandler.getAllFlowPaths();
816 } catch (Exception e) {
817 // TODO: handle exceptions
818 dbHandler.rollback();
819 log.error(":getAllFlowPaths failed");
820 return flowPaths;
821 }
822 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
823 dbHandler.commit();
824 return flowPaths; // No Flows found
825 }
826
827 for (IFlowPath flowObj : flowPathsObj) {
828 //
829 // Extract the Flow state
830 //
831 FlowPath flowPath = extractFlowPath(flowObj);
832 if (flowPath != null)
833 flowPaths.add(flowPath);
834 }
835
836 dbHandler.commit();
837
838 return flowPaths;
839 }
840
841 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700842 * Extract Flow Path State from a Titan Database Object @ref IFlowPath.
843 *
844 * @param flowObj the object to extract the Flow Path State from.
845 * @return the extracted Flow Path State.
846 */
847 private static FlowPath extractFlowPath(IFlowPath flowObj) {
848 //
849 // Extract the Flow state
850 //
851 String flowIdStr = flowObj.getFlowId();
852 String installerIdStr = flowObj.getInstallerId();
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700853 String flowPathType = flowObj.getFlowPathType();
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700854 String flowPathUserState = flowObj.getFlowPathUserState();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700855 Long flowPathFlags = flowObj.getFlowPathFlags();
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800856 Integer idleTimeout = flowObj.getIdleTimeout();
857 Integer hardTimeout = flowObj.getHardTimeout();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700858 String srcSwitchStr = flowObj.getSrcSwitch();
859 Short srcPortShort = flowObj.getSrcPort();
860 String dstSwitchStr = flowObj.getDstSwitch();
861 Short dstPortShort = flowObj.getDstPort();
862
863 if ((flowIdStr == null) ||
864 (installerIdStr == null) ||
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700865 (flowPathType == null) ||
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700866 (flowPathUserState == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700867 (flowPathFlags == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800868 (idleTimeout == null) ||
869 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700870 (srcSwitchStr == null) ||
871 (srcPortShort == null) ||
872 (dstSwitchStr == null) ||
873 (dstPortShort == null)) {
874 // TODO: A work-around, becauuse of some bogus database objects
875 return null;
876 }
877
878 FlowPath flowPath = new FlowPath();
879 flowPath.setFlowId(new FlowId(flowIdStr));
880 flowPath.setInstallerId(new CallerId(installerIdStr));
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700881 flowPath.setFlowPathType(FlowPathType.valueOf(flowPathType));
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700882 flowPath.setFlowPathUserState(FlowPathUserState.valueOf(flowPathUserState));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700883 flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800884 flowPath.setIdleTimeout(idleTimeout);
885 flowPath.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700886 flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
887 flowPath.dataPath().srcPort().setPort(new Port(srcPortShort));
888 flowPath.dataPath().dstPort().setDpid(new Dpid(dstSwitchStr));
889 flowPath.dataPath().dstPort().setPort(new Port(dstPortShort));
890 //
891 // Extract the match conditions common for all Flow Entries
892 //
893 {
894 FlowEntryMatch match = new FlowEntryMatch();
895 String matchSrcMac = flowObj.getMatchSrcMac();
896 if (matchSrcMac != null)
897 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
898 String matchDstMac = flowObj.getMatchDstMac();
899 if (matchDstMac != null)
900 match.enableDstMac(MACAddress.valueOf(matchDstMac));
901 Short matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
902 if (matchEthernetFrameType != null)
903 match.enableEthernetFrameType(matchEthernetFrameType);
904 Short matchVlanId = flowObj.getMatchVlanId();
905 if (matchVlanId != null)
906 match.enableVlanId(matchVlanId);
907 Byte matchVlanPriority = flowObj.getMatchVlanPriority();
908 if (matchVlanPriority != null)
909 match.enableVlanPriority(matchVlanPriority);
910 String matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
911 if (matchSrcIPv4Net != null)
912 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
913 String matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
914 if (matchDstIPv4Net != null)
915 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
916 Byte matchIpProto = flowObj.getMatchIpProto();
917 if (matchIpProto != null)
918 match.enableIpProto(matchIpProto);
919 Byte matchIpToS = flowObj.getMatchIpToS();
920 if (matchIpToS != null)
921 match.enableIpToS(matchIpToS);
922 Short matchSrcTcpUdpPort = flowObj.getMatchSrcTcpUdpPort();
923 if (matchSrcTcpUdpPort != null)
924 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
925 Short matchDstTcpUdpPort = flowObj.getMatchDstTcpUdpPort();
926 if (matchDstTcpUdpPort != null)
927 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
928
929 flowPath.setFlowEntryMatch(match);
930 }
931 //
932 // Extract the actions for the first Flow Entry
933 //
934 {
935 String actionsStr = flowObj.getActions();
936 if (actionsStr != null) {
937 FlowEntryActions flowEntryActions = new FlowEntryActions(actionsStr);
938 flowPath.setFlowEntryActions(flowEntryActions);
939 }
940 }
941
942 //
943 // Extract all Flow Entries
944 //
945 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
946 for (IFlowEntry flowEntryObj : flowEntries) {
947 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
948 if (flowEntry == null)
949 continue;
950 flowPath.dataPath().flowEntries().add(flowEntry);
951 }
952
953 return flowPath;
954 }
955
956 /**
957 * Extract Flow Entry State from a Titan Database Object @ref IFlowEntry.
958 *
959 * @param flowEntryObj the object to extract the Flow Entry State from.
960 * @return the extracted Flow Entry State.
961 */
Brian O'Connora8e49802013-10-30 20:49:59 -0700962 public static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800963 IFlowPath flowObj = flowEntryObj.getFlow();
964 if (flowObj == null)
965 return null;
966
967 String flowIdStr = flowObj.getFlowId();
968 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700969 String flowEntryIdStr = flowEntryObj.getFlowEntryId();
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800970 Integer idleTimeout = flowEntryObj.getIdleTimeout();
971 Integer hardTimeout = flowEntryObj.getHardTimeout();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700972 String switchDpidStr = flowEntryObj.getSwitchDpid();
973 String userState = flowEntryObj.getUserState();
974 String switchState = flowEntryObj.getSwitchState();
975
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800976 if ((flowIdStr == null) ||
977 (flowEntryIdStr == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800978 (idleTimeout == null) ||
979 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700980 (switchDpidStr == null) ||
981 (userState == null) ||
982 (switchState == null)) {
Brian O'Connora8e49802013-10-30 20:49:59 -0700983 // TODO: A work-around, because of some bogus database objects
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700984 return null;
985 }
986
987 FlowEntry flowEntry = new FlowEntry();
988 flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800989 flowEntry.setFlowId(new FlowId(flowIdStr));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700990 flowEntry.setDpid(new Dpid(switchDpidStr));
yoshia97632b2013-12-17 15:46:08 -0800991 flowEntry.setIdleTimeout(idleTimeout);
992 flowEntry.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700993
994 //
995 // Extract the match conditions
996 //
997 FlowEntryMatch match = new FlowEntryMatch();
998 Short matchInPort = flowEntryObj.getMatchInPort();
999 if (matchInPort != null)
1000 match.enableInPort(new Port(matchInPort));
1001 String matchSrcMac = flowEntryObj.getMatchSrcMac();
1002 if (matchSrcMac != null)
1003 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
1004 String matchDstMac = flowEntryObj.getMatchDstMac();
1005 if (matchDstMac != null)
1006 match.enableDstMac(MACAddress.valueOf(matchDstMac));
1007 Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
1008 if (matchEthernetFrameType != null)
1009 match.enableEthernetFrameType(matchEthernetFrameType);
1010 Short matchVlanId = flowEntryObj.getMatchVlanId();
1011 if (matchVlanId != null)
1012 match.enableVlanId(matchVlanId);
1013 Byte matchVlanPriority = flowEntryObj.getMatchVlanPriority();
1014 if (matchVlanPriority != null)
1015 match.enableVlanPriority(matchVlanPriority);
1016 String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
1017 if (matchSrcIPv4Net != null)
1018 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
1019 String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
1020 if (matchDstIPv4Net != null)
1021 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
1022 Byte matchIpProto = flowEntryObj.getMatchIpProto();
1023 if (matchIpProto != null)
1024 match.enableIpProto(matchIpProto);
1025 Byte matchIpToS = flowEntryObj.getMatchIpToS();
1026 if (matchIpToS != null)
1027 match.enableIpToS(matchIpToS);
1028 Short matchSrcTcpUdpPort = flowEntryObj.getMatchSrcTcpUdpPort();
1029 if (matchSrcTcpUdpPort != null)
1030 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
1031 Short matchDstTcpUdpPort = flowEntryObj.getMatchDstTcpUdpPort();
1032 if (matchDstTcpUdpPort != null)
1033 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
1034 flowEntry.setFlowEntryMatch(match);
1035
1036 //
1037 // Extract the actions
1038 //
1039 FlowEntryActions actions = new FlowEntryActions();
1040 String actionsStr = flowEntryObj.getActions();
1041 if (actionsStr != null)
1042 actions = new FlowEntryActions(actionsStr);
1043 flowEntry.setFlowEntryActions(actions);
1044 flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
1045 flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
1046 //
1047 // TODO: Take care of FlowEntryErrorState.
1048 //
1049 return flowEntry;
1050 }
1051}