blob: 467c6ff240e38fda14d245555a9de12069f51c69 [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 HIGUCHI765cd0d2014-02-06 12:46:41 -080025import net.onrc.onos.ofcontroller.util.Dpid;
Yuta HIGUCHI170229f2014-02-17 15:47:54 -080026import net.onrc.onos.registry.controller.IControllerRegistryService;
Jonathan Hart062a2e82014-02-03 09:41:57 -080027
28import org.slf4j.Logger;
29import org.slf4j.LoggerFactory;
30
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -080031/**
32 * The "NB" read-only Network Map.
33 *
Yuta HIGUCHI4bfdd532014-02-07 13:47:36 -080034 * - Maintain Invariant/Relationships between Topology Objects.
35 *
Yuta HIGUCHI765cd0d2014-02-06 12:46:41 -080036 * TODO To be synchronized based on TopologyEvent Notification.
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -080037 *
Yuta HIGUCHIcb951982014-02-11 13:31:44 -080038 * TODO TBD: Caller is expected to maintain parent/child calling order. Parent
Yuta HIGUCHI1c700102014-02-12 16:30:52 -080039 * Object must exist before adding sub component(Add Switch -> Port).
Yuta HIGUCHIcb951982014-02-11 13:31:44 -080040 *
Yuta HIGUCHI4bfdd532014-02-07 13:47:36 -080041 * TODO TBD: This class may delay the requested change to handle event
42 * re-ordering. e.g.) Link Add came in, but Switch was not there.
Yuta HIGUCHIcb951982014-02-11 13:31:44 -080043 *
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -080044 */
Pavlin Radoslavov87dcc262014-02-19 21:13:23 -080045public class TopologyManager implements NetworkGraphDiscoveryInterface {
Jonathan Hart062a2e82014-02-03 09:41:57 -080046
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080047 private static final Logger log = LoggerFactory
Pavlin Radoslavovdb7dbb22014-02-18 14:45:10 -080048 .getLogger(TopologyManager.class);
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -080049
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080050 private IEventChannel<byte[], TopologyEvent> eventChannel;
51 private static final String EVENT_CHANNEL_NAME = "onos.topology";
52 private EventHandler eventHandler = new EventHandler();
53
Jonathan Hart22eb9882014-02-11 15:52:59 -080054 private final NetworkGraphDatastore datastore;
Pavlin Radoslavov6d224ee2014-02-18 16:43:15 -080055 private final NetworkGraphImpl networkGraph = new NetworkGraphImpl();
Yuta HIGUCHI170229f2014-02-17 15:47:54 -080056 private final IControllerRegistryService registryService;
Yuta HIGUCHIa536e762014-02-17 21:47:28 -080057 private CopyOnWriteArrayList<INetworkGraphListener> networkGraphListeners;
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -080058
Pavlin Radoslavov018d5332014-02-19 23:08:35 -080059 // Local state for computing the final set of events
60 private Map<ByteBuffer, SwitchEvent> addedSwitchEvents =
61 new HashMap<ByteBuffer, SwitchEvent>();
62 private Map<ByteBuffer, SwitchEvent> removedSwitchEvents =
63 new HashMap<ByteBuffer, SwitchEvent>();
64 private Map<ByteBuffer, PortEvent> addedPortEvents =
65 new HashMap<ByteBuffer, PortEvent>();
66 private Map<ByteBuffer, PortEvent> removedPortEvents =
67 new HashMap<ByteBuffer, PortEvent>();
68 private Map<ByteBuffer, LinkEvent> addedLinkEvents =
69 new HashMap<ByteBuffer, LinkEvent>();
70 private Map<ByteBuffer, LinkEvent> removedLinkEvents =
71 new HashMap<ByteBuffer, LinkEvent>();
72 private Map<ByteBuffer, DeviceEvent> addedDeviceEvents =
73 new HashMap<ByteBuffer, DeviceEvent>();
74 private Map<ByteBuffer, DeviceEvent> removedDeviceEvents =
75 new HashMap<ByteBuffer, DeviceEvent>();
76
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -080077 /**
78 * Constructor.
79 *
80 * @param registryService the Registry Service to use.
81 * @param networkGraphListeners the collection of Network Graph Listeners
82 * to use.
83 */
84 public TopologyManager(IControllerRegistryService registryService,
85 CopyOnWriteArrayList<INetworkGraphListener> networkGraphListeners) {
Jonathan Hartdaea86f2014-02-19 15:28:42 -080086 datastore = new NetworkGraphDatastore();
Yuta HIGUCHI170229f2014-02-17 15:47:54 -080087 this.registryService = registryService;
Yuta HIGUCHIa536e762014-02-17 21:47:28 -080088 this.networkGraphListeners = networkGraphListeners;
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080089 }
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -080090
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -080091 /**
92 * Get the Network Graph.
93 *
94 * @return the Network Graph.
95 */
Pavlin Radoslavov6d224ee2014-02-18 16:43:15 -080096 NetworkGraph getNetworkGraph() {
97 return networkGraph;
98 }
99
Yuta HIGUCHI4bfdd532014-02-07 13:47:36 -0800100 /**
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800101 * Event handler class.
102 */
103 private class EventHandler extends Thread implements
104 IEventChannelListener<byte[], TopologyEvent> {
105 private BlockingQueue<EventEntry<TopologyEvent>> topologyEvents =
106 new LinkedBlockingQueue<EventEntry<TopologyEvent>>();
107
108 /**
109 * Startup processing.
110 */
111 private void startup() {
112 //
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800113 // TODO: Read all state from the database:
114 //
115 // Collection<EventEntry<TopologyEvent>> collection =
116 // readWholeTopologyFromDB();
117 //
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800118 // For now, as a shortcut we read it from the datagrid
119 //
120 Collection<TopologyEvent> topologyEvents =
121 eventChannel.getAllEntries();
122 Collection<EventEntry<TopologyEvent>> collection =
123 new LinkedList<EventEntry<TopologyEvent>>();
124
125 for (TopologyEvent topologyEvent : topologyEvents) {
126 EventEntry<TopologyEvent> eventEntry =
127 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
128 topologyEvent);
129 collection.add(eventEntry);
130 }
131 processEvents(collection);
132 }
133
134 /**
135 * Run the thread.
136 */
Yuta HIGUCHI240bf072014-02-17 10:55:21 -0800137 @Override
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800138 public void run() {
139 Collection<EventEntry<TopologyEvent>> collection =
140 new LinkedList<EventEntry<TopologyEvent>>();
141
Pavlin Radoslavovdb7dbb22014-02-18 14:45:10 -0800142 this.setName("TopologyManager.EventHandler " + this.getId());
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800143 startup();
144
145 //
146 // The main loop
147 //
148 try {
149 while (true) {
150 EventEntry<TopologyEvent> eventEntry = topologyEvents.take();
151 collection.add(eventEntry);
152 topologyEvents.drainTo(collection);
153
154 processEvents(collection);
155 collection.clear();
156 }
157 } catch (Exception exception) {
158 log.debug("Exception processing Topology Events: ", exception);
159 }
160 }
161
162 /**
163 * Process all topology events.
164 *
165 * @param events the events to process.
166 */
167 private void processEvents(Collection<EventEntry<TopologyEvent>> events) {
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800168
169 //
170 // Classify and suppress matching events
171 //
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800172 for (EventEntry<TopologyEvent> event : events) {
173 TopologyEvent topologyEvent = event.eventData();
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800174 SwitchEvent switchEvent = topologyEvent.switchEvent;
175 PortEvent portEvent = topologyEvent.portEvent;
176 LinkEvent linkEvent = topologyEvent.linkEvent;
177 DeviceEvent deviceEvent = topologyEvent.deviceEvent;
178
179 //
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800180 // Extract the events
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800181 //
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800182 switch (event.eventType()) {
183 case ENTRY_ADD:
184 log.debug("Topology event ENTRY_ADD: {}", topologyEvent);
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800185 if (switchEvent != null) {
186 ByteBuffer id = ByteBuffer.wrap(switchEvent.getID());
187 addedSwitchEvents.put(id, switchEvent);
188 removedSwitchEvents.remove(id);
189 }
190 if (portEvent != null) {
191 ByteBuffer id = ByteBuffer.wrap(portEvent.getID());
192 addedPortEvents.put(id, portEvent);
193 removedPortEvents.remove(id);
194 }
195 if (linkEvent != null) {
196 ByteBuffer id = ByteBuffer.wrap(linkEvent.getID());
197 addedLinkEvents.put(id, linkEvent);
198 removedLinkEvents.remove(id);
199 }
200 if (deviceEvent != null) {
201 ByteBuffer id = ByteBuffer.wrap(deviceEvent.getID());
202 addedDeviceEvents.put(id, deviceEvent);
203 removedDeviceEvents.remove(id);
204 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800205 break;
206 case ENTRY_REMOVE:
207 log.debug("Topology event ENTRY_REMOVE: {}", topologyEvent);
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800208 if (switchEvent != null) {
209 ByteBuffer id = ByteBuffer.wrap(switchEvent.getID());
210 addedSwitchEvents.remove(id);
211 removedSwitchEvents.put(id, switchEvent);
212 }
213 if (portEvent != null) {
214 ByteBuffer id = ByteBuffer.wrap(portEvent.getID());
215 addedPortEvents.remove(id);
216 removedPortEvents.put(id, portEvent);
217 }
218 if (linkEvent != null) {
219 ByteBuffer id = ByteBuffer.wrap(linkEvent.getID());
220 addedLinkEvents.remove(id);
221 removedLinkEvents.put(id, linkEvent);
222 }
223 if (deviceEvent != null) {
224 ByteBuffer id = ByteBuffer.wrap(deviceEvent.getID());
225 addedDeviceEvents.remove(id);
226 removedDeviceEvents.put(id, deviceEvent);
227 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800228 break;
229 }
230 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800231
232 //
233 // Apply the classified events.
234 //
235 // Apply the "add" events in the proper order:
236 // switch, port, link, device
237 //
238 for (SwitchEvent switchEvent : addedSwitchEvents.values())
239 addSwitch(switchEvent);
240 for (PortEvent portEvent : addedPortEvents.values())
241 addPort(portEvent);
242 for (LinkEvent linkEvent : addedLinkEvents.values())
243 addLink(linkEvent);
244 for (DeviceEvent deviceEvent : addedDeviceEvents.values())
245 addDevice(deviceEvent);
246 //
247 // Apply the "remove" events in the reverse order:
248 // device, link, port, switch
249 //
250 for (DeviceEvent deviceEvent : removedDeviceEvents.values())
251 removeDevice(deviceEvent);
252 for (LinkEvent linkEvent : removedLinkEvents.values())
253 removeLink(linkEvent);
254 for (PortEvent portEvent : removedPortEvents.values())
255 removePort(portEvent);
256 for (SwitchEvent switchEvent : removedSwitchEvents.values())
257 removeSwitch(switchEvent);
258
259
260 //
261 // Cleanup
262 //
263 addedSwitchEvents.clear();
264 removedSwitchEvents.clear();
265 addedPortEvents.clear();
266 removedPortEvents.clear();
267 addedLinkEvents.clear();
268 removedLinkEvents.clear();
269 addedDeviceEvents.clear();
270 removedDeviceEvents.clear();
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800271 }
272
273 /**
274 * Receive a notification that an entry is added.
275 *
276 * @param value the value for the entry.
277 */
278 @Override
279 public void entryAdded(TopologyEvent value) {
280 EventEntry<TopologyEvent> eventEntry =
281 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
282 value);
283 topologyEvents.add(eventEntry);
284 }
285
286 /**
287 * Receive a notification that an entry is removed.
288 *
289 * @param value the value for the entry.
290 */
291 @Override
292 public void entryRemoved(TopologyEvent value) {
293 EventEntry<TopologyEvent> eventEntry =
294 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_REMOVE,
295 value);
296 topologyEvents.add(eventEntry);
297 }
298
299 /**
300 * Receive a notification that an entry is updated.
301 *
302 * @param value the value for the entry.
303 */
304 @Override
305 public void entryUpdated(TopologyEvent value) {
306 // NOTE: The ADD and UPDATE events are processed in same way
307 entryAdded(value);
308 }
309 }
310
311 /**
312 * Startup processing.
313 *
314 * @param datagridService the datagrid service to use.
315 */
316 void startup(IDatagridService datagridService) {
317 eventChannel = datagridService.addListener(EVENT_CHANNEL_NAME,
318 eventHandler,
319 byte[].class,
320 TopologyEvent.class);
321 eventHandler.start();
322 }
323
Jonathan Hart22eb9882014-02-11 15:52:59 -0800324 /* ******************************
325 * NetworkGraphDiscoveryInterface methods
326 * ******************************/
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -0800327
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800328 @Override
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800329 public void putSwitchDiscoveryEvent(SwitchEvent switchEvent,
330 Collection<PortEvent> portEvents) {
331 if (datastore.addSwitch(switchEvent, portEvents)) {
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800332 // Send out notification
Pavlin Radoslavov87dcc262014-02-19 21:13:23 -0800333 TopologyEvent topologyEvent = new TopologyEvent(switchEvent);
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800334 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800335
336 for (PortEvent portEvent : portEvents) {
337 topologyEvent = new TopologyEvent(portEvent);
338 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
339 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800340 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800341 }
342
343 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800344 public void removeSwitchDiscoveryEvent(SwitchEvent switchEvent) {
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800345 // TODO: Use a copy of the port events previously added for that switch
346 Collection<PortEvent> portEvents = new LinkedList<PortEvent>();
347
348 if (datastore.deactivateSwitch(switchEvent, portEvents)) {
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800349 // Send out notification
350 eventChannel.removeEntry(switchEvent.getID());
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800351
352 for (PortEvent portEvent : portEvents) {
353 eventChannel.removeEntry(portEvent.getID());
354 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800355 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800356 }
357
358 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800359 public void putPortDiscoveryEvent(PortEvent portEvent) {
Pavlin Radoslavov50cd1482014-02-19 16:57:03 -0800360 if (datastore.addPort(portEvent)) {
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800361 // Send out notification
Pavlin Radoslavov87dcc262014-02-19 21:13:23 -0800362 TopologyEvent topologyEvent = new TopologyEvent(portEvent);
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800363 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800364 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800365 }
366
367 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800368 public void removePortDiscoveryEvent(PortEvent portEvent) {
Pavlin Radoslavov50cd1482014-02-19 16:57:03 -0800369 if (datastore.deactivatePort(portEvent)) {
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800370 // Send out notification
371 eventChannel.removeEntry(portEvent.getID());
372 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800373 }
374
375 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800376 public void putLinkDiscoveryEvent(LinkEvent linkEvent) {
Pavlin Radoslavov50cd1482014-02-19 16:57:03 -0800377 if (datastore.addLink(linkEvent)) {
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800378 // Send out notification
Pavlin Radoslavov87dcc262014-02-19 21:13:23 -0800379 TopologyEvent topologyEvent = new TopologyEvent(linkEvent);
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800380 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
381 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800382 }
383
384 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800385 public void removeLinkDiscoveryEvent(LinkEvent linkEvent) {
Pavlin Radoslavov50cd1482014-02-19 16:57:03 -0800386 if (datastore.removeLink(linkEvent)) {
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800387 // Send out notification
388 eventChannel.removeEntry(linkEvent.getID());
Jonathan Hart22eb9882014-02-11 15:52:59 -0800389 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800390 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800391
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800392 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800393 public void putDeviceDiscoveryEvent(DeviceEvent deviceEvent) {
Pavlin Radoslavov50cd1482014-02-19 16:57:03 -0800394 if (datastore.addDevice(deviceEvent)) {
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800395 // Send out notification
Pavlin Radoslavov87dcc262014-02-19 21:13:23 -0800396 TopologyEvent topologyEvent = new TopologyEvent(deviceEvent);
Pavlin Radoslavov50cd1482014-02-19 16:57:03 -0800397 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
Jonathan Hart22eb9882014-02-11 15:52:59 -0800398 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800399 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800400
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800401 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800402 public void removeDeviceDiscoveryEvent(DeviceEvent deviceEvent) {
Pavlin Radoslavov50cd1482014-02-19 16:57:03 -0800403 if (datastore.removeDevice(deviceEvent)) {
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800404 // Send out notification
405 eventChannel.removeEntry(deviceEvent.getID());
Jonathan Hart22eb9882014-02-11 15:52:59 -0800406 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800407 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800408
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800409 /* ************************************************
410 * Internal methods to maintain the network graph
411 * ************************************************/
412 private void addSwitch(SwitchEvent swEvent) {
413 Switch sw = networkGraph.getSwitch(swEvent.getDpid());
414 if (sw == null) {
415 sw = new SwitchImpl(networkGraph, swEvent.getDpid());
416 networkGraph.putSwitch(sw);
417 } else {
418 // TODO: Update the switch attributes
419 // TODO: Nothing to do for now
420 }
421 }
422
423 private void removeSwitch(SwitchEvent swEvent) {
424 Switch sw = networkGraph.getSwitch(swEvent.getDpid());
425 if (sw == null) {
426 log.warn("Switch {} already removed, ignoring", swEvent);
427 return;
428 }
429
430 //
431 // Remove all Ports on the Switch
432 //
433 ArrayList<PortEvent> portsToRemove = new ArrayList<>();
434 for (Port port : sw.getPorts()) {
435 log.warn("Port {} on Switch {} should be removed prior to removing Switch. Removing Port now.",
436 port, swEvent);
437 PortEvent portEvent = new PortEvent(port.getDpid(),
438 port.getNumber());
439 portsToRemove.add(portEvent);
440 }
441 for (PortEvent portEvent : portsToRemove)
442 removePort(portEvent);
443
444 networkGraph.removeSwitch(swEvent.getDpid());
445 }
446
447 private void addPort(PortEvent portEvent) {
448 Switch sw = networkGraph.getSwitch(portEvent.getDpid());
449 if (sw == null) {
450 // Reordered event
451 // TODO: Delay the event in local cache
452 return;
453 }
454 SwitchImpl switchImpl = getSwitchImpl(sw);
455
456 Port port = sw.getPort(portEvent.getNumber());
457 if (port == null) {
458 port = new PortImpl(networkGraph, sw, portEvent.getNumber());
459 switchImpl.addPort(port);
460 } else {
461 // TODO: Update the port attributes
462 }
463 }
464
465 private void removePort(PortEvent portEvent) {
466 Switch sw = networkGraph.getSwitch(portEvent.getDpid());
467 if (sw == null) {
468 log.warn("Parent Switch for Port {} already removed, ignoring",
469 portEvent);
470 return;
471 }
472
473 Port port = sw.getPort(portEvent.getNumber());
474 if (port == null) {
475 log.warn("Port {} already removed, ignoring", portEvent);
476 return;
477 }
478
479 //
480 // Remove all Devices attached to the Port
481 //
482 ArrayList<DeviceEvent> devicesToRemove = new ArrayList<>();
483 for (Device device : port.getDevices()) {
484 log.debug("Removing Device {} on Port {}", device, portEvent);
485 DeviceEvent deviceEvent = new DeviceEvent(device.getMacAddress());
486 SwitchPort switchPort = new SwitchPort(port.getSwitch().getDpid(),
487 port.getNumber());
488 deviceEvent.addAttachmentPoint(switchPort);
489 devicesToRemove.add(deviceEvent);
490 }
491 for (DeviceEvent deviceEvent : devicesToRemove)
492 removeDevice(deviceEvent);
493
494 //
495 // Remove all Links connected to the Port
496 //
497 Set<Link> links = new HashSet<>();
498 links.add(port.getOutgoingLink());
499 links.add(port.getIncomingLink());
500 ArrayList<LinkEvent> linksToRemove = new ArrayList<>();
501 for (Link link : links) {
502 if (link == null)
503 continue;
504 log.debug("Removing Link {} on Port {}", link, portEvent);
505 LinkEvent linkEvent = new LinkEvent(link.getSrcSwitch().getDpid(),
506 link.getSrcPort().getNumber(),
507 link.getDstSwitch().getDpid(),
508 link.getDstPort().getNumber());
509 linksToRemove.add(linkEvent);
510 }
511 for (LinkEvent linkEvent : linksToRemove)
512 removeLink(linkEvent);
513
514 // Remove the Port from the Switch
515 SwitchImpl switchImpl = getSwitchImpl(sw);
516 switchImpl.removePort(port);
517 }
518
519 private void addLink(LinkEvent linkEvent) {
520 Port srcPort = networkGraph.getPort(linkEvent.getSrc().dpid,
521 linkEvent.getSrc().number);
522 if (srcPort == null) {
523 // Reordered event
524 // TODO: Delay the event in local cache
525 return;
526 }
527
528 Port dstPort = networkGraph.getPort(linkEvent.getDst().dpid,
529 linkEvent.getDst().number);
530 if (dstPort == null) {
531 // Reordered event
532 // TODO: Delay the event in local cache
533 return;
534 }
535
536 // Get the Link instance from the Destination Port Incoming Link
537 Link link = dstPort.getIncomingLink();
538 assert(link == srcPort.getOutgoingLink());
539 if (link == null) {
540 link = new LinkImpl(networkGraph, srcPort, dstPort);
541 PortImpl srcPortImpl = getPortImpl(srcPort);
542 PortImpl dstPortImpl = getPortImpl(dstPort);
543 srcPortImpl.setOutgoingLink(link);
544 dstPortImpl.setIncomingLink(link);
545
546 // Remove all Devices attached to the Ports
547 ArrayList<DeviceEvent> devicesToRemove = new ArrayList<>();
548 ArrayList<Port> ports = new ArrayList<>();
549 ports.add(srcPort);
550 ports.add(dstPort);
551 for (Port port : ports) {
552 for (Device device : port.getDevices()) {
553 log.error("Device {} on Port {} should have been removed prior to adding Link {}",
554 device, port, linkEvent);
555 DeviceEvent deviceEvent =
556 new DeviceEvent(device.getMacAddress());
557 SwitchPort switchPort =
558 new SwitchPort(port.getSwitch().getDpid(),
559 port.getNumber());
560 deviceEvent.addAttachmentPoint(switchPort);
561 devicesToRemove.add(deviceEvent);
562 }
563 }
564 for (DeviceEvent deviceEvent : devicesToRemove)
565 removeDevice(deviceEvent);
566 } else {
567 // TODO: Update the link attributes
568 }
569 }
570
571 private void removeLink(LinkEvent linkEvent) {
572 Port srcPort = networkGraph.getPort(linkEvent.getSrc().dpid,
573 linkEvent.getSrc().number);
574 if (srcPort == null) {
575 log.warn("Src Port for Link {} already removed, ignoring",
576 linkEvent);
577 return;
578 }
579
580 Port dstPort = networkGraph.getPort(linkEvent.getDst().dpid,
581 linkEvent.getDst().number);
582 if (dstPort == null) {
583 log.warn("Dst Port for Link {} already removed, ignoring",
584 linkEvent);
585 return;
586 }
587
588 //
589 // Remove the Link instance from the Destination Port Incoming Link
590 // and the Source Port Outgoing Link.
591 //
592 Link link = dstPort.getIncomingLink();
593 if (link == null) {
594 log.warn("Link {} already removed on destination Port", linkEvent);
595 }
596 link = srcPort.getOutgoingLink();
597 if (link == null) {
598 log.warn("Link {} already removed on src Port", linkEvent);
599 }
600 getPortImpl(dstPort).setIncomingLink(null);
601 getPortImpl(srcPort).setOutgoingLink(null);
602 }
603
604 // TODO: Device-related work is incomplete
605 private void addDevice(DeviceEvent deviceEvent) {
606 Device device = networkGraph.getDeviceByMac(deviceEvent.getMac());
607 if (device == null) {
608 device = new DeviceImpl(networkGraph, deviceEvent.getMac());
609 }
610 DeviceImpl deviceImpl = getDeviceImpl(device);
611
612 // Update the IP addresses
613 for (InetAddress ipAddr : deviceEvent.getIpAddresses())
614 deviceImpl.addIpAddress(ipAddr);
615
616 // Process each attachment point
617 boolean attachmentFound = false;
618 for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
619 // Attached Ports must exist
620 Port port = networkGraph.getPort(swp.dpid, swp.number);
621 if (port == null) {
622 // Reordered event
623 // TODO: Delay the event in local cache
624 continue;
625 }
626 // Attached Ports must not have Link
627 if (port.getOutgoingLink() != null ||
628 port.getIncomingLink() != null) {
629 log.warn("Link (Out:{},In:{}) exist on the attachment point, skipping mutation.",
630 port.getOutgoingLink(),
631 port.getIncomingLink());
632 continue;
633 }
634
635 // Add Device <-> Port attachment
636 PortImpl portImpl = getPortImpl(port);
637 portImpl.addDevice(device);
638 deviceImpl.addAttachmentPoint(port);
639 attachmentFound = true;
640 }
641
642 // Update the device in the Network Graph
643 if (attachmentFound)
644 networkGraph.putDevice(device);
645 }
646
647 private void removeDevice(DeviceEvent deviceEvent) {
648 Device device = networkGraph.getDeviceByMac(deviceEvent.getMac());
649 if (device == null) {
650 log.warn("Device {} already removed, ignoring", deviceEvent);
651 return;
652 }
653 DeviceImpl deviceImpl = getDeviceImpl(device);
654
655 // Process each attachment point
656 for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
657 // Attached Ports must exist
658 Port port = networkGraph.getPort(swp.dpid, swp.number);
659 if (port == null) {
660 log.warn("Port for the attachment point {} did not exist. skipping attachment point mutation", swp);
661 continue;
662 }
663
664 // Remove Device <-> Port attachment
665 PortImpl portImpl = getPortImpl(port);
666 portImpl.removeDevice(device);
667 deviceImpl.removeAttachmentPoint(port);
668 }
669 networkGraph.removeDevice(device);
670 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800671
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800672 /**
673 *
674 * @param swEvent
675 * @return true if ready to accept event.
676 */
677 private boolean prepareForAddSwitchEvent(SwitchEvent swEvent) {
678 // No show stopping precondition
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800679 return true;
680 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800681
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800682 private boolean prepareForRemoveSwitchEvent(SwitchEvent swEvent) {
683 // No show stopping precondition
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800684 return true;
685 }
Yuta HIGUCHI71e7a052014-02-17 22:14:15 -0800686
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800687 private boolean prepareForAddPortEvent(PortEvent portEvent) {
688 // Parent Switch must exist
689 if (networkGraph.getSwitch(portEvent.getDpid()) == null) {
690 log.warn("Dropping add port event because switch doesn't exist: {}",
691 portEvent);
692 return false;
693 }
694 // Prep: None
695 return true;
696 }
697
698 private boolean prepareForRemovePortEvent(PortEvent portEvent) {
699 Port port = networkGraph.getPort(portEvent.getDpid(),
700 portEvent.getNumber());
701 if (port == null) {
702 log.debug("Port already removed? {}", portEvent);
703 // let it pass
704 return true;
Jonathan Hart22eb9882014-02-11 15:52:59 -0800705 }
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -0800706
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800707 // Prep: Remove Link and Device Attachment
708 ArrayList<DeviceEvent> deviceEvents = new ArrayList<>();
709 for (Device device : port.getDevices()) {
710 log.debug("Removing Device {} on Port {}", device, portEvent);
711 DeviceEvent devEvent = new DeviceEvent(device.getMacAddress());
712 devEvent.addAttachmentPoint(new SwitchPort(port.getSwitch().getDpid(),
713 port.getNumber()));
714 deviceEvents.add(devEvent);
715 }
716 for (DeviceEvent devEvent : deviceEvents) {
717 // calling Discovery API to wipe from DB, etc.
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800718 removeDeviceDiscoveryEvent(devEvent);
Jonathan Hart22eb9882014-02-11 15:52:59 -0800719 }
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -0800720
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800721 Set<Link> links = new HashSet<>();
722 links.add(port.getOutgoingLink());
723 links.add(port.getIncomingLink());
724 for (Link link : links) {
725 if (link == null) {
726 continue;
727 }
728 log.debug("Removing Link {} on Port {}", link, portEvent);
729 LinkEvent linkEvent =
Pavlin Radoslavov7c8f69a2014-02-19 19:01:45 -0800730 new LinkEvent(link.getSrcSwitch().getDpid(),
731 link.getSrcPort().getNumber(),
732 link.getDstSwitch().getDpid(),
733 link.getDstPort().getNumber());
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800734 // calling Discovery API to wipe from DB, etc.
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800735
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800736 // Call internal remove Link, which will check
737 // ownership of DST dpid and modify DB only if it is the owner
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800738 removeLinkDiscoveryEvent(linkEvent, true);
Jonathan Hart22eb9882014-02-11 15:52:59 -0800739 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800740 return true;
741 }
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -0800742
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800743 private boolean prepareForAddLinkEvent(LinkEvent linkEvent) {
744 // Src/Dst Port must exist
745 Port srcPort = networkGraph.getPort(linkEvent.getSrc().dpid,
746 linkEvent.getSrc().number);
747 Port dstPort = networkGraph.getPort(linkEvent.getDst().dpid,
748 linkEvent.getDst().number);
749 if (srcPort == null || dstPort == null) {
Jonathan Hart0a4846e2014-02-18 11:03:40 -0800750 log.warn("Dropping add link event because port doesn't exist: {}",
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800751 linkEvent);
752 return false;
Jonathan Hart22eb9882014-02-11 15:52:59 -0800753 }
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -0800754
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800755 // Prep: remove Device attachment on both Ports
756 ArrayList<DeviceEvent> deviceEvents = new ArrayList<>();
757 for (Device device : srcPort.getDevices()) {
758 DeviceEvent devEvent = new DeviceEvent(device.getMacAddress());
759 devEvent.addAttachmentPoint(new SwitchPort(srcPort.getSwitch().getDpid(), srcPort.getNumber()));
760 deviceEvents.add(devEvent);
761 }
762 for (Device device : dstPort.getDevices()) {
763 DeviceEvent devEvent = new DeviceEvent(device.getMacAddress());
764 devEvent.addAttachmentPoint(new SwitchPort(dstPort.getSwitch().getDpid(),
765 dstPort.getNumber()));
766 deviceEvents.add(devEvent);
767 }
768 for (DeviceEvent devEvent : deviceEvents) {
769 // calling Discovery API to wipe from DB, etc.
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800770 removeDeviceDiscoveryEvent(devEvent);
Jonathan Hart22eb9882014-02-11 15:52:59 -0800771 }
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -0800772
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800773 return true;
774 }
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800775
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800776 private boolean prepareForRemoveLinkEvent(LinkEvent linkEvent) {
777 // Src/Dst Port must exist
778 Port srcPort = networkGraph.getPort(linkEvent.getSrc().dpid,
779 linkEvent.getSrc().number);
780 Port dstPort = networkGraph.getPort(linkEvent.getDst().dpid,
781 linkEvent.getDst().number);
782 if (srcPort == null || dstPort == null) {
783 log.warn("Dropping remove link event because port doesn't exist {}", linkEvent);
784 return false;
785 }
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800786
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800787 Link link = srcPort.getOutgoingLink();
788
789 // Link is already gone, or different Link exist in memory
790 // XXX Check if we should reject or just accept these cases.
791 // it should be harmless to remove the Link on event from DB anyways
792 if (link == null ||
Pavlin Radoslavov7c8f69a2014-02-19 19:01:45 -0800793 !link.getDstPort().getNumber().equals(linkEvent.getDst().number)
794 || !link.getDstSwitch().getDpid().equals(linkEvent.getDst().dpid)) {
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800795 log.warn("Dropping remove link event because link doesn't exist: {}", linkEvent);
796 return false;
797 }
798 // Prep: None
799 return true;
800 }
801
802 /**
803 *
804 * @param deviceEvent Event will be modified to remove inapplicable attachemntPoints/ipAddress
805 * @return false if this event should be dropped.
806 */
807 private boolean prepareForAddDeviceEvent(DeviceEvent deviceEvent) {
808 boolean preconditionBroken = false;
809 ArrayList<PortEvent.SwitchPort> failedSwitchPort = new ArrayList<>();
810 for ( PortEvent.SwitchPort swp : deviceEvent.getAttachmentPoints() ) {
811 // Attached Ports must exist
812 Port port = networkGraph.getPort(swp.dpid, swp.number);
813 if (port == null) {
814 preconditionBroken = true;
815 failedSwitchPort.add(swp);
816 continue;
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800817 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800818 // Attached Ports must not have Link
819 if (port.getOutgoingLink() != null ||
820 port.getIncomingLink() != null) {
821 preconditionBroken = true;
822 failedSwitchPort.add(swp);
823 continue;
824 }
825 }
826
827 // Rewriting event to exclude failed attachmentPoint
828 // XXX Assumption behind this is that inapplicable device event should
829 // be dropped, not deferred. If we decide to defer Device event,
830 // rewriting can become a problem
831 List<SwitchPort> attachmentPoints = deviceEvent.getAttachmentPoints();
832 attachmentPoints.removeAll(failedSwitchPort);
833 deviceEvent.setAttachmentPoints(attachmentPoints);
834
835 if (deviceEvent.getAttachmentPoints().isEmpty() &&
836 deviceEvent.getIpAddresses().isEmpty()) {
837 // return false to represent: Nothing left to do for this event.
838 // Caller should drop event
839 return false;
840 }
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800841
842 // Should we return false to tell caller that the event was trimmed?
843 // if ( preconditionBroken ) {
844 // return false;
845 // }
846
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800847 return true;
848 }
849
850 private boolean prepareForRemoveDeviceEvent(DeviceEvent deviceEvent) {
851 // No show stopping precondition?
852 // Prep: none
853 return true;
854 }
855
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800856 private void dispatchPutSwitchEvent(SwitchEvent switchEvent) {
857 for (INetworkGraphListener listener : this.networkGraphListeners) {
858 // TODO Should copy before handing them over to listener
859 listener.putSwitchEvent(switchEvent);
860 }
861 }
862
863 private void dispatchRemoveSwitchEvent(SwitchEvent switchEvent) {
864 for (INetworkGraphListener listener : this.networkGraphListeners) {
865 // TODO Should copy before handing them over to listener
866 listener.removeSwitchEvent(switchEvent);
867 }
868 }
869
870 private void dispatchPutPortEvent(PortEvent portEvent) {
871 for (INetworkGraphListener listener : this.networkGraphListeners) {
872 // TODO Should copy before handing them over to listener
873 listener.putPortEvent(portEvent);
874 }
875 }
876
877 private void dispatchRemovePortEvent(PortEvent portEvent) {
878 for (INetworkGraphListener listener : this.networkGraphListeners) {
879 // TODO Should copy before handing them over to listener
880 listener.removePortEvent(portEvent);
881 }
882 }
883
884 private void dispatchPutLinkEvent(LinkEvent linkEvent) {
885 for (INetworkGraphListener listener : this.networkGraphListeners) {
886 // TODO Should copy before handing them over to listener
887 listener.putLinkEvent(linkEvent);
888 }
889 }
890
891 private void dispatchRemoveLinkEvent(LinkEvent linkEvent) {
892 for (INetworkGraphListener listener : this.networkGraphListeners) {
893 // TODO Should copy before handing them over to listener
894 listener.removeLinkEvent(linkEvent);
895 }
896 }
897
898 private void dispatchPutDeviceEvent(DeviceEvent deviceEvent) {
899 for (INetworkGraphListener listener : this.networkGraphListeners) {
900 // TODO Should copy before handing them over to listener
901 listener.putDeviceEvent(deviceEvent);;
902 }
903 }
904
905 private void dispatchRemoveDeviceEvent(DeviceEvent deviceEvent) {
906 for (INetworkGraphListener listener : this.networkGraphListeners) {
907 // TODO Should copy before handing them over to listener
908 listener.removeDeviceEvent(deviceEvent);
909 }
910 }
911
912 private SwitchImpl getSwitchImpl(Switch sw) {
913 if (sw instanceof SwitchImpl) {
914 return (SwitchImpl) sw;
915 }
916 throw new ClassCastException("SwitchImpl expected, but found: " + sw);
917 }
918
919 private PortImpl getPortImpl(Port p) {
920 if (p instanceof PortImpl) {
921 return (PortImpl) p;
922 }
923 throw new ClassCastException("PortImpl expected, but found: " + p);
924 }
925
926 private LinkImpl getLinkImpl(Link l) {
927 if (l instanceof LinkImpl) {
928 return (LinkImpl) l;
929 }
930 throw new ClassCastException("LinkImpl expected, but found: " + l);
931 }
932
933 private DeviceImpl getDeviceImpl(Device d) {
934 if (d instanceof DeviceImpl) {
935 return (DeviceImpl) d;
936 }
937 throw new ClassCastException("DeviceImpl expected, but found: " + d);
938 }
939
940 @Deprecated
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800941 private Collection<EventEntry<TopologyEvent>> readWholeTopologyFromDB() {
942 Collection<EventEntry<TopologyEvent>> collection =
943 new LinkedList<EventEntry<TopologyEvent>>();
944
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800945 // XXX May need to clear whole topology first, depending on
946 // how we initially subscribe to replication events
947
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800948 // Add all active switches
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800949 for (RCSwitch sw : RCSwitch.getAllSwitches()) {
950 if (sw.getStatus() != RCSwitch.STATUS.ACTIVE) {
951 continue;
952 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800953
954 SwitchEvent switchEvent = new SwitchEvent(sw.getDpid());
955 TopologyEvent topologyEvent = new TopologyEvent(switchEvent);
956 EventEntry<TopologyEvent> eventEntry =
957 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
958 topologyEvent);
959 collection.add(eventEntry);
Yuta HIGUCHIa536e762014-02-17 21:47:28 -0800960 }
961
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800962 // Add all active ports
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800963 for (RCPort p : RCPort.getAllPorts()) {
964 if (p.getStatus() != RCPort.STATUS.ACTIVE) {
965 continue;
Yuta HIGUCHIa536e762014-02-17 21:47:28 -0800966 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800967
968 PortEvent portEvent = new PortEvent(p.getDpid(), p.getNumber());
969 TopologyEvent topologyEvent = new TopologyEvent(portEvent);
970 EventEntry<TopologyEvent> eventEntry =
971 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
972 topologyEvent);
973 collection.add(eventEntry);
Yuta HIGUCHIa536e762014-02-17 21:47:28 -0800974 }
975
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800976 // TODO Is Device going to be in DB? If so, read from DB.
977 // for (RCDevice d : RCDevice.getAllDevices()) {
978 // DeviceEvent devEvent = new DeviceEvent( MACAddress.valueOf(d.getMac()) );
979 // for (byte[] portId : d.getAllPortIds() ) {
980 // devEvent.addAttachmentPoint( new SwitchPort( RCPort.getDpidFromKey(portId), RCPort.getNumberFromKey(portId) ));
981 // }
982 // }
983
984 for (RCLink l : RCLink.getAllLinks()) {
985 // check if src/dst switch/port exist before triggering event
986 Port srcPort = networkGraph.getPort(l.getSrc().dpid,
987 l.getSrc().number);
988 Port dstPort = networkGraph.getPort(l.getDst().dpid,
989 l.getDst().number);
990 if (srcPort == null || dstPort == null) {
991 continue;
Yuta HIGUCHI76df2472014-02-12 22:36:51 -0800992 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800993
994 LinkEvent linkEvent = new LinkEvent(l.getSrc().dpid,
995 l.getSrc().number,
996 l.getDst().dpid,
997 l.getDst().number);
998 TopologyEvent topologyEvent = new TopologyEvent(linkEvent);
999 EventEntry<TopologyEvent> eventEntry =
1000 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
1001 topologyEvent);
1002 collection.add(eventEntry);
Yuta HIGUCHI76df2472014-02-12 22:36:51 -08001003 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001004
1005 return collection;
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001006 }
Pavlin Radoslavov50cd1482014-02-19 16:57:03 -08001007
1008 @Deprecated
1009 private void removeLinkDiscoveryEvent(LinkEvent linkEvent,
1010 boolean dstCheckBeforeDBmodify) {
1011 if (prepareForRemoveLinkEvent(linkEvent)) {
1012 if (dstCheckBeforeDBmodify) {
1013 // write to DB only if it is owner of the dst dpid
1014 // XXX this will cause link remove events to be dropped
1015 // if the dst switch just disconnected
1016 if (registryService.hasControl(linkEvent.getDst().dpid)) {
1017 datastore.removeLink(linkEvent);
1018 }
1019 } else {
1020 datastore.removeLink(linkEvent);
1021 }
1022 removeLink(linkEvent);
1023 // Send out notification
1024 eventChannel.removeEntry(linkEvent.getID());
1025 }
1026 // TODO handle invariant violation
1027 }
Jonathan Hart062a2e82014-02-03 09:41:57 -08001028}