blob: 38f164a3390c42206fb14c661db4b7be0afc9eba [file] [log] [blame]
Jonathan Hart062a2e82014-02-03 09:41:57 -08001package net.onrc.onos.ofcontroller.networkgraph;
2
Yuta HIGUCHI1c700102014-02-12 16:30:52 -08003import java.net.InetAddress;
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08004import java.nio.ByteBuffer;
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -08005import java.util.ArrayList;
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -08006import java.util.Collection;
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08007import java.util.HashMap;
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -08008import java.util.HashSet;
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -08009import java.util.LinkedList;
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -080010import java.util.List;
Pavlin Radoslavov018d5332014-02-19 23:08:35 -080011import java.util.Map;
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -080012import java.util.Set;
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080013import java.util.concurrent.BlockingQueue;
Yuta HIGUCHIa536e762014-02-17 21:47:28 -080014import java.util.concurrent.CopyOnWriteArrayList;
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080015import java.util.concurrent.LinkedBlockingQueue;
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -080016
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080017import net.onrc.onos.datagrid.IDatagridService;
18import net.onrc.onos.datagrid.IEventChannel;
19import net.onrc.onos.datagrid.IEventChannelListener;
Yuta HIGUCHI765cd0d2014-02-06 12:46:41 -080020import net.onrc.onos.datastore.topology.RCLink;
Jonathan Hart062a2e82014-02-03 09:41:57 -080021import net.onrc.onos.datastore.topology.RCPort;
22import net.onrc.onos.datastore.topology.RCSwitch;
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -080023import net.onrc.onos.ofcontroller.networkgraph.PortEvent.SwitchPort;
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080024import net.onrc.onos.ofcontroller.util.EventEntry;
Yuta HIGUCHI170229f2014-02-17 15:47:54 -080025import net.onrc.onos.registry.controller.IControllerRegistryService;
Jonathan Hart062a2e82014-02-03 09:41:57 -080026
27import org.slf4j.Logger;
28import org.slf4j.LoggerFactory;
29
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -080030/**
31 * The "NB" read-only Network Map.
32 *
Yuta HIGUCHI4bfdd532014-02-07 13:47:36 -080033 * - Maintain Invariant/Relationships between Topology Objects.
34 *
Yuta HIGUCHI765cd0d2014-02-06 12:46:41 -080035 * TODO To be synchronized based on TopologyEvent Notification.
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -080036 *
Yuta HIGUCHIcb951982014-02-11 13:31:44 -080037 * TODO TBD: Caller is expected to maintain parent/child calling order. Parent
Yuta HIGUCHI1c700102014-02-12 16:30:52 -080038 * Object must exist before adding sub component(Add Switch -> Port).
Yuta HIGUCHIcb951982014-02-11 13:31:44 -080039 *
Yuta HIGUCHI4bfdd532014-02-07 13:47:36 -080040 * TODO TBD: This class may delay the requested change to handle event
41 * re-ordering. e.g.) Link Add came in, but Switch was not there.
Yuta HIGUCHIcb951982014-02-11 13:31:44 -080042 *
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -080043 */
Pavlin Radoslavov87dcc262014-02-19 21:13:23 -080044public class TopologyManager implements NetworkGraphDiscoveryInterface {
Jonathan Hart062a2e82014-02-03 09:41:57 -080045
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080046 private static final Logger log = LoggerFactory
Pavlin Radoslavovdb7dbb22014-02-18 14:45:10 -080047 .getLogger(TopologyManager.class);
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -080048
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080049 private IEventChannel<byte[], TopologyEvent> eventChannel;
Jonathan Hart10a7e2b2014-02-21 18:30:08 -080050 public static final String EVENT_CHANNEL_NAME = "onos.topology";
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080051 private EventHandler eventHandler = new EventHandler();
52
Jonathan Hart22eb9882014-02-11 15:52:59 -080053 private final NetworkGraphDatastore datastore;
Pavlin Radoslavov6d224ee2014-02-18 16:43:15 -080054 private final NetworkGraphImpl networkGraph = new NetworkGraphImpl();
Yuta HIGUCHI170229f2014-02-17 15:47:54 -080055 private final IControllerRegistryService registryService;
Yuta HIGUCHIa536e762014-02-17 21:47:28 -080056 private CopyOnWriteArrayList<INetworkGraphListener> networkGraphListeners;
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -080057
Pavlin Radoslavov706add22014-02-20 12:15:59 -080058 //
59 // Local state for keeping track of reordered events.
60 // NOTE: Switch Events are not affected by the event reordering.
61 //
62 private Map<ByteBuffer, PortEvent> reorderedAddedPortEvents =
Pavlin Radoslavov018d5332014-02-19 23:08:35 -080063 new HashMap<ByteBuffer, PortEvent>();
Pavlin Radoslavov706add22014-02-20 12:15:59 -080064 private Map<ByteBuffer, LinkEvent> reorderedAddedLinkEvents =
Pavlin Radoslavov018d5332014-02-19 23:08:35 -080065 new HashMap<ByteBuffer, LinkEvent>();
Pavlin Radoslavov706add22014-02-20 12:15:59 -080066 private Map<ByteBuffer, DeviceEvent> reorderedAddedDeviceEvents =
Pavlin Radoslavov018d5332014-02-19 23:08:35 -080067 new HashMap<ByteBuffer, DeviceEvent>();
68
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -080069 //
Pavlin Radoslavov26d83402014-02-20 15:24:30 -080070 // Local state for keeping track of locally discovered events so we can
71 // cleanup properly when a Switch or Port is removed.
72 //
73 // We keep all Port, Link and Device events per Switch DPID:
74 // - If a switch goes down, we remove all corresponding Port, Link and
75 // Device events.
76 // - If a port on a switch goes down, we remove all corresponding Link
77 // and Device events.
78 //
79 private Map<Long, Map<ByteBuffer, PortEvent>> discoveredAddedPortEvents =
80 new HashMap<>();
81 private Map<Long, Map<ByteBuffer, LinkEvent>> discoveredAddedLinkEvents =
82 new HashMap<>();
83 private Map<Long, Map<ByteBuffer, DeviceEvent>> discoveredAddedDeviceEvents =
84 new HashMap<>();
85
86 //
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -080087 // Local state for keeping track of the application event notifications
88 //
89 List<SwitchEvent> apiAddedSwitchEvents = new LinkedList<SwitchEvent>();
90 List<SwitchEvent> apiRemovedSwitchEvents = new LinkedList<SwitchEvent>();
91 List<PortEvent> apiAddedPortEvents = new LinkedList<PortEvent>();
92 List<PortEvent> apiRemovedPortEvents = new LinkedList<PortEvent>();
93 List<LinkEvent> apiAddedLinkEvents = new LinkedList<LinkEvent>();
94 List<LinkEvent> apiRemovedLinkEvents = new LinkedList<LinkEvent>();
95 List<DeviceEvent> apiAddedDeviceEvents = new LinkedList<DeviceEvent>();
96 List<DeviceEvent> apiRemovedDeviceEvents = new LinkedList<DeviceEvent>();
97
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -080098 /**
99 * Constructor.
100 *
101 * @param registryService the Registry Service to use.
102 * @param networkGraphListeners the collection of Network Graph Listeners
103 * to use.
104 */
105 public TopologyManager(IControllerRegistryService registryService,
106 CopyOnWriteArrayList<INetworkGraphListener> networkGraphListeners) {
Jonathan Hartdaea86f2014-02-19 15:28:42 -0800107 datastore = new NetworkGraphDatastore();
Yuta HIGUCHI170229f2014-02-17 15:47:54 -0800108 this.registryService = registryService;
Yuta HIGUCHIa536e762014-02-17 21:47:28 -0800109 this.networkGraphListeners = networkGraphListeners;
Yuta HIGUCHI80829d12014-02-05 20:16:56 -0800110 }
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -0800111
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800112 /**
113 * Get the Network Graph.
114 *
115 * @return the Network Graph.
116 */
Pavlin Radoslavov6d224ee2014-02-18 16:43:15 -0800117 NetworkGraph getNetworkGraph() {
118 return networkGraph;
119 }
120
Yuta HIGUCHI4bfdd532014-02-07 13:47:36 -0800121 /**
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800122 * Event handler class.
123 */
124 private class EventHandler extends Thread implements
125 IEventChannelListener<byte[], TopologyEvent> {
126 private BlockingQueue<EventEntry<TopologyEvent>> topologyEvents =
127 new LinkedBlockingQueue<EventEntry<TopologyEvent>>();
128
129 /**
130 * Startup processing.
131 */
132 private void startup() {
133 //
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800134 // TODO: Read all state from the database:
135 //
136 // Collection<EventEntry<TopologyEvent>> collection =
137 // readWholeTopologyFromDB();
138 //
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800139 // For now, as a shortcut we read it from the datagrid
140 //
141 Collection<TopologyEvent> topologyEvents =
142 eventChannel.getAllEntries();
143 Collection<EventEntry<TopologyEvent>> collection =
144 new LinkedList<EventEntry<TopologyEvent>>();
145
146 for (TopologyEvent topologyEvent : topologyEvents) {
147 EventEntry<TopologyEvent> eventEntry =
148 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
149 topologyEvent);
150 collection.add(eventEntry);
151 }
152 processEvents(collection);
153 }
154
155 /**
156 * Run the thread.
157 */
Yuta HIGUCHI240bf072014-02-17 10:55:21 -0800158 @Override
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800159 public void run() {
160 Collection<EventEntry<TopologyEvent>> collection =
161 new LinkedList<EventEntry<TopologyEvent>>();
162
Pavlin Radoslavovdb7dbb22014-02-18 14:45:10 -0800163 this.setName("TopologyManager.EventHandler " + this.getId());
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800164 startup();
165
166 //
167 // The main loop
168 //
169 try {
170 while (true) {
171 EventEntry<TopologyEvent> eventEntry = topologyEvents.take();
172 collection.add(eventEntry);
173 topologyEvents.drainTo(collection);
174
175 processEvents(collection);
176 collection.clear();
177 }
178 } catch (Exception exception) {
179 log.debug("Exception processing Topology Events: ", exception);
180 }
181 }
182
183 /**
184 * Process all topology events.
185 *
186 * @param events the events to process.
187 */
188 private void processEvents(Collection<EventEntry<TopologyEvent>> events) {
Pavlin Radoslavov706add22014-02-20 12:15:59 -0800189 // Local state for computing the final set of events
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800190 Map<ByteBuffer, SwitchEvent> addedSwitchEvents = new HashMap<>();
191 Map<ByteBuffer, SwitchEvent> removedSwitchEvents = new HashMap<>();
192 Map<ByteBuffer, PortEvent> addedPortEvents = new HashMap<>();
193 Map<ByteBuffer, PortEvent> removedPortEvents = new HashMap<>();
194 Map<ByteBuffer, LinkEvent> addedLinkEvents = new HashMap<>();
195 Map<ByteBuffer, LinkEvent> removedLinkEvents = new HashMap<>();
196 Map<ByteBuffer, DeviceEvent> addedDeviceEvents = new HashMap<>();
197 Map<ByteBuffer, DeviceEvent> removedDeviceEvents = new HashMap<>();
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800198
199 //
200 // Classify and suppress matching events
201 //
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800202 for (EventEntry<TopologyEvent> event : events) {
203 TopologyEvent topologyEvent = event.eventData();
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800204 SwitchEvent switchEvent = topologyEvent.switchEvent;
205 PortEvent portEvent = topologyEvent.portEvent;
206 LinkEvent linkEvent = topologyEvent.linkEvent;
207 DeviceEvent deviceEvent = topologyEvent.deviceEvent;
208
209 //
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800210 // Extract the events
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800211 //
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800212 switch (event.eventType()) {
213 case ENTRY_ADD:
214 log.debug("Topology event ENTRY_ADD: {}", topologyEvent);
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800215 if (switchEvent != null) {
Yuta HIGUCHIa341b112014-02-23 15:42:00 -0800216 ByteBuffer id = switchEvent.getIDasByteBuffer();
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800217 addedSwitchEvents.put(id, switchEvent);
218 removedSwitchEvents.remove(id);
Pavlin Radoslavov706add22014-02-20 12:15:59 -0800219 // Switch Events are not affected by event reordering
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800220 }
221 if (portEvent != null) {
Yuta HIGUCHIa341b112014-02-23 15:42:00 -0800222 ByteBuffer id = portEvent.getIDasByteBuffer();
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800223 addedPortEvents.put(id, portEvent);
224 removedPortEvents.remove(id);
Pavlin Radoslavov706add22014-02-20 12:15:59 -0800225 reorderedAddedPortEvents.remove(id);
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800226 }
227 if (linkEvent != null) {
Yuta HIGUCHIa341b112014-02-23 15:42:00 -0800228 ByteBuffer id = linkEvent.getIDasByteBuffer();
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800229 addedLinkEvents.put(id, linkEvent);
230 removedLinkEvents.remove(id);
Pavlin Radoslavov706add22014-02-20 12:15:59 -0800231 reorderedAddedLinkEvents.remove(id);
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800232 }
233 if (deviceEvent != null) {
Yuta HIGUCHIa341b112014-02-23 15:42:00 -0800234 ByteBuffer id = deviceEvent.getIDasByteBuffer();
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800235 addedDeviceEvents.put(id, deviceEvent);
236 removedDeviceEvents.remove(id);
Pavlin Radoslavov706add22014-02-20 12:15:59 -0800237 reorderedAddedDeviceEvents.remove(id);
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800238 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800239 break;
240 case ENTRY_REMOVE:
241 log.debug("Topology event ENTRY_REMOVE: {}", topologyEvent);
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800242 if (switchEvent != null) {
Yuta HIGUCHIa341b112014-02-23 15:42:00 -0800243 ByteBuffer id = switchEvent.getIDasByteBuffer();
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800244 addedSwitchEvents.remove(id);
245 removedSwitchEvents.put(id, switchEvent);
Pavlin Radoslavov706add22014-02-20 12:15:59 -0800246 // Switch Events are not affected by event reordering
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800247 }
248 if (portEvent != null) {
Yuta HIGUCHIa341b112014-02-23 15:42:00 -0800249 ByteBuffer id = portEvent.getIDasByteBuffer();
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800250 addedPortEvents.remove(id);
251 removedPortEvents.put(id, portEvent);
Pavlin Radoslavov706add22014-02-20 12:15:59 -0800252 reorderedAddedPortEvents.remove(id);
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800253 }
254 if (linkEvent != null) {
Yuta HIGUCHIa341b112014-02-23 15:42:00 -0800255 ByteBuffer id = linkEvent.getIDasByteBuffer();
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800256 addedLinkEvents.remove(id);
257 removedLinkEvents.put(id, linkEvent);
Pavlin Radoslavov706add22014-02-20 12:15:59 -0800258 reorderedAddedLinkEvents.remove(id);
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800259 }
260 if (deviceEvent != null) {
Yuta HIGUCHIa341b112014-02-23 15:42:00 -0800261 ByteBuffer id = deviceEvent.getIDasByteBuffer();
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800262 addedDeviceEvents.remove(id);
263 removedDeviceEvents.put(id, deviceEvent);
Pavlin Radoslavov706add22014-02-20 12:15:59 -0800264 reorderedAddedDeviceEvents.remove(id);
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800265 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800266 break;
267 }
268 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800269
270 //
Pavlin Radoslavov8ffb8bf2014-02-20 15:34:26 -0800271 // Lock the Network Graph while it is modified
272 //
273 networkGraph.acquireWriteLock();
274
Jonathan Hart26241692014-02-20 16:31:11 -0800275 try {
276 //
277 // Apply the classified events.
278 //
279 // Apply the "add" events in the proper order:
280 // switch, port, link, device
281 //
282 for (SwitchEvent switchEvent : addedSwitchEvents.values())
283 addSwitch(switchEvent);
284 for (PortEvent portEvent : addedPortEvents.values())
285 addPort(portEvent);
286 for (LinkEvent linkEvent : addedLinkEvents.values())
287 addLink(linkEvent);
288 for (DeviceEvent deviceEvent : addedDeviceEvents.values())
289 addDevice(deviceEvent);
290 //
291 // Apply the "remove" events in the reverse order:
292 // device, link, port, switch
293 //
294 for (DeviceEvent deviceEvent : removedDeviceEvents.values())
295 removeDevice(deviceEvent);
296 for (LinkEvent linkEvent : removedLinkEvents.values())
297 removeLink(linkEvent);
298 for (PortEvent portEvent : removedPortEvents.values())
299 removePort(portEvent);
300 for (SwitchEvent switchEvent : removedSwitchEvents.values())
301 removeSwitch(switchEvent);
Yuta HIGUCHI3aca81a2014-02-23 12:41:19 -0800302
Jonathan Hart26241692014-02-20 16:31:11 -0800303 //
304 // Apply reordered events
305 //
306 applyReorderedEvents(! addedSwitchEvents.isEmpty(),
307 ! addedPortEvents.isEmpty());
Yuta HIGUCHI3aca81a2014-02-23 12:41:19 -0800308
Jonathan Hart26241692014-02-20 16:31:11 -0800309 }
310 finally {
311 //
312 // Network Graph modifications completed: Release the lock
313 //
314 networkGraph.releaseWriteLock();
315 }
Yuta HIGUCHI3aca81a2014-02-23 12:41:19 -0800316
Pavlin Radoslavov8ffb8bf2014-02-20 15:34:26 -0800317 //
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800318 // Dispatch the Topology Notification Events to the applications
319 //
320 dispatchNetworkGraphEvents();
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800321 }
322
323 /**
324 * Receive a notification that an entry is added.
325 *
326 * @param value the value for the entry.
327 */
328 @Override
329 public void entryAdded(TopologyEvent value) {
330 EventEntry<TopologyEvent> eventEntry =
331 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
332 value);
333 topologyEvents.add(eventEntry);
334 }
335
336 /**
337 * Receive a notification that an entry is removed.
338 *
339 * @param value the value for the entry.
340 */
341 @Override
342 public void entryRemoved(TopologyEvent value) {
343 EventEntry<TopologyEvent> eventEntry =
344 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_REMOVE,
345 value);
346 topologyEvents.add(eventEntry);
347 }
348
349 /**
350 * Receive a notification that an entry is updated.
351 *
352 * @param value the value for the entry.
353 */
354 @Override
355 public void entryUpdated(TopologyEvent value) {
356 // NOTE: The ADD and UPDATE events are processed in same way
357 entryAdded(value);
358 }
359 }
360
361 /**
362 * Startup processing.
363 *
364 * @param datagridService the datagrid service to use.
365 */
366 void startup(IDatagridService datagridService) {
367 eventChannel = datagridService.addListener(EVENT_CHANNEL_NAME,
368 eventHandler,
369 byte[].class,
370 TopologyEvent.class);
371 eventHandler.start();
372 }
373
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800374 /**
375 * Dispatch Network Graph Events to the listeners.
376 */
377 private void dispatchNetworkGraphEvents() {
378 if (apiAddedSwitchEvents.isEmpty() &&
379 apiRemovedSwitchEvents.isEmpty() &&
380 apiAddedPortEvents.isEmpty() &&
381 apiRemovedPortEvents.isEmpty() &&
382 apiAddedLinkEvents.isEmpty() &&
383 apiRemovedLinkEvents.isEmpty() &&
384 apiAddedDeviceEvents.isEmpty() &&
385 apiRemovedDeviceEvents.isEmpty()) {
386 return; // No events to dispatch
387 }
388
Yuta HIGUCHI3aca81a2014-02-23 12:41:19 -0800389 if (log.isDebugEnabled()) {
390 //
391 // Debug statements
392 // TODO: Those statements should be removed in the future
393 //
394 for (SwitchEvent switchEvent : apiAddedSwitchEvents)
395 log.debug("Dispatch Network Graph Event: ADDED {}", switchEvent);
396 for (SwitchEvent switchEvent : apiRemovedSwitchEvents)
397 log.debug("Dispatch Network Graph Event: REMOVED {}", switchEvent);
398 for (PortEvent portEvent : apiAddedPortEvents)
399 log.debug("Dispatch Network Graph Event: ADDED {}", portEvent);
400 for (PortEvent portEvent : apiRemovedPortEvents)
401 log.debug("Dispatch Network Graph Event: REMOVED {}", portEvent);
402 for (LinkEvent linkEvent : apiAddedLinkEvents)
403 log.debug("Dispatch Network Graph Event: ADDED {}", linkEvent);
404 for (LinkEvent linkEvent : apiRemovedLinkEvents)
405 log.debug("Dispatch Network Graph Event: REMOVED {}", linkEvent);
406 for (DeviceEvent deviceEvent : apiAddedDeviceEvents)
407 log.debug("Dispatch Network Graph Event: ADDED {}", deviceEvent);
408 for (DeviceEvent deviceEvent : apiRemovedDeviceEvents)
409 log.debug("Dispatch Network Graph Event: REMOVED {}", deviceEvent);
410 }
adminbc181552014-02-21 18:36:42 -0800411
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800412 // Deliver the events
413 for (INetworkGraphListener listener : this.networkGraphListeners) {
414 // TODO: Should copy before handing them over to listener?
415 listener.networkGraphEvents(apiAddedSwitchEvents,
416 apiRemovedSwitchEvents,
417 apiAddedPortEvents,
418 apiRemovedPortEvents,
419 apiAddedLinkEvents,
420 apiRemovedLinkEvents,
421 apiAddedDeviceEvents,
422 apiRemovedDeviceEvents);
423 }
424
425 //
426 // Cleanup
427 //
428 apiAddedSwitchEvents.clear();
429 apiRemovedSwitchEvents.clear();
430 apiAddedPortEvents.clear();
431 apiRemovedPortEvents.clear();
432 apiAddedLinkEvents.clear();
433 apiRemovedLinkEvents.clear();
434 apiAddedDeviceEvents.clear();
435 apiRemovedDeviceEvents.clear();
436 }
437
438 /**
439 * Apply reordered events.
440 *
441 * @param hasAddedSwitchEvents true if there were Added Switch Events.
442 * @param hasAddedPortEvents true if there were Added Port Events.
443 */
444 private void applyReorderedEvents(boolean hasAddedSwitchEvents,
445 boolean hasAddedPortEvents) {
446 if (! (hasAddedSwitchEvents || hasAddedPortEvents))
447 return; // Nothing to do
448
449 //
450 // Try to apply the reordered events.
451 //
452 // NOTE: For simplicity we try to apply all events of a particular
453 // type if any "parent" type event was processed:
454 // - Apply reordered Port Events if Switches were added
455 // - Apply reordered Link and Device Events if Switches or Ports
456 // were added
457 //
adminbc181552014-02-21 18:36:42 -0800458
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800459 //
460 // Apply reordered Port Events if Switches were added
461 //
462 if (hasAddedSwitchEvents) {
adminbc181552014-02-21 18:36:42 -0800463 Map<ByteBuffer, PortEvent> portEvents = reorderedAddedPortEvents;
464 reorderedAddedPortEvents = new HashMap<>();
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800465 for (PortEvent portEvent : portEvents.values())
466 addPort(portEvent);
467 }
468 //
469 // Apply reordered Link and Device Events if Switches or Ports
470 // were added.
471 //
adminbc181552014-02-21 18:36:42 -0800472 Map<ByteBuffer, LinkEvent> linkEvents = reorderedAddedLinkEvents;
473 reorderedAddedLinkEvents = new HashMap<>();
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800474 for (LinkEvent linkEvent : linkEvents.values())
475 addLink(linkEvent);
adminbc181552014-02-21 18:36:42 -0800476 //
477 Map<ByteBuffer, DeviceEvent> deviceEvents = reorderedAddedDeviceEvents;
478 reorderedAddedDeviceEvents = new HashMap<>();
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800479 for (DeviceEvent deviceEvent : deviceEvents.values())
480 addDevice(deviceEvent);
481 }
482
Jonathan Hart22eb9882014-02-11 15:52:59 -0800483 /* ******************************
484 * NetworkGraphDiscoveryInterface methods
485 * ******************************/
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -0800486
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800487 @Override
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800488 public void putSwitchDiscoveryEvent(SwitchEvent switchEvent,
489 Collection<PortEvent> portEvents) {
490 if (datastore.addSwitch(switchEvent, portEvents)) {
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800491 // Send out notification
Pavlin Radoslavov87dcc262014-02-19 21:13:23 -0800492 TopologyEvent topologyEvent = new TopologyEvent(switchEvent);
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800493 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800494
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800495 // Send out notification for each port
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800496 for (PortEvent portEvent : portEvents) {
497 topologyEvent = new TopologyEvent(portEvent);
498 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
499 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800500
501 //
502 // Keep track of the added ports
503 //
504 // Get the old Port Events
505 Map<ByteBuffer, PortEvent> oldPortEvents =
506 discoveredAddedPortEvents.get(switchEvent.getDpid());
507 if (oldPortEvents == null)
508 oldPortEvents = new HashMap<>();
509
510 // Store the new Port Events in the local cache
511 Map<ByteBuffer, PortEvent> newPortEvents = new HashMap<>();
512 for (PortEvent portEvent : portEvents) {
Yuta HIGUCHIa341b112014-02-23 15:42:00 -0800513 ByteBuffer id = portEvent.getIDasByteBuffer();
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800514 newPortEvents.put(id, portEvent);
515 }
516 discoveredAddedPortEvents.put(switchEvent.getDpid(),
517 newPortEvents);
518
519 //
520 // Extract the removed ports
521 //
522 List<PortEvent> removedPortEvents = new LinkedList<>();
523 for (Map.Entry<ByteBuffer, PortEvent> entry : oldPortEvents.entrySet()) {
524 ByteBuffer key = entry.getKey();
525 PortEvent portEvent = entry.getValue();
526 if (! newPortEvents.containsKey(key))
527 removedPortEvents.add(portEvent);
528 }
529
530 // Cleanup old removed ports
531 for (PortEvent portEvent : removedPortEvents)
532 removePortDiscoveryEvent(portEvent);
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800533 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800534 }
535
536 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800537 public void removeSwitchDiscoveryEvent(SwitchEvent switchEvent) {
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800538 // Get the old Port Events
539 Map<ByteBuffer, PortEvent> oldPortEvents =
540 discoveredAddedPortEvents.get(switchEvent.getDpid());
541 if (oldPortEvents == null)
542 oldPortEvents = new HashMap<>();
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800543
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800544 if (datastore.deactivateSwitch(switchEvent, oldPortEvents.values())) {
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800545 // Send out notification
546 eventChannel.removeEntry(switchEvent.getID());
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800547
Pavlin Radoslavov6f870a12014-02-24 14:25:54 -0800548 //
549 // Send out notification for each port.
550 //
551 // NOTE: We don't use removePortDiscoveryEvent() for the cleanup,
552 // because it will attempt to remove the port from the database,
553 // and the deactiveSwitch() call above already removed all ports.
554 //
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800555 for (PortEvent portEvent : oldPortEvents.values())
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800556 eventChannel.removeEntry(portEvent.getID());
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800557 discoveredAddedPortEvents.remove(switchEvent.getDpid());
558
559 // Cleanup for each link
560 Map<ByteBuffer, LinkEvent> oldLinkEvents =
561 discoveredAddedLinkEvents.get(switchEvent.getDpid());
562 if (oldLinkEvents != null) {
Yuta HIGUCHI95b20352014-02-24 12:06:27 -0800563 for (LinkEvent linkEvent : new ArrayList<>(oldLinkEvents.values())) {
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800564 removeLinkDiscoveryEvent(linkEvent);
Yuta HIGUCHI95b20352014-02-24 12:06:27 -0800565 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800566 discoveredAddedLinkEvents.remove(switchEvent.getDpid());
567 }
568
569 // Cleanup for each device
570 Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
571 discoveredAddedDeviceEvents.get(switchEvent.getDpid());
572 if (oldDeviceEvents != null) {
Yuta HIGUCHI95b20352014-02-24 12:06:27 -0800573 for (DeviceEvent deviceEvent : new ArrayList<>(oldDeviceEvents.values())) {
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800574 removeDeviceDiscoveryEvent(deviceEvent);
Yuta HIGUCHI95b20352014-02-24 12:06:27 -0800575 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800576 discoveredAddedDeviceEvents.remove(switchEvent.getDpid());
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800577 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800578 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800579 }
580
581 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800582 public void putPortDiscoveryEvent(PortEvent portEvent) {
Pavlin Radoslavov50cd1482014-02-19 16:57:03 -0800583 if (datastore.addPort(portEvent)) {
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800584 // Send out notification
Pavlin Radoslavov87dcc262014-02-19 21:13:23 -0800585 TopologyEvent topologyEvent = new TopologyEvent(portEvent);
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800586 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800587
588 // Store the new Port Event in the local cache
589 Map<ByteBuffer, PortEvent> oldPortEvents =
590 discoveredAddedPortEvents.get(portEvent.getDpid());
591 if (oldPortEvents == null) {
592 oldPortEvents = new HashMap<>();
593 discoveredAddedPortEvents.put(portEvent.getDpid(),
594 oldPortEvents);
595 }
Yuta HIGUCHIa341b112014-02-23 15:42:00 -0800596 ByteBuffer id = portEvent.getIDasByteBuffer();
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800597 oldPortEvents.put(id, portEvent);
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800598 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800599 }
600
601 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800602 public void removePortDiscoveryEvent(PortEvent portEvent) {
Pavlin Radoslavov50cd1482014-02-19 16:57:03 -0800603 if (datastore.deactivatePort(portEvent)) {
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800604 // Send out notification
605 eventChannel.removeEntry(portEvent.getID());
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800606
607 // Cleanup the Port Event from the local cache
608 Map<ByteBuffer, PortEvent> oldPortEvents =
609 discoveredAddedPortEvents.get(portEvent.getDpid());
610 if (oldPortEvents != null) {
Yuta HIGUCHIa341b112014-02-23 15:42:00 -0800611 ByteBuffer id = portEvent.getIDasByteBuffer();
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800612 oldPortEvents.remove(id);
613 }
614
615 // Cleanup for the incoming link
616 Map<ByteBuffer, LinkEvent> oldLinkEvents =
617 discoveredAddedLinkEvents.get(portEvent.getDpid());
618 if (oldLinkEvents != null) {
Pavlin Radoslavov6f870a12014-02-24 14:25:54 -0800619 for (LinkEvent linkEvent : new ArrayList<>(oldLinkEvents.values())) {
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800620 if (linkEvent.getDst().equals(portEvent.id)) {
621 removeLinkDiscoveryEvent(linkEvent);
Yuta HIGUCHI95b20352014-02-24 12:06:27 -0800622 // XXX If we change our model to allow multiple Link on
623 // a Port, this loop must be fixed to allow continuing.
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800624 break;
625 }
626 }
627 }
628
629 // Cleanup for the connected devices
630 // TODO: The implementation below is probably wrong
631 List<DeviceEvent> removedDeviceEvents = new LinkedList<>();
632 Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
633 discoveredAddedDeviceEvents.get(portEvent.getDpid());
634 if (oldDeviceEvents != null) {
Yuta HIGUCHI95b20352014-02-24 12:06:27 -0800635 for (DeviceEvent deviceEvent : new ArrayList<>(oldDeviceEvents.values())) {
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800636 for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
637 if (swp.equals(portEvent.id)) {
638 removedDeviceEvents.add(deviceEvent);
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800639 }
640 }
641 }
642 for (DeviceEvent deviceEvent : removedDeviceEvents)
643 removeDeviceDiscoveryEvent(deviceEvent);
644 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800645 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800646 }
647
648 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800649 public void putLinkDiscoveryEvent(LinkEvent linkEvent) {
Pavlin Radoslavov50cd1482014-02-19 16:57:03 -0800650 if (datastore.addLink(linkEvent)) {
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800651 // Send out notification
Pavlin Radoslavov87dcc262014-02-19 21:13:23 -0800652 TopologyEvent topologyEvent = new TopologyEvent(linkEvent);
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800653 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800654
655 // Store the new Link Event in the local cache
656 Map<ByteBuffer, LinkEvent> oldLinkEvents =
657 discoveredAddedLinkEvents.get(linkEvent.getDst().getDpid());
658 if (oldLinkEvents == null) {
659 oldLinkEvents = new HashMap<>();
660 discoveredAddedLinkEvents.put(linkEvent.getDst().getDpid(),
661 oldLinkEvents);
662 }
Yuta HIGUCHIa341b112014-02-23 15:42:00 -0800663 ByteBuffer id = linkEvent.getIDasByteBuffer();
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800664 oldLinkEvents.put(id, linkEvent);
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800665 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800666 }
667
668 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800669 public void removeLinkDiscoveryEvent(LinkEvent linkEvent) {
Pavlin Radoslavov50cd1482014-02-19 16:57:03 -0800670 if (datastore.removeLink(linkEvent)) {
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800671 // Send out notification
672 eventChannel.removeEntry(linkEvent.getID());
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800673
674 // Cleanup the Link Event from the local cache
675 Map<ByteBuffer, LinkEvent> oldLinkEvents =
676 discoveredAddedLinkEvents.get(linkEvent.getDst().getDpid());
677 if (oldLinkEvents != null) {
Yuta HIGUCHIa341b112014-02-23 15:42:00 -0800678 ByteBuffer id = linkEvent.getIDasByteBuffer();
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800679 oldLinkEvents.remove(id);
680 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800681 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800682 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800683
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800684 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800685 public void putDeviceDiscoveryEvent(DeviceEvent deviceEvent) {
Pavlin Radoslavov50cd1482014-02-19 16:57:03 -0800686 if (datastore.addDevice(deviceEvent)) {
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800687 // Send out notification
Pavlin Radoslavov87dcc262014-02-19 21:13:23 -0800688 TopologyEvent topologyEvent = new TopologyEvent(deviceEvent);
Pavlin Radoslavov50cd1482014-02-19 16:57:03 -0800689 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800690
691 // Store the new Device Event in the local cache
692 // TODO: The implementation below is probably wrong
693 for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
694 Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
695 discoveredAddedDeviceEvents.get(swp.getDpid());
696 if (oldDeviceEvents == null) {
697 oldDeviceEvents = new HashMap<>();
698 discoveredAddedDeviceEvents.put(swp.getDpid(),
699 oldDeviceEvents);
700 }
Yuta HIGUCHIa341b112014-02-23 15:42:00 -0800701 ByteBuffer id = deviceEvent.getIDasByteBuffer();
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800702 oldDeviceEvents.put(id, deviceEvent);
703 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800704 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800705 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800706
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800707 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800708 public void removeDeviceDiscoveryEvent(DeviceEvent deviceEvent) {
Pavlin Radoslavov50cd1482014-02-19 16:57:03 -0800709 if (datastore.removeDevice(deviceEvent)) {
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800710 // Send out notification
711 eventChannel.removeEntry(deviceEvent.getID());
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800712
713 // Cleanup the Device Event from the local cache
714 // TODO: The implementation below is probably wrong
715 ByteBuffer id = ByteBuffer.wrap(deviceEvent.getID());
716 for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
717 Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
718 discoveredAddedDeviceEvents.get(swp.getDpid());
719 if (oldDeviceEvents != null) {
720 oldDeviceEvents.remove(id);
721 }
722 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800723 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800724 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800725
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800726 /* ************************************************
727 * Internal methods to maintain the network graph
728 * ************************************************/
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800729 private void addSwitch(SwitchEvent switchEvent) {
730 Switch sw = networkGraph.getSwitch(switchEvent.getDpid());
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800731 if (sw == null) {
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800732 sw = new SwitchImpl(networkGraph, switchEvent.getDpid());
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800733 networkGraph.putSwitch(sw);
734 } else {
735 // TODO: Update the switch attributes
736 // TODO: Nothing to do for now
737 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800738 apiAddedSwitchEvents.add(switchEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800739 }
740
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800741 private void removeSwitch(SwitchEvent switchEvent) {
742 Switch sw = networkGraph.getSwitch(switchEvent.getDpid());
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800743 if (sw == null) {
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800744 log.warn("Switch {} already removed, ignoring", switchEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800745 return;
746 }
747
748 //
749 // Remove all Ports on the Switch
750 //
751 ArrayList<PortEvent> portsToRemove = new ArrayList<>();
752 for (Port port : sw.getPorts()) {
753 log.warn("Port {} on Switch {} should be removed prior to removing Switch. Removing Port now.",
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800754 port, switchEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800755 PortEvent portEvent = new PortEvent(port.getDpid(),
756 port.getNumber());
757 portsToRemove.add(portEvent);
758 }
759 for (PortEvent portEvent : portsToRemove)
760 removePort(portEvent);
761
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800762 networkGraph.removeSwitch(switchEvent.getDpid());
763 apiRemovedSwitchEvents.add(switchEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800764 }
765
766 private void addPort(PortEvent portEvent) {
767 Switch sw = networkGraph.getSwitch(portEvent.getDpid());
768 if (sw == null) {
Pavlin Radoslavov706add22014-02-20 12:15:59 -0800769 // Reordered event: delay the event in local cache
Yuta HIGUCHIa341b112014-02-23 15:42:00 -0800770 ByteBuffer id = portEvent.getIDasByteBuffer();
Pavlin Radoslavov706add22014-02-20 12:15:59 -0800771 reorderedAddedPortEvents.put(id, portEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800772 return;
773 }
774 SwitchImpl switchImpl = getSwitchImpl(sw);
775
776 Port port = sw.getPort(portEvent.getNumber());
777 if (port == null) {
778 port = new PortImpl(networkGraph, sw, portEvent.getNumber());
779 switchImpl.addPort(port);
780 } else {
781 // TODO: Update the port attributes
782 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800783 apiAddedPortEvents.add(portEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800784 }
785
786 private void removePort(PortEvent portEvent) {
787 Switch sw = networkGraph.getSwitch(portEvent.getDpid());
788 if (sw == null) {
789 log.warn("Parent Switch for Port {} already removed, ignoring",
790 portEvent);
791 return;
792 }
793
794 Port port = sw.getPort(portEvent.getNumber());
795 if (port == null) {
796 log.warn("Port {} already removed, ignoring", portEvent);
797 return;
798 }
799
800 //
801 // Remove all Devices attached to the Port
802 //
803 ArrayList<DeviceEvent> devicesToRemove = new ArrayList<>();
804 for (Device device : port.getDevices()) {
805 log.debug("Removing Device {} on Port {}", device, portEvent);
806 DeviceEvent deviceEvent = new DeviceEvent(device.getMacAddress());
807 SwitchPort switchPort = new SwitchPort(port.getSwitch().getDpid(),
808 port.getNumber());
809 deviceEvent.addAttachmentPoint(switchPort);
810 devicesToRemove.add(deviceEvent);
811 }
812 for (DeviceEvent deviceEvent : devicesToRemove)
813 removeDevice(deviceEvent);
814
815 //
816 // Remove all Links connected to the Port
817 //
818 Set<Link> links = new HashSet<>();
819 links.add(port.getOutgoingLink());
820 links.add(port.getIncomingLink());
821 ArrayList<LinkEvent> linksToRemove = new ArrayList<>();
822 for (Link link : links) {
823 if (link == null)
824 continue;
825 log.debug("Removing Link {} on Port {}", link, portEvent);
826 LinkEvent linkEvent = new LinkEvent(link.getSrcSwitch().getDpid(),
827 link.getSrcPort().getNumber(),
828 link.getDstSwitch().getDpid(),
829 link.getDstPort().getNumber());
830 linksToRemove.add(linkEvent);
831 }
832 for (LinkEvent linkEvent : linksToRemove)
833 removeLink(linkEvent);
834
835 // Remove the Port from the Switch
836 SwitchImpl switchImpl = getSwitchImpl(sw);
837 switchImpl.removePort(port);
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800838
839 apiRemovedPortEvents.add(portEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800840 }
841
842 private void addLink(LinkEvent linkEvent) {
843 Port srcPort = networkGraph.getPort(linkEvent.getSrc().dpid,
844 linkEvent.getSrc().number);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800845 Port dstPort = networkGraph.getPort(linkEvent.getDst().dpid,
846 linkEvent.getDst().number);
Pavlin Radoslavov706add22014-02-20 12:15:59 -0800847 if ((srcPort == null) || (dstPort == null)) {
848 // Reordered event: delay the event in local cache
Yuta HIGUCHIa341b112014-02-23 15:42:00 -0800849 ByteBuffer id = linkEvent.getIDasByteBuffer();
Pavlin Radoslavov706add22014-02-20 12:15:59 -0800850 reorderedAddedLinkEvents.put(id, linkEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800851 return;
852 }
853
854 // Get the Link instance from the Destination Port Incoming Link
855 Link link = dstPort.getIncomingLink();
856 assert(link == srcPort.getOutgoingLink());
857 if (link == null) {
858 link = new LinkImpl(networkGraph, srcPort, dstPort);
859 PortImpl srcPortImpl = getPortImpl(srcPort);
860 PortImpl dstPortImpl = getPortImpl(dstPort);
861 srcPortImpl.setOutgoingLink(link);
862 dstPortImpl.setIncomingLink(link);
863
864 // Remove all Devices attached to the Ports
865 ArrayList<DeviceEvent> devicesToRemove = new ArrayList<>();
866 ArrayList<Port> ports = new ArrayList<>();
867 ports.add(srcPort);
868 ports.add(dstPort);
869 for (Port port : ports) {
870 for (Device device : port.getDevices()) {
871 log.error("Device {} on Port {} should have been removed prior to adding Link {}",
872 device, port, linkEvent);
873 DeviceEvent deviceEvent =
874 new DeviceEvent(device.getMacAddress());
875 SwitchPort switchPort =
876 new SwitchPort(port.getSwitch().getDpid(),
877 port.getNumber());
878 deviceEvent.addAttachmentPoint(switchPort);
879 devicesToRemove.add(deviceEvent);
880 }
881 }
882 for (DeviceEvent deviceEvent : devicesToRemove)
883 removeDevice(deviceEvent);
884 } else {
885 // TODO: Update the link attributes
886 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800887
888 apiAddedLinkEvents.add(linkEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800889 }
890
891 private void removeLink(LinkEvent linkEvent) {
892 Port srcPort = networkGraph.getPort(linkEvent.getSrc().dpid,
893 linkEvent.getSrc().number);
894 if (srcPort == null) {
895 log.warn("Src Port for Link {} already removed, ignoring",
896 linkEvent);
897 return;
898 }
899
900 Port dstPort = networkGraph.getPort(linkEvent.getDst().dpid,
901 linkEvent.getDst().number);
902 if (dstPort == null) {
903 log.warn("Dst Port for Link {} already removed, ignoring",
904 linkEvent);
905 return;
906 }
907
908 //
909 // Remove the Link instance from the Destination Port Incoming Link
910 // and the Source Port Outgoing Link.
911 //
912 Link link = dstPort.getIncomingLink();
913 if (link == null) {
914 log.warn("Link {} already removed on destination Port", linkEvent);
915 }
916 link = srcPort.getOutgoingLink();
917 if (link == null) {
918 log.warn("Link {} already removed on src Port", linkEvent);
919 }
920 getPortImpl(dstPort).setIncomingLink(null);
921 getPortImpl(srcPort).setOutgoingLink(null);
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800922
923 apiRemovedLinkEvents.add(linkEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800924 }
925
926 // TODO: Device-related work is incomplete
927 private void addDevice(DeviceEvent deviceEvent) {
928 Device device = networkGraph.getDeviceByMac(deviceEvent.getMac());
929 if (device == null) {
930 device = new DeviceImpl(networkGraph, deviceEvent.getMac());
931 }
932 DeviceImpl deviceImpl = getDeviceImpl(device);
933
934 // Update the IP addresses
935 for (InetAddress ipAddr : deviceEvent.getIpAddresses())
936 deviceImpl.addIpAddress(ipAddr);
937
938 // Process each attachment point
939 boolean attachmentFound = false;
940 for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
941 // Attached Ports must exist
942 Port port = networkGraph.getPort(swp.dpid, swp.number);
943 if (port == null) {
Pavlin Radoslavov706add22014-02-20 12:15:59 -0800944 // Reordered event: delay the event in local cache
Yuta HIGUCHIa341b112014-02-23 15:42:00 -0800945 ByteBuffer id = deviceEvent.getIDasByteBuffer();
Pavlin Radoslavov706add22014-02-20 12:15:59 -0800946 reorderedAddedDeviceEvents.put(id, deviceEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800947 continue;
948 }
949 // Attached Ports must not have Link
950 if (port.getOutgoingLink() != null ||
951 port.getIncomingLink() != null) {
952 log.warn("Link (Out:{},In:{}) exist on the attachment point, skipping mutation.",
953 port.getOutgoingLink(),
954 port.getIncomingLink());
955 continue;
956 }
957
958 // Add Device <-> Port attachment
959 PortImpl portImpl = getPortImpl(port);
960 portImpl.addDevice(device);
961 deviceImpl.addAttachmentPoint(port);
962 attachmentFound = true;
963 }
964
965 // Update the device in the Network Graph
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800966 if (attachmentFound) {
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800967 networkGraph.putDevice(device);
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800968 apiAddedDeviceEvents.add(deviceEvent);
969 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800970 }
971
972 private void removeDevice(DeviceEvent deviceEvent) {
973 Device device = networkGraph.getDeviceByMac(deviceEvent.getMac());
974 if (device == null) {
975 log.warn("Device {} already removed, ignoring", deviceEvent);
976 return;
977 }
978 DeviceImpl deviceImpl = getDeviceImpl(device);
979
980 // Process each attachment point
981 for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
982 // Attached Ports must exist
983 Port port = networkGraph.getPort(swp.dpid, swp.number);
984 if (port == null) {
985 log.warn("Port for the attachment point {} did not exist. skipping attachment point mutation", swp);
986 continue;
987 }
988
989 // Remove Device <-> Port attachment
990 PortImpl portImpl = getPortImpl(port);
991 portImpl.removeDevice(device);
992 deviceImpl.removeAttachmentPoint(port);
993 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800994
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800995 networkGraph.removeDevice(device);
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800996 apiRemovedDeviceEvents.add(deviceEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800997 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800998
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800999 /**
1000 *
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -08001001 * @param switchEvent
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001002 * @return true if ready to accept event.
1003 */
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -08001004 private boolean prepareForAddSwitchEvent(SwitchEvent switchEvent) {
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001005 // No show stopping precondition
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001006 return true;
1007 }
Jonathan Hart22eb9882014-02-11 15:52:59 -08001008
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -08001009 private boolean prepareForRemoveSwitchEvent(SwitchEvent switchEvent) {
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001010 // No show stopping precondition
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001011 return true;
1012 }
Yuta HIGUCHI71e7a052014-02-17 22:14:15 -08001013
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001014 private boolean prepareForAddPortEvent(PortEvent portEvent) {
1015 // Parent Switch must exist
1016 if (networkGraph.getSwitch(portEvent.getDpid()) == null) {
1017 log.warn("Dropping add port event because switch doesn't exist: {}",
1018 portEvent);
1019 return false;
1020 }
1021 // Prep: None
1022 return true;
1023 }
1024
1025 private boolean prepareForRemovePortEvent(PortEvent portEvent) {
1026 Port port = networkGraph.getPort(portEvent.getDpid(),
1027 portEvent.getNumber());
1028 if (port == null) {
1029 log.debug("Port already removed? {}", portEvent);
1030 // let it pass
1031 return true;
Jonathan Hart22eb9882014-02-11 15:52:59 -08001032 }
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -08001033
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001034 // Prep: Remove Link and Device Attachment
1035 ArrayList<DeviceEvent> deviceEvents = new ArrayList<>();
1036 for (Device device : port.getDevices()) {
1037 log.debug("Removing Device {} on Port {}", device, portEvent);
1038 DeviceEvent devEvent = new DeviceEvent(device.getMacAddress());
1039 devEvent.addAttachmentPoint(new SwitchPort(port.getSwitch().getDpid(),
1040 port.getNumber()));
1041 deviceEvents.add(devEvent);
1042 }
1043 for (DeviceEvent devEvent : deviceEvents) {
1044 // calling Discovery API to wipe from DB, etc.
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -08001045 removeDeviceDiscoveryEvent(devEvent);
Jonathan Hart22eb9882014-02-11 15:52:59 -08001046 }
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -08001047
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001048 Set<Link> links = new HashSet<>();
1049 links.add(port.getOutgoingLink());
1050 links.add(port.getIncomingLink());
1051 for (Link link : links) {
1052 if (link == null) {
1053 continue;
1054 }
1055 log.debug("Removing Link {} on Port {}", link, portEvent);
1056 LinkEvent linkEvent =
Pavlin Radoslavov7c8f69a2014-02-19 19:01:45 -08001057 new LinkEvent(link.getSrcSwitch().getDpid(),
1058 link.getSrcPort().getNumber(),
1059 link.getDstSwitch().getDpid(),
1060 link.getDstPort().getNumber());
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001061 // calling Discovery API to wipe from DB, etc.
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -08001062
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001063 // Call internal remove Link, which will check
1064 // ownership of DST dpid and modify DB only if it is the owner
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -08001065 removeLinkDiscoveryEvent(linkEvent, true);
Jonathan Hart22eb9882014-02-11 15:52:59 -08001066 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001067 return true;
1068 }
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -08001069
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001070 private boolean prepareForAddLinkEvent(LinkEvent linkEvent) {
1071 // Src/Dst Port must exist
1072 Port srcPort = networkGraph.getPort(linkEvent.getSrc().dpid,
1073 linkEvent.getSrc().number);
1074 Port dstPort = networkGraph.getPort(linkEvent.getDst().dpid,
1075 linkEvent.getDst().number);
1076 if (srcPort == null || dstPort == null) {
Jonathan Hart0a4846e2014-02-18 11:03:40 -08001077 log.warn("Dropping add link event because port doesn't exist: {}",
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001078 linkEvent);
1079 return false;
Jonathan Hart22eb9882014-02-11 15:52:59 -08001080 }
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -08001081
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001082 // Prep: remove Device attachment on both Ports
1083 ArrayList<DeviceEvent> deviceEvents = new ArrayList<>();
1084 for (Device device : srcPort.getDevices()) {
1085 DeviceEvent devEvent = new DeviceEvent(device.getMacAddress());
1086 devEvent.addAttachmentPoint(new SwitchPort(srcPort.getSwitch().getDpid(), srcPort.getNumber()));
1087 deviceEvents.add(devEvent);
1088 }
1089 for (Device device : dstPort.getDevices()) {
1090 DeviceEvent devEvent = new DeviceEvent(device.getMacAddress());
1091 devEvent.addAttachmentPoint(new SwitchPort(dstPort.getSwitch().getDpid(),
1092 dstPort.getNumber()));
1093 deviceEvents.add(devEvent);
1094 }
1095 for (DeviceEvent devEvent : deviceEvents) {
1096 // calling Discovery API to wipe from DB, etc.
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -08001097 removeDeviceDiscoveryEvent(devEvent);
Jonathan Hart22eb9882014-02-11 15:52:59 -08001098 }
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -08001099
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001100 return true;
1101 }
Yuta HIGUCHId02e9282014-02-12 09:24:41 -08001102
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001103 private boolean prepareForRemoveLinkEvent(LinkEvent linkEvent) {
1104 // Src/Dst Port must exist
1105 Port srcPort = networkGraph.getPort(linkEvent.getSrc().dpid,
1106 linkEvent.getSrc().number);
1107 Port dstPort = networkGraph.getPort(linkEvent.getDst().dpid,
1108 linkEvent.getDst().number);
1109 if (srcPort == null || dstPort == null) {
1110 log.warn("Dropping remove link event because port doesn't exist {}", linkEvent);
1111 return false;
1112 }
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -08001113
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001114 Link link = srcPort.getOutgoingLink();
1115
1116 // Link is already gone, or different Link exist in memory
1117 // XXX Check if we should reject or just accept these cases.
1118 // it should be harmless to remove the Link on event from DB anyways
1119 if (link == null ||
Pavlin Radoslavov7c8f69a2014-02-19 19:01:45 -08001120 !link.getDstPort().getNumber().equals(linkEvent.getDst().number)
1121 || !link.getDstSwitch().getDpid().equals(linkEvent.getDst().dpid)) {
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001122 log.warn("Dropping remove link event because link doesn't exist: {}", linkEvent);
1123 return false;
1124 }
1125 // Prep: None
1126 return true;
1127 }
1128
1129 /**
1130 *
1131 * @param deviceEvent Event will be modified to remove inapplicable attachemntPoints/ipAddress
1132 * @return false if this event should be dropped.
1133 */
1134 private boolean prepareForAddDeviceEvent(DeviceEvent deviceEvent) {
1135 boolean preconditionBroken = false;
1136 ArrayList<PortEvent.SwitchPort> failedSwitchPort = new ArrayList<>();
1137 for ( PortEvent.SwitchPort swp : deviceEvent.getAttachmentPoints() ) {
1138 // Attached Ports must exist
1139 Port port = networkGraph.getPort(swp.dpid, swp.number);
1140 if (port == null) {
1141 preconditionBroken = true;
1142 failedSwitchPort.add(swp);
1143 continue;
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -08001144 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001145 // Attached Ports must not have Link
1146 if (port.getOutgoingLink() != null ||
1147 port.getIncomingLink() != null) {
1148 preconditionBroken = true;
1149 failedSwitchPort.add(swp);
1150 continue;
1151 }
1152 }
1153
1154 // Rewriting event to exclude failed attachmentPoint
1155 // XXX Assumption behind this is that inapplicable device event should
1156 // be dropped, not deferred. If we decide to defer Device event,
1157 // rewriting can become a problem
1158 List<SwitchPort> attachmentPoints = deviceEvent.getAttachmentPoints();
1159 attachmentPoints.removeAll(failedSwitchPort);
1160 deviceEvent.setAttachmentPoints(attachmentPoints);
1161
1162 if (deviceEvent.getAttachmentPoints().isEmpty() &&
1163 deviceEvent.getIpAddresses().isEmpty()) {
1164 // return false to represent: Nothing left to do for this event.
1165 // Caller should drop event
1166 return false;
1167 }
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -08001168
1169 // Should we return false to tell caller that the event was trimmed?
1170 // if ( preconditionBroken ) {
1171 // return false;
1172 // }
1173
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001174 return true;
1175 }
1176
1177 private boolean prepareForRemoveDeviceEvent(DeviceEvent deviceEvent) {
1178 // No show stopping precondition?
1179 // Prep: none
1180 return true;
1181 }
1182
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001183 private SwitchImpl getSwitchImpl(Switch sw) {
1184 if (sw instanceof SwitchImpl) {
1185 return (SwitchImpl) sw;
1186 }
1187 throw new ClassCastException("SwitchImpl expected, but found: " + sw);
1188 }
1189
1190 private PortImpl getPortImpl(Port p) {
1191 if (p instanceof PortImpl) {
1192 return (PortImpl) p;
1193 }
1194 throw new ClassCastException("PortImpl expected, but found: " + p);
1195 }
1196
1197 private LinkImpl getLinkImpl(Link l) {
1198 if (l instanceof LinkImpl) {
1199 return (LinkImpl) l;
1200 }
1201 throw new ClassCastException("LinkImpl expected, but found: " + l);
1202 }
1203
1204 private DeviceImpl getDeviceImpl(Device d) {
1205 if (d instanceof DeviceImpl) {
1206 return (DeviceImpl) d;
1207 }
1208 throw new ClassCastException("DeviceImpl expected, but found: " + d);
1209 }
1210
1211 @Deprecated
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001212 private Collection<EventEntry<TopologyEvent>> readWholeTopologyFromDB() {
1213 Collection<EventEntry<TopologyEvent>> collection =
1214 new LinkedList<EventEntry<TopologyEvent>>();
1215
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001216 // XXX May need to clear whole topology first, depending on
1217 // how we initially subscribe to replication events
1218
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001219 // Add all active switches
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001220 for (RCSwitch sw : RCSwitch.getAllSwitches()) {
1221 if (sw.getStatus() != RCSwitch.STATUS.ACTIVE) {
1222 continue;
1223 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001224
1225 SwitchEvent switchEvent = new SwitchEvent(sw.getDpid());
1226 TopologyEvent topologyEvent = new TopologyEvent(switchEvent);
1227 EventEntry<TopologyEvent> eventEntry =
1228 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
1229 topologyEvent);
1230 collection.add(eventEntry);
Yuta HIGUCHIa536e762014-02-17 21:47:28 -08001231 }
1232
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001233 // Add all active ports
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001234 for (RCPort p : RCPort.getAllPorts()) {
1235 if (p.getStatus() != RCPort.STATUS.ACTIVE) {
1236 continue;
Yuta HIGUCHIa536e762014-02-17 21:47:28 -08001237 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001238
1239 PortEvent portEvent = new PortEvent(p.getDpid(), p.getNumber());
1240 TopologyEvent topologyEvent = new TopologyEvent(portEvent);
1241 EventEntry<TopologyEvent> eventEntry =
1242 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
1243 topologyEvent);
1244 collection.add(eventEntry);
Yuta HIGUCHIa536e762014-02-17 21:47:28 -08001245 }
1246
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001247 // TODO Is Device going to be in DB? If so, read from DB.
1248 // for (RCDevice d : RCDevice.getAllDevices()) {
1249 // DeviceEvent devEvent = new DeviceEvent( MACAddress.valueOf(d.getMac()) );
1250 // for (byte[] portId : d.getAllPortIds() ) {
1251 // devEvent.addAttachmentPoint( new SwitchPort( RCPort.getDpidFromKey(portId), RCPort.getNumberFromKey(portId) ));
1252 // }
1253 // }
1254
1255 for (RCLink l : RCLink.getAllLinks()) {
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001256 LinkEvent linkEvent = new LinkEvent(l.getSrc().dpid,
1257 l.getSrc().number,
1258 l.getDst().dpid,
1259 l.getDst().number);
1260 TopologyEvent topologyEvent = new TopologyEvent(linkEvent);
1261 EventEntry<TopologyEvent> eventEntry =
1262 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
1263 topologyEvent);
1264 collection.add(eventEntry);
Yuta HIGUCHI76df2472014-02-12 22:36:51 -08001265 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001266
1267 return collection;
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001268 }
Pavlin Radoslavov50cd1482014-02-19 16:57:03 -08001269
1270 @Deprecated
1271 private void removeLinkDiscoveryEvent(LinkEvent linkEvent,
1272 boolean dstCheckBeforeDBmodify) {
1273 if (prepareForRemoveLinkEvent(linkEvent)) {
1274 if (dstCheckBeforeDBmodify) {
1275 // write to DB only if it is owner of the dst dpid
1276 // XXX this will cause link remove events to be dropped
1277 // if the dst switch just disconnected
1278 if (registryService.hasControl(linkEvent.getDst().dpid)) {
1279 datastore.removeLink(linkEvent);
1280 }
1281 } else {
1282 datastore.removeLink(linkEvent);
1283 }
1284 removeLink(linkEvent);
1285 // Send out notification
1286 eventChannel.removeEntry(linkEvent.getID());
1287 }
1288 // TODO handle invariant violation
1289 }
Jonathan Hart062a2e82014-02-03 09:41:57 -08001290}