blob: 27521f94bbde5231d7d36c6142d0c08865b47f19 [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 }
Toshio Koidea9b25142014-01-10 01:15:57 -0800131
132 FlowPathProperty flowProp = new FlowPathProperty(dbHandler, flowObj);
133
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800134 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700135 // Set the Flow key:
136 // - flowId
137 //
Toshio Koidea9b25142014-01-10 01:15:57 -0800138 flowProp.setFlowId(flowPath.flowId().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800139 if ( measureONOSFlowTimeProp ) {
140 numPropsSet += 2;
141 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700142
143 //
144 // Set the Flow attributes:
145 // - flowPath.installerId()
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700146 // - flowPath.flowPathType()
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700147 // - flowPath.flowPathUserState()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700148 // - flowPath.flowPathFlags()
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800149 // - flowPath.idleTimeout()
150 // - flowPath.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700151 // - flowPath.dataPath().srcPort()
152 // - flowPath.dataPath().dstPort()
153 // - flowPath.matchSrcMac()
154 // - flowPath.matchDstMac()
155 // - flowPath.matchEthernetFrameType()
156 // - flowPath.matchVlanId()
157 // - flowPath.matchVlanPriority()
158 // - flowPath.matchSrcIPv4Net()
159 // - flowPath.matchDstIPv4Net()
160 // - flowPath.matchIpProto()
161 // - flowPath.matchIpToS()
162 // - flowPath.matchSrcTcpUdpPort()
163 // - flowPath.matchDstTcpUdpPort()
164 // - flowPath.flowEntryActions()
165 //
Toshio Koidea9b25142014-01-10 01:15:57 -0800166 flowProp.setInstallerId(flowPath.installerId().toString());
167 flowProp.setFlowPathType(flowPath.flowPathType().toString());
168 flowProp.setFlowPathUserState(flowPath.flowPathUserState().toString());
169 flowProp.setFlowPathFlags(flowPath.flowPathFlags().flags());
170 flowProp.setIdleTimeout(flowPath.idleTimeout());
171 flowProp.setHardTimeout(flowPath.hardTimeout());
172 flowProp.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
173 flowProp.setSrcPort(flowPath.dataPath().srcPort().port().value());
174 flowProp.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
175 flowProp.setDstPort(flowPath.dataPath().dstPort().port().value());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800176 if ( measureONOSFlowTimeProp ) {
177 numPropsSet += 10;
178 }
179
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700180 if (flowPath.flowEntryMatch().matchSrcMac()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800181 flowProp.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800182 if ( measureONOSFlowTimeProp ) {
183 ++numPropsSet;
184 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700185 }
186 if (flowPath.flowEntryMatch().matchDstMac()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800187 flowProp.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800188 if ( measureONOSFlowTimeProp ) {
189 ++numPropsSet;
190 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700191 }
192 if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800193 flowProp.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800194 if ( measureONOSFlowTimeProp ) {
195 ++numPropsSet;
196 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700197 }
198 if (flowPath.flowEntryMatch().matchVlanId()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800199 flowProp.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800200 if ( measureONOSFlowTimeProp ) {
201 ++numPropsSet;
202 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700203 }
204 if (flowPath.flowEntryMatch().matchVlanPriority()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800205 flowProp.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800206 if ( measureONOSFlowTimeProp ) {
207 ++numPropsSet;
208 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700209 }
210 if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800211 flowProp.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800212 if ( measureONOSFlowTimeProp ) {
213 ++numPropsSet;
214 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700215 }
216 if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800217 flowProp.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800218 if ( measureONOSFlowTimeProp ) {
219 ++numPropsSet;
220 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700221 }
222 if (flowPath.flowEntryMatch().matchIpProto()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800223 flowProp.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800224 if ( measureONOSFlowTimeProp ) {
225 ++numPropsSet;
226 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700227 }
228 if (flowPath.flowEntryMatch().matchIpToS()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800229 flowProp.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800230 if ( measureONOSFlowTimeProp ) {
231 ++numPropsSet;
232 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700233 }
234 if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800235 flowProp.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800236 if ( measureONOSFlowTimeProp ) {
237 ++numPropsSet;
238 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700239 }
240 if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800241 flowProp.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800242 if ( measureONOSFlowTimeProp ) {
243 ++numPropsSet;
244 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700245 }
246 if (! flowPath.flowEntryActions().actions().isEmpty()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800247 flowProp.setActions(flowPath.flowEntryActions().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800248 if ( measureONOSFlowTimeProp ) {
249 ++numPropsSet;
250 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700251 }
Toshio Koidea9b25142014-01-10 01:15:57 -0800252 flowProp.setDataPathSummary(flowPath.dataPath().dataPathSummary());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800253 if ( measureONOSFlowTimeProp ) {
254 ++numPropsSet;
255 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700256
257 if (found)
Toshio Koidea9b25142014-01-10 01:15:57 -0800258 flowProp.setFlowPathUserState("FP_USER_MODIFY");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700259 else
Toshio Koidea9b25142014-01-10 01:15:57 -0800260 flowProp.setFlowPathUserState("FP_USER_ADD");
261
262 flowProp.commitProperties();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700263
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800264 if ( measureONOSFlowTimeProp ) {
265 ++numPropsSet;
266 }
267
268 if ( measureONOSFlowTimeProp ) {
269 endSettingFlowPathProps = System.nanoTime();
270 }
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800271 pm.addflowpath_end();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700272 // Flow edges:
273 // HeadFE
274
275
276 //
277 // Flow Entries:
278 // flowPath.dataPath().flowEntries()
279 //
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800280 pm.addflowentry_start();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700281 for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800282 if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE)
283 continue; // Skip: all Flow Entries were deleted earlier
284
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800285 pm.addflowentry_incr();
286
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800287 long startAddFlowEntry = 0, endAddFlowEntry;
288 if( measureONOSFlowTimeProp ) {
289 startAddFlowEntry = System.nanoTime();
290 }
291 IFlowEntry iFlowEntry = addFlowEntry(dbHandler, flowObj, flowEntry);
292 if( measureONOSFlowTimeProp ) {
293 endAddFlowEntry = System.nanoTime();
294 accTimeAddFlowEntries += endAddFlowEntry - startAddFlowEntry;
295
296 flowEntryTimes.addLast( new long[]{flowEntry.flowId().value(), endAddFlowEntry - startAddFlowEntry} );
297 }
298 if ( iFlowEntry == null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700299 dbHandler.rollback();
300 return false;
301 }
302 }
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800303 pm.addflowentry_end();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700304 dbHandler.commit();
305
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800306
307 if ( measureONOSFlowTimeProp ) {
308 endAddFlow = System.nanoTime();
309
Yuta HIGUCHI0b4fbaf2014-01-04 22:23:05 -0800310 log.error("Performance addFlow(_,{}) -- "
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800311 + "GrandTotal: {} "
312 + "only FlowPathTotal: {} "
313 + "searchExistingFlowPath: {} "
314 + "createNewFlowPathTime: {}"
315 + "followExistingFlowEntries: {} "
316 + "accTimeRemovingFlowEntriesFromFlowPath: {} "
317 + "accTimeRemovingFlowEntriesFromDB: {} "
318 + "settingFlowPathProps: {} #Props: {} "
319 + "accFlowEntries: {} #FEs: {}",
320 flowPath.flowId(),
321 (endAddFlow - startAddFlow),
322 (endSettingFlowPathProps - startAddFlow),
323 (endSearchExistingFlowPathTime - startAddFlow),
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800324 (endCreateNewFlowPathTime - startCreateNewFlowPathTime),
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800325 (endFollowExistingFlowEntries - startFollowExistingFlowEntries),
326 (accTimeRemovingFlowEntriesFromFlowPath),
327 (accTimeRemovingFlowEntriesFromDB),
328 (endSettingFlowPathProps - startSettingFlowPathProps), numPropsSet,
329 accTimeAddFlowEntries, numNewFlowEntries
330 );
331
332 // Each FlowEntries
333 final String strFlowId = flowPath.flowId().toString();
334 for ( long[] idFE_Time : flowEntryTimes ) {
Yuta HIGUCHI0b4fbaf2014-01-04 22:23:05 -0800335 log.error("Performance addFlowEntry(_,{},{})@addFlow -- FlowEntryTotal: {}",
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800336 strFlowId,
337 "0x" + Long.toHexString(idFE_Time[0]),
338 idFE_Time[1]);
339 }
340 }
341
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700342 return true;
343 }
344
345 /**
346 * Add a flow entry to the Network MAP.
347 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700348 * @param dbHandler the Graph Database handler to use.
349 * @param flowObj the corresponding Flow Path object for the Flow Entry.
350 * @param flowEntry the Flow Entry to install.
351 * @return the added Flow Entry object on success, otherwise null.
352 */
onlab-qa38805cd2013-12-06 20:08:54 -0800353 static IFlowEntry addFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700354 IFlowPath flowObj,
355 FlowEntry flowEntry) {
356 // Flow edges
357 // HeadFE (TODO)
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800358 long startAddFlowEntry = 0;
359 long endAddFlowEntry = 0;
360
361 long endSearchFlowEntry = 0;
362
363 long startCreateNewFlowEntry = 0;
364 long endCreateNewFlowEntry = 0;
365
366 long startSetProperties = 0;
367 long endSetProperties = 0;
368 int numProperties = 0;
369
370 long startSearchSwitch = 0;
371 long endSearchSwitch = 0;
372
373 long startAddEdgeToSwitch =0;
374 long endAddEdgeToSwitch =0;
375
376 long startSearchInPort = 0;
377 long endSearchInPort = 0;
378
379 long startAddEdgeToInPort =0;
380 long endAddEdgeToInPort =0;
381
382 long startSearchOutPort = 0;
383 long endSearchOutPort = 0;
384
385 long startAddEdgeToOutPort =0;
386 long endAddEdgeToOutPort =0;
387
388 long startAddEdgeBetweenFlowPath = 0;
389 long endAddEdgeBetweenFlowPath = 0;
390
391 if (measureONOSFlowEntryTimeProp) {
392 startAddFlowEntry = System.nanoTime();
393 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700394
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700395 IFlowEntry flowEntryObj = null;
396 boolean found = false;
397 try {
Yuta HIGUCHIc27a6c92014-01-07 11:51:11 -0800398 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
399 if (measureONOSFlowEntryTimeProp) {
400 endSearchFlowEntry = System.nanoTime();
401 }
402 if (flowEntryObj != null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700403 found = true;
404 } else {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800405 if (measureONOSFlowEntryTimeProp) {
406 startCreateNewFlowEntry = System.nanoTime();
407 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700408 flowEntryObj = dbHandler.newFlowEntry();
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800409 if (measureONOSFlowEntryTimeProp) {
410 endCreateNewFlowEntry = System.nanoTime();
411 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700412 }
413 } catch (Exception e) {
414 log.error(":addFlow FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800415 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700416 return null;
417 }
418 if (flowEntryObj == null) {
419 log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800420 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700421 return null;
422 }
423
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800424 if (measureONOSFlowEntryTimeProp) {
425 startSetProperties = System.nanoTime();
426 }
Yuta HIGUCHI8685f9c2014-01-07 15:53:28 -0800427
Toshio Koide7f76e9e2014-01-09 22:06:35 -0800428 FlowEntryProperty flowProp = new FlowEntryProperty(dbHandler, flowEntryObj);
Yuta HIGUCHI8685f9c2014-01-07 15:53:28 -0800429
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700430 //
431 // Set the Flow Entry key:
432 // - flowEntry.flowEntryId()
433 //
Toshio Koide3f233542014-01-07 14:19:09 -0800434 flowProp.setFlowEntryId(flowEntry.flowEntryId().toString());
435 flowProp.setType("flow_entry");
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800436 if (measureONOSFlowEntryTimeProp) {
437 numProperties += 2;
438 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700439
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800440 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700441 // Set the Flow Entry Edges and attributes:
442 // - Switch edge
443 // - InPort edge
444 // - OutPort edge
445 //
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800446 // - flowEntry.idleTimeout()
447 // - flowEntry.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700448 // - flowEntry.dpid()
449 // - flowEntry.flowEntryUserState()
450 // - flowEntry.flowEntrySwitchState()
451 // - flowEntry.flowEntryErrorState()
452 // - flowEntry.matchInPort()
453 // - flowEntry.matchSrcMac()
454 // - flowEntry.matchDstMac()
455 // - flowEntry.matchEthernetFrameType()
456 // - flowEntry.matchVlanId()
457 // - flowEntry.matchVlanPriority()
458 // - flowEntry.matchSrcIPv4Net()
459 // - flowEntry.matchDstIPv4Net()
460 // - flowEntry.matchIpProto()
461 // - flowEntry.matchIpToS()
462 // - flowEntry.matchSrcTcpUdpPort()
463 // - flowEntry.matchDstTcpUdpPort()
464 // - flowEntry.actionOutputPort()
465 // - flowEntry.actions()
466 //
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800467 if (measureONOSFlowEntryTimeProp) {
468 startSearchSwitch = System.nanoTime();
469 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700470 ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800471 if (measureONOSFlowEntryTimeProp) {
472 endSearchSwitch = System.nanoTime();
473 }
474
Toshio Koide3f233542014-01-07 14:19:09 -0800475 flowProp.setIdleTimeout(flowEntry.idleTimeout());
476 flowProp.setHardTimeout(flowEntry.hardTimeout());
477 flowProp.setSwitchDpid(flowEntry.dpid().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800478 if (measureONOSFlowEntryTimeProp) {
479 numProperties += 3;
480 }
481
482 if (measureONOSFlowEntryTimeProp) {
483 startAddEdgeToSwitch = System.nanoTime();
484 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700485 flowEntryObj.setSwitch(sw);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800486 if (measureONOSFlowEntryTimeProp) {
487 endAddEdgeToSwitch = System.nanoTime();
488 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700489 if (flowEntry.flowEntryMatch().matchInPort()) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800490 if (measureONOSFlowEntryTimeProp) {
491 startSearchInPort = System.nanoTime();
492 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700493 IPortObject inport =
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800494 dbHandler.searchPort(flowEntry.dpid().toString(),
495 flowEntry.flowEntryMatch().inPort().value());
496 if (measureONOSFlowEntryTimeProp) {
497 endSearchInPort = System.nanoTime();
498 }
499
Toshio Koide3f233542014-01-07 14:19:09 -0800500 flowProp.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800501 if (measureONOSFlowEntryTimeProp) {
502 ++numProperties;
503 }
504
505 if (measureONOSFlowEntryTimeProp) {
506 startAddEdgeToInPort = System.nanoTime();
507 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700508 flowEntryObj.setInPort(inport);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800509 if (measureONOSFlowEntryTimeProp) {
510 endAddEdgeToInPort = System.nanoTime();
511 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700512 }
513 if (flowEntry.flowEntryMatch().matchSrcMac()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800514 flowProp.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800515 if (measureONOSFlowEntryTimeProp) {
516 ++numProperties;
517 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700518 }
519 if (flowEntry.flowEntryMatch().matchDstMac()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800520 flowProp.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800521 if (measureONOSFlowEntryTimeProp) {
522 ++numProperties;
523 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700524 }
525 if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800526 flowProp.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800527 if (measureONOSFlowEntryTimeProp) {
528 ++numProperties;
529 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700530 }
531 if (flowEntry.flowEntryMatch().matchVlanId()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800532 flowProp.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800533 if (measureONOSFlowEntryTimeProp) {
534 ++numProperties;
535 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700536 }
537 if (flowEntry.flowEntryMatch().matchVlanPriority()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800538 flowProp.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800539 if (measureONOSFlowEntryTimeProp) {
540 ++numProperties;
541 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700542 }
543 if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800544 flowProp.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800545 if (measureONOSFlowEntryTimeProp) {
546 ++numProperties;
547 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700548 }
549 if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800550 flowProp.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800551 if (measureONOSFlowEntryTimeProp) {
552 ++numProperties;
553 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700554 }
555 if (flowEntry.flowEntryMatch().matchIpProto()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800556 flowProp.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800557 if (measureONOSFlowEntryTimeProp) {
558 ++numProperties;
559 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700560 }
561 if (flowEntry.flowEntryMatch().matchIpToS()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800562 flowProp.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800563 if (measureONOSFlowEntryTimeProp) {
564 ++numProperties;
565 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700566 }
567 if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800568 flowProp.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800569 if (measureONOSFlowEntryTimeProp) {
570 ++numProperties;
571 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700572 }
573 if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800574 flowProp.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800575 if (measureONOSFlowEntryTimeProp) {
576 ++numProperties;
577 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700578 }
579
580 for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
581 if (fa.actionOutput() != null) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800582 if (measureONOSFlowEntryTimeProp) {
583 if ( startSearchOutPort != 0 ) log.error("Performance addFlowEntry(_,{},{}) -- Multiple output port action unexpected.", flowEntry.flowId(), flowEntry.flowEntryId());
584 startSearchOutPort = System.nanoTime();
585 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700586 IPortObject outport =
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800587 dbHandler.searchPort(flowEntry.dpid().toString(),
588 fa.actionOutput().port().value());
589 if (measureONOSFlowEntryTimeProp) {
590 endSearchOutPort = System.nanoTime();
591 }
592
Toshio Koide3f233542014-01-07 14:19:09 -0800593 flowProp.setActionOutputPort(fa.actionOutput().port().value());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800594 if (measureONOSFlowEntryTimeProp) {
595 ++numProperties;
596 }
597
598 if (measureONOSFlowEntryTimeProp) {
599 startAddEdgeToOutPort = System.nanoTime();
600 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700601 flowEntryObj.setOutPort(outport);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800602 if (measureONOSFlowEntryTimeProp) {
603 endAddEdgeToOutPort = System.nanoTime();
604 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700605 }
606 }
607 if (! flowEntry.flowEntryActions().isEmpty()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800608 flowProp.setActions(flowEntry.flowEntryActions().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800609 if (measureONOSFlowEntryTimeProp) {
610 ++numProperties;
611 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700612 }
613
614 // TODO: Hacks with hard-coded state names!
615 if (found)
Toshio Koide3f233542014-01-07 14:19:09 -0800616 flowProp.setUserState("FE_USER_MODIFY");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700617 else
Toshio Koide3f233542014-01-07 14:19:09 -0800618 flowProp.setUserState("FE_USER_ADD");
619 flowProp.setSwitchState(flowEntry.flowEntrySwitchState().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800620 if (measureONOSFlowEntryTimeProp) {
621 numProperties += 2;
622 }
Yuta HIGUCHI8685f9c2014-01-07 15:53:28 -0800623 flowProp.commitProperties();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700624 //
625 // TODO: Take care of the FlowEntryErrorState.
626 //
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800627 if (measureONOSFlowEntryTimeProp) {
628 endSetProperties = System.nanoTime();
629 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700630
631 // Flow Entries edges:
632 // Flow
633 // NextFE (TODO)
634 if (! found) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800635 if (measureONOSFlowEntryTimeProp) {
636 startAddEdgeBetweenFlowPath = System.nanoTime();
637 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700638 flowObj.addFlowEntry(flowEntryObj);
639 flowEntryObj.setFlow(flowObj);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800640 if (measureONOSFlowEntryTimeProp) {
641 endAddEdgeBetweenFlowPath = System.nanoTime();
642 }
643 }
644 if (measureONOSFlowEntryTimeProp) {
645 endAddFlowEntry = System.nanoTime();
646
647 log.error("Performance addFlowEntry(_,{},{}) -- "
648 + "GrandTotal: {} "
649 + "SearchExistingFE: {} "
650 + "CreateNewFE: {} "
651 + "SetProp+Edge: {} #Props: {} "
652 + "SearchSwitch: {} "
653 + "AddEdgeToSwitch: {} "
654 + "SearchInPort: {} "
655 + "AddEdgeToInPort: {} "
656 + "SearchOutPort: {} "
657 + "AddEdgeToOutPort: {} "
658 + "AddEdgeBetweenFlowPath: {} "
659 , flowEntry.flowId(), flowEntry.flowEntryId()
660 , endAddFlowEntry - startAddFlowEntry
661 , endSearchFlowEntry - startAddFlowEntry
662 , endCreateNewFlowEntry - startCreateNewFlowEntry
663 , endSetProperties - startSetProperties, numProperties
664 , endSearchSwitch - startSearchSwitch
665 , endAddEdgeToSwitch - startAddEdgeToSwitch
666 , endSearchInPort - startSearchInPort
667 , endAddEdgeToInPort - startAddEdgeToInPort
668 , endSearchOutPort - startSearchOutPort
669 , endAddEdgeToOutPort - startAddEdgeToOutPort
670 , endAddEdgeBetweenFlowPath - startAddEdgeBetweenFlowPath
671 );
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700672 }
673
674 return flowEntryObj;
675 }
676
677 /**
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700678 * Delete a flow entry from the Network MAP.
679 *
680 * @param dbHandler the Graph Database handler to use.
681 * @param flowObj the corresponding Flow Path object for the Flow Entry.
682 * @param flowEntry the Flow Entry to delete.
683 * @return true on success, otherwise false.
684 */
yoshitomob292c622013-11-23 14:35:58 -0800685 static boolean deleteFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700686 IFlowPath flowObj,
687 FlowEntry flowEntry) {
688 IFlowEntry flowEntryObj = null;
689 try {
690 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
691 } catch (Exception e) {
692 log.error(":deleteFlowEntry FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800693 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700694 return false;
695 }
696 //
697 // TODO: Don't print an error for now, because multiple controller
698 // instances might be deleting the same flow entry.
699 //
700 /*
701 if (flowEntryObj == null) {
702 log.error(":deleteFlowEntry FlowEntryId:{} failed: FlowEntry object not found",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800703 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700704 return false;
705 }
706 */
707 if (flowEntryObj == null)
708 return true;
709
710 flowObj.removeFlowEntry(flowEntryObj);
711 dbHandler.removeFlowEntry(flowEntryObj);
712 return true;
713 }
714
715 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700716 * Delete all previously added flows.
717 *
718 * @param dbHandler the Graph Database handler to use.
719 * @return true on success, otherwise false.
720 */
yoshitomob292c622013-11-23 14:35:58 -0800721 static boolean deleteAllFlows(DBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700722 List<FlowId> allFlowIds = new LinkedList<FlowId>();
723
724 // Get all Flow IDs
725 Iterable<IFlowPath> allFlowPaths = dbHandler.getAllFlowPaths();
726 for (IFlowPath flowPathObj : allFlowPaths) {
727 if (flowPathObj == null)
728 continue;
729 String flowIdStr = flowPathObj.getFlowId();
730 if (flowIdStr == null)
731 continue;
732 FlowId flowId = new FlowId(flowIdStr);
733 allFlowIds.add(flowId);
734 }
735
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800736 // Delete all flows one-by-one
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700737 for (FlowId flowId : allFlowIds) {
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800738 deleteFlow(dbHandler, flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700739 }
740
741 return true;
742 }
743
744 /**
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800745 * Delete a previously added flow.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700746 *
747 * @param dbHandler the Graph Database handler to use.
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800748 * @param flowId the Flow ID of the flow to delete.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700749 * @return true on success, otherwise false.
750 */
yoshitomob292c622013-11-23 14:35:58 -0800751 static boolean deleteFlow(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700752 IFlowPath flowObj = null;
753 try {
754 flowObj = dbHandler.searchFlowPath(flowId);
755 } catch (Exception e) {
756 // TODO: handle exceptions
757 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800758 log.error(":deleteFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700759 return false;
760 }
761 if (flowObj == null) {
762 dbHandler.commit();
763 return true; // OK: No such flow
764 }
765
766 //
767 // Remove all Flow Entries
768 //
769 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
770 for (IFlowEntry flowEntryObj : flowEntries) {
771 flowObj.removeFlowEntry(flowEntryObj);
772 dbHandler.removeFlowEntry(flowEntryObj);
773 }
774 // Remove the Flow itself
775 dbHandler.removeFlowPath(flowObj);
776 dbHandler.commit();
777
778 return true;
779 }
780
781 /**
782 * Get a previously added flow.
783 *
784 * @param dbHandler the Graph Database handler to use.
785 * @param flowId the Flow ID of the flow to get.
786 * @return the Flow Path if found, otherwise null.
787 */
yoshitomob292c622013-11-23 14:35:58 -0800788 static FlowPath getFlow(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700789 IFlowPath flowObj = null;
790 try {
791 flowObj = dbHandler.searchFlowPath(flowId);
792 } catch (Exception e) {
793 // TODO: handle exceptions
794 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800795 log.error(":getFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700796 return null;
797 }
798 if (flowObj == null) {
799 dbHandler.commit();
800 return null; // Flow not found
801 }
802
803 //
804 // Extract the Flow state
805 //
806 FlowPath flowPath = extractFlowPath(flowObj);
807 dbHandler.commit();
808
809 return flowPath;
810 }
811
812 /**
813 * Get all installed flows by all installers.
814 *
815 * @param dbHandler the Graph Database handler to use.
816 * @return the Flow Paths if found, otherwise null.
817 */
yoshitomob292c622013-11-23 14:35:58 -0800818 static ArrayList<FlowPath> getAllFlows(DBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700819 Iterable<IFlowPath> flowPathsObj = null;
820 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
821
822 try {
823 flowPathsObj = dbHandler.getAllFlowPaths();
824 } catch (Exception e) {
825 // TODO: handle exceptions
826 dbHandler.rollback();
827 log.error(":getAllFlowPaths failed");
828 return flowPaths;
829 }
830 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
831 dbHandler.commit();
832 return flowPaths; // No Flows found
833 }
834
835 for (IFlowPath flowObj : flowPathsObj) {
836 //
837 // Extract the Flow state
838 //
839 FlowPath flowPath = extractFlowPath(flowObj);
840 if (flowPath != null)
841 flowPaths.add(flowPath);
842 }
843
844 dbHandler.commit();
845
846 return flowPaths;
847 }
848
849 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700850 * Extract Flow Path State from a Titan Database Object @ref IFlowPath.
851 *
852 * @param flowObj the object to extract the Flow Path State from.
853 * @return the extracted Flow Path State.
854 */
855 private static FlowPath extractFlowPath(IFlowPath flowObj) {
856 //
857 // Extract the Flow state
858 //
Toshio Koidea9b25142014-01-10 01:15:57 -0800859 log.info("extractFlowPath: start");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700860 String flowIdStr = flowObj.getFlowId();
861 String installerIdStr = flowObj.getInstallerId();
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700862 String flowPathType = flowObj.getFlowPathType();
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700863 String flowPathUserState = flowObj.getFlowPathUserState();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700864 Long flowPathFlags = flowObj.getFlowPathFlags();
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800865 Integer idleTimeout = flowObj.getIdleTimeout();
866 Integer hardTimeout = flowObj.getHardTimeout();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700867 String srcSwitchStr = flowObj.getSrcSwitch();
868 Short srcPortShort = flowObj.getSrcPort();
869 String dstSwitchStr = flowObj.getDstSwitch();
870 Short dstPortShort = flowObj.getDstPort();
871
872 if ((flowIdStr == null) ||
873 (installerIdStr == null) ||
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700874 (flowPathType == null) ||
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700875 (flowPathUserState == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700876 (flowPathFlags == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800877 (idleTimeout == null) ||
878 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700879 (srcSwitchStr == null) ||
880 (srcPortShort == null) ||
881 (dstSwitchStr == null) ||
882 (dstPortShort == null)) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800883 // TODO: A work-around, because of some bogus database objects
884 log.error("extractFlowPath: wrong properties");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700885 return null;
886 }
887
888 FlowPath flowPath = new FlowPath();
889 flowPath.setFlowId(new FlowId(flowIdStr));
890 flowPath.setInstallerId(new CallerId(installerIdStr));
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700891 flowPath.setFlowPathType(FlowPathType.valueOf(flowPathType));
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700892 flowPath.setFlowPathUserState(FlowPathUserState.valueOf(flowPathUserState));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700893 flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800894 flowPath.setIdleTimeout(idleTimeout);
895 flowPath.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700896 flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
897 flowPath.dataPath().srcPort().setPort(new Port(srcPortShort));
898 flowPath.dataPath().dstPort().setDpid(new Dpid(dstSwitchStr));
899 flowPath.dataPath().dstPort().setPort(new Port(dstPortShort));
900 //
901 // Extract the match conditions common for all Flow Entries
902 //
903 {
904 FlowEntryMatch match = new FlowEntryMatch();
905 String matchSrcMac = flowObj.getMatchSrcMac();
906 if (matchSrcMac != null)
907 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
908 String matchDstMac = flowObj.getMatchDstMac();
909 if (matchDstMac != null)
910 match.enableDstMac(MACAddress.valueOf(matchDstMac));
911 Short matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
912 if (matchEthernetFrameType != null)
913 match.enableEthernetFrameType(matchEthernetFrameType);
914 Short matchVlanId = flowObj.getMatchVlanId();
915 if (matchVlanId != null)
916 match.enableVlanId(matchVlanId);
917 Byte matchVlanPriority = flowObj.getMatchVlanPriority();
918 if (matchVlanPriority != null)
919 match.enableVlanPriority(matchVlanPriority);
920 String matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
921 if (matchSrcIPv4Net != null)
922 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
923 String matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
924 if (matchDstIPv4Net != null)
925 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
926 Byte matchIpProto = flowObj.getMatchIpProto();
927 if (matchIpProto != null)
928 match.enableIpProto(matchIpProto);
929 Byte matchIpToS = flowObj.getMatchIpToS();
930 if (matchIpToS != null)
931 match.enableIpToS(matchIpToS);
932 Short matchSrcTcpUdpPort = flowObj.getMatchSrcTcpUdpPort();
933 if (matchSrcTcpUdpPort != null)
934 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
935 Short matchDstTcpUdpPort = flowObj.getMatchDstTcpUdpPort();
936 if (matchDstTcpUdpPort != null)
937 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
938
939 flowPath.setFlowEntryMatch(match);
940 }
941 //
942 // Extract the actions for the first Flow Entry
943 //
944 {
945 String actionsStr = flowObj.getActions();
946 if (actionsStr != null) {
947 FlowEntryActions flowEntryActions = new FlowEntryActions(actionsStr);
948 flowPath.setFlowEntryActions(flowEntryActions);
949 }
950 }
951
952 //
953 // Extract all Flow Entries
954 //
955 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
956 for (IFlowEntry flowEntryObj : flowEntries) {
957 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
958 if (flowEntry == null)
959 continue;
960 flowPath.dataPath().flowEntries().add(flowEntry);
961 }
962
Toshio Koidea9b25142014-01-10 01:15:57 -0800963 log.info("extractFlowPath: end");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700964 return flowPath;
965 }
966
967 /**
968 * Extract Flow Entry State from a Titan Database Object @ref IFlowEntry.
969 *
970 * @param flowEntryObj the object to extract the Flow Entry State from.
971 * @return the extracted Flow Entry State.
972 */
Brian O'Connora8e49802013-10-30 20:49:59 -0700973 public static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800974 log.info("extractFlowEntry: start");
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800975 IFlowPath flowObj = flowEntryObj.getFlow();
Toshio Koidea9b25142014-01-10 01:15:57 -0800976 if (flowObj == null) {
977 log.error("extractFlowEntry: no flowPath exists");
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800978 return null;
Toshio Koidea9b25142014-01-10 01:15:57 -0800979 }
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800980
981 String flowIdStr = flowObj.getFlowId();
982 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700983 String flowEntryIdStr = flowEntryObj.getFlowEntryId();
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800984 Integer idleTimeout = flowEntryObj.getIdleTimeout();
985 Integer hardTimeout = flowEntryObj.getHardTimeout();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700986 String switchDpidStr = flowEntryObj.getSwitchDpid();
987 String userState = flowEntryObj.getUserState();
988 String switchState = flowEntryObj.getSwitchState();
989
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800990 if ((flowIdStr == null) ||
991 (flowEntryIdStr == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800992 (idleTimeout == null) ||
993 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700994 (switchDpidStr == null) ||
995 (userState == null) ||
996 (switchState == null)) {
Brian O'Connora8e49802013-10-30 20:49:59 -0700997 // TODO: A work-around, because of some bogus database objects
Toshio Koidea9b25142014-01-10 01:15:57 -0800998 log.error("extractFlowEntry: wrong properties");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700999 return null;
1000 }
1001
1002 FlowEntry flowEntry = new FlowEntry();
1003 flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001004 flowEntry.setFlowId(new FlowId(flowIdStr));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001005 flowEntry.setDpid(new Dpid(switchDpidStr));
yoshia97632b2013-12-17 15:46:08 -08001006 flowEntry.setIdleTimeout(idleTimeout);
1007 flowEntry.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001008
1009 //
1010 // Extract the match conditions
1011 //
1012 FlowEntryMatch match = new FlowEntryMatch();
1013 Short matchInPort = flowEntryObj.getMatchInPort();
1014 if (matchInPort != null)
1015 match.enableInPort(new Port(matchInPort));
1016 String matchSrcMac = flowEntryObj.getMatchSrcMac();
1017 if (matchSrcMac != null)
1018 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
1019 String matchDstMac = flowEntryObj.getMatchDstMac();
1020 if (matchDstMac != null)
1021 match.enableDstMac(MACAddress.valueOf(matchDstMac));
1022 Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
1023 if (matchEthernetFrameType != null)
1024 match.enableEthernetFrameType(matchEthernetFrameType);
1025 Short matchVlanId = flowEntryObj.getMatchVlanId();
1026 if (matchVlanId != null)
1027 match.enableVlanId(matchVlanId);
1028 Byte matchVlanPriority = flowEntryObj.getMatchVlanPriority();
1029 if (matchVlanPriority != null)
1030 match.enableVlanPriority(matchVlanPriority);
1031 String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
1032 if (matchSrcIPv4Net != null)
1033 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
1034 String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
1035 if (matchDstIPv4Net != null)
1036 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
1037 Byte matchIpProto = flowEntryObj.getMatchIpProto();
1038 if (matchIpProto != null)
1039 match.enableIpProto(matchIpProto);
1040 Byte matchIpToS = flowEntryObj.getMatchIpToS();
1041 if (matchIpToS != null)
1042 match.enableIpToS(matchIpToS);
1043 Short matchSrcTcpUdpPort = flowEntryObj.getMatchSrcTcpUdpPort();
1044 if (matchSrcTcpUdpPort != null)
1045 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
1046 Short matchDstTcpUdpPort = flowEntryObj.getMatchDstTcpUdpPort();
1047 if (matchDstTcpUdpPort != null)
1048 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
1049 flowEntry.setFlowEntryMatch(match);
1050
1051 //
1052 // Extract the actions
1053 //
1054 FlowEntryActions actions = new FlowEntryActions();
1055 String actionsStr = flowEntryObj.getActions();
1056 if (actionsStr != null)
1057 actions = new FlowEntryActions(actionsStr);
1058 flowEntry.setFlowEntryActions(actions);
1059 flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
1060 flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
1061 //
1062 // TODO: Take care of FlowEntryErrorState.
1063 //
Toshio Koidea9b25142014-01-10 01:15:57 -08001064 log.info("extractFlowEntry: end");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001065 return flowEntry;
1066 }
1067}