blob: 08f57ed19b7191222a8408aab10385430e5b4277 [file] [log] [blame]
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -07001package net.onrc.onos.ofcontroller.flowmanager;
2
Pavlin Radoslavovfb06a9e2013-10-28 23:56:15 -07003import java.util.ArrayList;
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -07004import java.util.Collection;
Pavlin Radoslavovfb06a9e2013-10-28 23:56:15 -07005import java.util.HashMap;
6import java.util.Iterator;
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -07007import java.util.LinkedList;
8import java.util.List;
Pavlin Radoslavovfb06a9e2013-10-28 23:56:15 -07009import java.util.Map;
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -070010
11import java.util.concurrent.BlockingQueue;
12import java.util.concurrent.LinkedBlockingQueue;
13
14import net.onrc.onos.datagrid.IDatagridService;
Pavlin Radoslavovfb06a9e2013-10-28 23:56:15 -070015import net.onrc.onos.ofcontroller.topology.ShortestPath;
Pavlin Radoslavova23e5412013-10-27 19:56:40 -070016import net.onrc.onos.ofcontroller.topology.Topology;
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -070017import net.onrc.onos.ofcontroller.topology.TopologyElement;
Pavlin Radoslavov3ecd41e2013-10-29 14:29:30 -070018import net.onrc.onos.ofcontroller.topology.TopologyManager;
Pavlin Radoslavovfb06a9e2013-10-28 23:56:15 -070019import net.onrc.onos.ofcontroller.util.DataPath;
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -070020import net.onrc.onos.ofcontroller.util.EventEntry;
Pavlin Radoslavovfb06a9e2013-10-28 23:56:15 -070021import net.onrc.onos.ofcontroller.util.FlowEntry;
22import net.onrc.onos.ofcontroller.util.FlowEntryAction;
23import net.onrc.onos.ofcontroller.util.FlowEntryActions;
24import net.onrc.onos.ofcontroller.util.FlowEntryMatch;
25import net.onrc.onos.ofcontroller.util.FlowEntrySwitchState;
26import net.onrc.onos.ofcontroller.util.FlowEntryUserState;
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -070027import net.onrc.onos.ofcontroller.util.FlowPath;
Pavlin Radoslavovfb06a9e2013-10-28 23:56:15 -070028import net.onrc.onos.ofcontroller.util.FlowPathUserState;
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -070029
30import org.slf4j.Logger;
31import org.slf4j.LoggerFactory;
32
33/**
34 * Class for implementing the Path Computation and Path Maintenance.
35 */
Pavlin Radoslavov9a859022013-10-30 10:08:24 -070036class FlowEventHandler extends Thread implements IFlowEventHandlerService {
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -070037 /** The logger. */
Pavlin Radoslavov9a859022013-10-30 10:08:24 -070038 private final static Logger log = LoggerFactory.getLogger(FlowEventHandler.class);
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -070039
40 private FlowManager flowManager; // The Flow Manager to use
41 private IDatagridService datagridService; // The Datagrid Service to use
Pavlin Radoslavova23e5412013-10-27 19:56:40 -070042 private Topology topology; // The network topology
Pavlin Radoslavovfb06a9e2013-10-28 23:56:15 -070043 private Map<Long, FlowPath> allFlowPaths = new HashMap<Long, FlowPath>();
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -070044
45 // The queue with Flow Path and Topology Element updates
46 private BlockingQueue<EventEntry<?>> networkEvents =
47 new LinkedBlockingQueue<EventEntry<?>>();
48
Pavlin Radoslavovb7506842013-10-29 17:46:54 -070049 // The pending Topology, FlowPath, and FlowEntry events
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -070050 private List<EventEntry<TopologyElement>> topologyEvents =
51 new LinkedList<EventEntry<TopologyElement>>();
52 private List<EventEntry<FlowPath>> flowPathEvents =
53 new LinkedList<EventEntry<FlowPath>>();
Pavlin Radoslavovb7506842013-10-29 17:46:54 -070054 private List<EventEntry<FlowEntry>> flowEntryEvents =
55 new LinkedList<EventEntry<FlowEntry>>();
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -070056
57 /**
58 * Constructor for a given Flow Manager and Datagrid Service.
59 *
60 * @param flowManager the Flow Manager to use.
61 * @param datagridService the Datagrid Service to use.
62 */
Pavlin Radoslavov9a859022013-10-30 10:08:24 -070063 FlowEventHandler(FlowManager flowManager,
64 IDatagridService datagridService) {
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -070065 this.flowManager = flowManager;
66 this.datagridService = datagridService;
Pavlin Radoslavova23e5412013-10-27 19:56:40 -070067 this.topology = new Topology();
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -070068 }
69
70 /**
71 * Run the thread.
72 */
73 @Override
74 public void run() {
75 //
76 // Obtain the initial Topology state
77 //
78 Collection<TopologyElement> topologyElements =
79 datagridService.getAllTopologyElements();
80 for (TopologyElement topologyElement : topologyElements) {
81 EventEntry<TopologyElement> eventEntry =
82 new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_ADD, topologyElement);
83 topologyEvents.add(eventEntry);
84 }
85 //
86 // Obtain the initial Flow Path state
87 //
88 Collection<FlowPath> flowPaths = datagridService.getAllFlows();
89 for (FlowPath flowPath : flowPaths) {
90 EventEntry<FlowPath> eventEntry =
91 new EventEntry<FlowPath>(EventEntry.Type.ENTRY_ADD, flowPath);
92 flowPathEvents.add(eventEntry);
93 }
Pavlin Radoslavovb7506842013-10-29 17:46:54 -070094 //
95 // Obtain the initial FlowEntry state
96 //
97 Collection<FlowEntry> flowEntries = datagridService.getAllFlowEntries();
98 for (FlowEntry flowEntry : flowEntries) {
99 EventEntry<FlowEntry> eventEntry =
100 new EventEntry<FlowEntry>(EventEntry.Type.ENTRY_ADD, flowEntry);
101 flowEntryEvents.add(eventEntry);
102 }
103
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -0700104 // Process the events (if any)
105 processEvents();
106
107 //
108 // The main loop
109 //
110 Collection<EventEntry<?>> collection = new LinkedList<EventEntry<?>>();
111 try {
112 while (true) {
113 EventEntry<?> eventEntry = networkEvents.take();
114 collection.add(eventEntry);
115 networkEvents.drainTo(collection);
116
Pavlin Radoslavoved4c7a92013-10-26 21:36:21 -0700117 //
118 // Demultiplex all events:
119 // - EventEntry<TopologyElement>
120 // - EventEntry<FlowPath>
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700121 // - EventEntry<FlowEntry>
Pavlin Radoslavoved4c7a92013-10-26 21:36:21 -0700122 //
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -0700123 for (EventEntry<?> event : collection) {
124 if (event.eventData() instanceof TopologyElement) {
125 EventEntry<TopologyElement> topologyEventEntry =
126 (EventEntry<TopologyElement>)event;
127 topologyEvents.add(topologyEventEntry);
128 } else if (event.eventData() instanceof FlowPath) {
129 EventEntry<FlowPath> flowPathEventEntry =
130 (EventEntry<FlowPath>)event;
131 flowPathEvents.add(flowPathEventEntry);
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700132 } else if (event.eventData() instanceof FlowEntry) {
133 EventEntry<FlowEntry> flowEntryEventEntry =
134 (EventEntry<FlowEntry>)event;
135 flowEntryEvents.add(flowEntryEventEntry);
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -0700136 }
137 }
138 collection.clear();
Pavlin Radoslavoved4c7a92013-10-26 21:36:21 -0700139
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -0700140 // Process the events (if any)
141 processEvents();
142 }
143 } catch (Exception exception) {
144 log.debug("Exception processing Network Events: ", exception);
145 }
146 }
147
148 /**
149 * Process the events (if any)
150 */
151 private void processEvents() {
Pavlin Radoslavovfb06a9e2013-10-28 23:56:15 -0700152 List<FlowPath> newFlowPaths = new LinkedList<FlowPath>();
153 List<FlowPath> recomputeFlowPaths = new LinkedList<FlowPath>();
154 List<FlowPath> modifiedFlowPaths = new LinkedList<FlowPath>();
155
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700156 // TODO: For now we don't use/process the FlowEntry events
157 flowEntryEvents.clear();
158
159 if (topologyEvents.isEmpty() && flowPathEvents.isEmpty() &&
160 flowEntryEvents.isEmpty()) {
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -0700161 return; // Nothing to do
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700162 }
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -0700163
Pavlin Radoslavova23e5412013-10-27 19:56:40 -0700164 //
Pavlin Radoslavovfb06a9e2013-10-28 23:56:15 -0700165 // Process the Flow Path events
166 //
167 for (EventEntry<FlowPath> eventEntry : flowPathEvents) {
168 FlowPath flowPath = eventEntry.eventData();
169
170 switch (eventEntry.eventType()) {
171 case ENTRY_ADD: {
172 //
173 // Add a new Flow Path
174 //
175 if (allFlowPaths.get(flowPath.flowId().value()) != null) {
176 //
177 // TODO: What to do if the Flow Path already exists?
178 // Remove and then re-add it, or merge the info?
179 // For now, we don't have to do anything.
180 //
181 break;
182 }
183
184 switch (flowPath.flowPathType()) {
185 case FP_TYPE_SHORTEST_PATH:
186 //
187 // Reset the Data Path, in case it was set already, because
188 // we are going to recompute it anyway.
189 //
190 flowPath.flowEntries().clear();
191 recomputeFlowPaths.add(flowPath);
192 break;
193 case FP_TYPE_EXPLICIT_PATH:
194 //
195 // Mark all Flow Entries for installation in the switches.
196 //
197 for (FlowEntry flowEntry : flowPath.flowEntries()) {
198 flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.FE_SWITCH_NOT_UPDATED);
199 }
200 modifiedFlowPaths.add(flowPath);
201 break;
202 }
203 newFlowPaths.add(flowPath);
204
205 break;
206 }
207
208 case ENTRY_REMOVE: {
209 //
210 // Remove an existing Flow Path.
211 //
212 // Find the Flow Path, and mark the Flow and its Flow Entries
213 // for deletion.
214 //
215 FlowPath existingFlowPath =
216 allFlowPaths.get(flowPath.flowId().value());
217 if (existingFlowPath == null)
218 continue; // Nothing to do
219
220 existingFlowPath.setFlowPathUserState(FlowPathUserState.FP_USER_DELETE);
221 for (FlowEntry flowEntry : existingFlowPath.flowEntries()) {
222 flowEntry.setFlowEntryUserState(FlowEntryUserState.FE_USER_DELETE);
223 flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.FE_SWITCH_NOT_UPDATED);
224 }
225
226 allFlowPaths.remove(existingFlowPath.flowId());
227 modifiedFlowPaths.add(existingFlowPath);
228
229 break;
230 }
231 }
232 }
233
234 //
235 // Process the topology events
Pavlin Radoslavova23e5412013-10-27 19:56:40 -0700236 //
237 boolean isTopologyModified = false;
238 for (EventEntry<TopologyElement> eventEntry : topologyEvents) {
239 TopologyElement topologyElement = eventEntry.eventData();
240 switch (eventEntry.eventType()) {
241 case ENTRY_ADD:
242 isTopologyModified = topology.addTopologyElement(topologyElement);
243 break;
244 case ENTRY_REMOVE:
245 isTopologyModified = topology.removeTopologyElement(topologyElement);
246 break;
247 }
248 }
Pavlin Radoslavovfb06a9e2013-10-28 23:56:15 -0700249 if (isTopologyModified) {
250 // TODO: For now, if the topology changes, we recompute all Flows
251 recomputeFlowPaths.addAll(allFlowPaths.values());
252 }
Pavlin Radoslavova23e5412013-10-27 19:56:40 -0700253
Pavlin Radoslavovfb06a9e2013-10-28 23:56:15 -0700254 // Add all new Flows
255 for (FlowPath flowPath : newFlowPaths) {
256 allFlowPaths.put(flowPath.flowId().value(), flowPath);
257 }
258
259 // Recompute all affected Flow Paths and keep only the modified
260 for (FlowPath flowPath : recomputeFlowPaths) {
261 if (recomputeFlowPath(flowPath))
262 modifiedFlowPaths.add(flowPath);
263 }
264
Pavlin Radoslavov3ecd41e2013-10-29 14:29:30 -0700265 //
266 // Push the Flow Entries that have been modified
267 //
Pavlin Radoslavovebc8b192013-10-29 15:35:35 -0700268 flowManager.pushModifiedFlowEntries(modifiedFlowPaths);
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -0700269
Pavlin Radoslavoved4c7a92013-10-26 21:36:21 -0700270 // Cleanup
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -0700271 topologyEvents.clear();
272 flowPathEvents.clear();
273 }
274
275 /**
Pavlin Radoslavovfb06a9e2013-10-28 23:56:15 -0700276 * Recompute a Flow Path.
277 *
278 * @param flowPath the Flow Path to recompute.
279 * @return true if the recomputed Flow Path has changed, otherwise false.
280 */
281 private boolean recomputeFlowPath(FlowPath flowPath) {
282 boolean hasChanged = false;
283
284 //
285 // Test whether the Flow Path needs to be recomputed
286 //
287 switch (flowPath.flowPathType()) {
288 case FP_TYPE_SHORTEST_PATH:
289 break;
290 case FP_TYPE_EXPLICIT_PATH:
291 return false; // An explicit path never changes
292 }
293
294 DataPath oldDataPath = flowPath.dataPath();
295
Pavlin Radoslavov3ecd41e2013-10-29 14:29:30 -0700296 // Compute the new path
297 DataPath newDataPath = TopologyManager.computeNetworkPath(topology,
298 flowPath);
Pavlin Radoslavovfb06a9e2013-10-28 23:56:15 -0700299 if (newDataPath == null) {
300 // We need the DataPath to compare the paths
301 newDataPath = new DataPath();
302 }
303 newDataPath.applyFlowPathFlags(flowPath.flowPathFlags());
304
305 //
Pavlin Radoslavov3ecd41e2013-10-29 14:29:30 -0700306 // Test whether the new path is same
Pavlin Radoslavovfb06a9e2013-10-28 23:56:15 -0700307 //
308 if (oldDataPath.flowEntries().size() !=
309 newDataPath.flowEntries().size()) {
310 hasChanged = true;
311 } else {
312 Iterator<FlowEntry> oldIter = oldDataPath.flowEntries().iterator();
313 Iterator<FlowEntry> newIter = newDataPath.flowEntries().iterator();
314 while (oldIter.hasNext() && newIter.hasNext()) {
315 FlowEntry oldFlowEntry = oldIter.next();
316 FlowEntry newFlowEntry = newIter.next();
Pavlin Radoslavov3ecd41e2013-10-29 14:29:30 -0700317 if (! TopologyManager.isSameFlowEntryDataPath(oldFlowEntry,
318 newFlowEntry)) {
Pavlin Radoslavovfb06a9e2013-10-28 23:56:15 -0700319 hasChanged = true;
320 break;
321 }
322 }
323 }
324 if (! hasChanged)
325 return hasChanged;
326
327 //
Pavlin Radoslavov3ecd41e2013-10-29 14:29:30 -0700328 // Merge the changes in the path:
Pavlin Radoslavovfb06a9e2013-10-28 23:56:15 -0700329 // - If a Flow Entry for a switch is in the old data path, but not
330 // in the new data path, then mark it for deletion.
331 // - If a Flow Entry for a switch is in the new data path, but not
332 // in the old data path, then mark it for addition.
333 // - If a Flow Entry for a switch is in both the old and the new
334 // data path, but it has changed, e.g., the incoming and/or outgoing
335 // port(s), then mark the old Flow Entry for deletion, and mark
336 // the new Flow Entry for addition.
337 // - If a Flow Entry for a switch is in both the old and the new
338 // data path, and it hasn't changed, then just keep it.
339 //
340 // NOTE: We use the Switch DPID of each entry to match the entries
341 //
342 Map<Long, FlowEntry> oldFlowEntriesMap = new HashMap<Long, FlowEntry>();
343 Map<Long, FlowEntry> newFlowEntriesMap = new HashMap<Long, FlowEntry>();
344 ArrayList<FlowEntry> finalFlowEntries = new ArrayList<FlowEntry>();
345 List<FlowEntry> deletedFlowEntries = new LinkedList<FlowEntry>();
346
347 // Prepare maps with the Flow Entries, so they are fast to lookup
348 for (FlowEntry flowEntry : oldDataPath.flowEntries())
349 oldFlowEntriesMap.put(flowEntry.dpid().value(), flowEntry);
350 for (FlowEntry flowEntry : newDataPath.flowEntries())
351 newFlowEntriesMap.put(flowEntry.dpid().value(), flowEntry);
352
353 //
354 // Find the old Flow Entries that should be deleted
355 //
356 for (FlowEntry oldFlowEntry : oldDataPath.flowEntries()) {
357 FlowEntry newFlowEntry =
358 newFlowEntriesMap.get(oldFlowEntry.dpid().value());
359 if (newFlowEntry == null) {
360 // The old Flow Entry should be deleted
361 oldFlowEntry.setFlowEntryUserState(FlowEntryUserState.FE_USER_DELETE);
362 oldFlowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.FE_SWITCH_NOT_UPDATED);
363 deletedFlowEntries.add(oldFlowEntry);
364 }
365 }
366
367 //
368 // Find the new Flow Entries that should be added or updated
369 //
370 int idx = 0;
371 for (FlowEntry newFlowEntry : newDataPath.flowEntries()) {
372 FlowEntry oldFlowEntry =
373 oldFlowEntriesMap.get(newFlowEntry.dpid().value());
374
375 if ((oldFlowEntry != null) &&
Pavlin Radoslavov3ecd41e2013-10-29 14:29:30 -0700376 TopologyManager.isSameFlowEntryDataPath(oldFlowEntry,
377 newFlowEntry)) {
Pavlin Radoslavovfb06a9e2013-10-28 23:56:15 -0700378 //
379 // Both Flow Entries are same
380 //
381 finalFlowEntries.add(oldFlowEntry);
382 idx++;
383 continue;
384 }
385
386 if (oldFlowEntry != null) {
387 //
388 // The old Flow Entry should be deleted
389 //
390 oldFlowEntry.setFlowEntryUserState(FlowEntryUserState.FE_USER_DELETE);
391 oldFlowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.FE_SWITCH_NOT_UPDATED);
392 deletedFlowEntries.add(oldFlowEntry);
393 }
394
395 //
396 // Add the new Flow Entry
397 //
398
399 // Set the incoming port matching
400 FlowEntryMatch flowEntryMatch = new FlowEntryMatch();
401 newFlowEntry.setFlowEntryMatch(flowEntryMatch);
402 flowEntryMatch.enableInPort(newFlowEntry.inPort());
403
404 //
405 // Set the actions:
406 // If the first Flow Entry, copy the Flow Path actions to it.
407 //
408 FlowEntryActions flowEntryActions = newFlowEntry.flowEntryActions();
409 if ((idx == 0) && (flowPath.flowEntryActions() != null)) {
410 FlowEntryActions flowActions =
411 new FlowEntryActions(flowPath.flowEntryActions());
412 for (FlowEntryAction action : flowActions.actions())
413 flowEntryActions.addAction(action);
414 }
415 idx++;
416
417 //
418 // Add the outgoing port output action
419 //
420 FlowEntryAction flowEntryAction = new FlowEntryAction();
421 flowEntryAction.setActionOutput(newFlowEntry.outPort());
422 flowEntryActions.addAction(flowEntryAction);
423
424 //
425 // Set the state of the new Flow Entry
426 //
427 newFlowEntry.setFlowEntryUserState(FlowEntryUserState.FE_USER_ADD);
428 newFlowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.FE_SWITCH_NOT_UPDATED);
429 finalFlowEntries.add(newFlowEntry);
430 }
431
432 //
433 // Replace the old Flow Entries with the new Flow Entries.
434 // Note that the Flow Entries that will be deleted are added at
435 // the end.
436 //
437 for (FlowEntry flowEntry : deletedFlowEntries)
438 finalFlowEntries.add(flowEntry);
439 flowPath.dataPath().setFlowEntries(finalFlowEntries);
440
441 return hasChanged;
442 }
443
444 /**
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -0700445 * Receive a notification that a Flow is added.
446 *
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700447 * @param flowPath the Flow that is added.
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -0700448 */
449 @Override
450 public void notificationRecvFlowAdded(FlowPath flowPath) {
451 EventEntry<FlowPath> eventEntry =
452 new EventEntry<FlowPath>(EventEntry.Type.ENTRY_ADD, flowPath);
453 networkEvents.add(eventEntry);
454 }
455
456 /**
457 * Receive a notification that a Flow is removed.
458 *
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700459 * @param flowPath the Flow that is removed.
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -0700460 */
461 @Override
462 public void notificationRecvFlowRemoved(FlowPath flowPath) {
463 EventEntry<FlowPath> eventEntry =
464 new EventEntry<FlowPath>(EventEntry.Type.ENTRY_REMOVE, flowPath);
465 networkEvents.add(eventEntry);
466 }
467
468 /**
469 * Receive a notification that a Flow is updated.
470 *
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700471 * @param flowPath the Flow that is updated.
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -0700472 */
473 @Override
474 public void notificationRecvFlowUpdated(FlowPath flowPath) {
475 // NOTE: The ADD and UPDATE events are processed in same way
476 EventEntry<FlowPath> eventEntry =
477 new EventEntry<FlowPath>(EventEntry.Type.ENTRY_ADD, flowPath);
478 networkEvents.add(eventEntry);
479 }
480
481 /**
Pavlin Radoslavovb7506842013-10-29 17:46:54 -0700482 * Receive a notification that a FlowEntry is added.
483 *
484 * @param flowEntry the FlowEntry that is added.
485 */
486 @Override
487 public void notificationRecvFlowEntryAdded(FlowEntry flowEntry) {
488 EventEntry<FlowEntry> eventEntry =
489 new EventEntry<FlowEntry>(EventEntry.Type.ENTRY_ADD, flowEntry);
490 networkEvents.add(eventEntry);
491 }
492
493 /**
494 * Receive a notification that a FlowEntry is removed.
495 *
496 * @param flowEntry the FlowEntry that is removed.
497 */
498 @Override
499 public void notificationRecvFlowEntryRemoved(FlowEntry flowEntry) {
500 EventEntry<FlowEntry> eventEntry =
501 new EventEntry<FlowEntry>(EventEntry.Type.ENTRY_REMOVE, flowEntry);
502 networkEvents.add(eventEntry);
503 }
504
505 /**
506 * Receive a notification that a FlowEntry is updated.
507 *
508 * @param flowEntry the FlowEntry that is updated.
509 */
510 @Override
511 public void notificationRecvFlowEntryUpdated(FlowEntry flowEntry) {
512 // NOTE: The ADD and UPDATE events are processed in same way
513 EventEntry<FlowEntry> eventEntry =
514 new EventEntry<FlowEntry>(EventEntry.Type.ENTRY_ADD, flowEntry);
515 networkEvents.add(eventEntry);
516 }
517
518 /**
Pavlin Radoslavov6b79f2b2013-10-26 21:31:10 -0700519 * Receive a notification that a Topology Element is added.
520 *
521 * @param topologyElement the Topology Element that is added.
522 */
523 @Override
524 public void notificationRecvTopologyElementAdded(TopologyElement topologyElement) {
525 EventEntry<TopologyElement> eventEntry =
526 new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_ADD, topologyElement);
527 networkEvents.add(eventEntry);
528 }
529
530 /**
531 * Receive a notification that a Topology Element is removed.
532 *
533 * @param topologyElement the Topology Element that is removed.
534 */
535 @Override
536 public void notificationRecvTopologyElementRemoved(TopologyElement topologyElement) {
537 EventEntry<TopologyElement> eventEntry =
538 new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_REMOVE, topologyElement);
539 networkEvents.add(eventEntry);
540 }
541
542 /**
543 * Receive a notification that a Topology Element is updated.
544 *
545 * @param topologyElement the Topology Element that is updated.
546 */
547 @Override
548 public void notificationRecvTopologyElementUpdated(TopologyElement topologyElement) {
549 // NOTE: The ADD and UPDATE events are processed in same way
550 EventEntry<TopologyElement> eventEntry =
551 new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_ADD, topologyElement);
552 networkEvents.add(eventEntry);
553 }
554}