blob: 580e785e590af69cfca0534a490a550704e01007 [file] [log] [blame]
Jonathan Hart472062d2014-04-03 10:56:48 -07001package net.onrc.onos.core.topology;
Jonathan Hart062a2e82014-02-03 09:41:57 -08002
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
Jonathan Hart6df90172014-04-03 10:13:11 -070017import net.onrc.onos.core.datagrid.IDatagridService;
18import net.onrc.onos.core.datagrid.IEventChannel;
19import net.onrc.onos.core.datagrid.IEventChannelListener;
20import net.onrc.onos.core.datastore.topology.KVLink;
21import net.onrc.onos.core.datastore.topology.KVPort;
22import net.onrc.onos.core.datastore.topology.KVSwitch;
Jonathan Hartdeda0ba2014-04-03 11:14:12 -070023import net.onrc.onos.core.registry.IControllerRegistryService;
Jonathan Hart472062d2014-04-03 10:56:48 -070024import net.onrc.onos.core.topology.PortEvent.SwitchPort;
Jonathan Hart23701d12014-04-03 10:45:48 -070025import net.onrc.onos.core.util.EventEntry;
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.
Ray Milkey269ffb92014-04-03 14:43:30 -070032 * <p/>
Yuta HIGUCHI4bfdd532014-02-07 13:47:36 -080033 * - Maintain Invariant/Relationships between Topology Objects.
Ray Milkey269ffb92014-04-03 14:43:30 -070034 * <p/>
Yuta HIGUCHI765cd0d2014-02-06 12:46:41 -080035 * TODO To be synchronized based on TopologyEvent Notification.
Ray Milkey269ffb92014-04-03 14:43:30 -070036 * <p/>
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).
Ray Milkey269ffb92014-04-03 14:43:30 -070039 * <p/>
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 HIGUCHI181d34d2014-02-05 15:05:46 -080042 */
Pavlin Radoslavov87dcc262014-02-19 21:13:23 -080043public class TopologyManager implements NetworkGraphDiscoveryInterface {
Jonathan Hart062a2e82014-02-03 09:41:57 -080044
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080045 private static final Logger log = LoggerFactory
Ray Milkey269ffb92014-04-03 14:43:30 -070046 .getLogger(TopologyManager.class);
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -080047
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080048 private IEventChannel<byte[], TopologyEvent> eventChannel;
Jonathan Hart10a7e2b2014-02-21 18:30:08 -080049 public static final String EVENT_CHANNEL_NAME = "onos.topology";
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080050 private EventHandler eventHandler = new EventHandler();
51
Jonathan Hart22eb9882014-02-11 15:52:59 -080052 private final NetworkGraphDatastore datastore;
Pavlin Radoslavov6d224ee2014-02-18 16:43:15 -080053 private final NetworkGraphImpl networkGraph = new NetworkGraphImpl();
Yuta HIGUCHI170229f2014-02-17 15:47:54 -080054 private final IControllerRegistryService registryService;
Yuta HIGUCHIa536e762014-02-17 21:47:28 -080055 private CopyOnWriteArrayList<INetworkGraphListener> networkGraphListeners;
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -080056
Pavlin Radoslavov706add22014-02-20 12:15:59 -080057 //
58 // Local state for keeping track of reordered events.
59 // NOTE: Switch Events are not affected by the event reordering.
60 //
61 private Map<ByteBuffer, PortEvent> reorderedAddedPortEvents =
Ray Milkey269ffb92014-04-03 14:43:30 -070062 new HashMap<ByteBuffer, PortEvent>();
Pavlin Radoslavov706add22014-02-20 12:15:59 -080063 private Map<ByteBuffer, LinkEvent> reorderedAddedLinkEvents =
Ray Milkey269ffb92014-04-03 14:43:30 -070064 new HashMap<ByteBuffer, LinkEvent>();
Pavlin Radoslavov706add22014-02-20 12:15:59 -080065 private Map<ByteBuffer, DeviceEvent> reorderedAddedDeviceEvents =
Ray Milkey269ffb92014-04-03 14:43:30 -070066 new HashMap<ByteBuffer, DeviceEvent>();
Pavlin Radoslavov018d5332014-02-19 23:08:35 -080067
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -080068 //
Pavlin Radoslavov26d83402014-02-20 15:24:30 -080069 // Local state for keeping track of locally discovered events so we can
70 // cleanup properly when a Switch or Port is removed.
71 //
72 // We keep all Port, Link and Device events per Switch DPID:
73 // - If a switch goes down, we remove all corresponding Port, Link and
74 // Device events.
75 // - If a port on a switch goes down, we remove all corresponding Link
76 // and Device events.
77 //
78 private Map<Long, Map<ByteBuffer, PortEvent>> discoveredAddedPortEvents =
Ray Milkey269ffb92014-04-03 14:43:30 -070079 new HashMap<>();
Pavlin Radoslavov26d83402014-02-20 15:24:30 -080080 private Map<Long, Map<ByteBuffer, LinkEvent>> discoveredAddedLinkEvents =
Ray Milkey269ffb92014-04-03 14:43:30 -070081 new HashMap<>();
Pavlin Radoslavov26d83402014-02-20 15:24:30 -080082 private Map<Long, Map<ByteBuffer, DeviceEvent>> discoveredAddedDeviceEvents =
Ray Milkey269ffb92014-04-03 14:43:30 -070083 new HashMap<>();
Pavlin Radoslavov26d83402014-02-20 15:24:30 -080084
85 //
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -080086 // Local state for keeping track of the application event notifications
87 //
88 List<SwitchEvent> apiAddedSwitchEvents = new LinkedList<SwitchEvent>();
89 List<SwitchEvent> apiRemovedSwitchEvents = new LinkedList<SwitchEvent>();
90 List<PortEvent> apiAddedPortEvents = new LinkedList<PortEvent>();
91 List<PortEvent> apiRemovedPortEvents = new LinkedList<PortEvent>();
92 List<LinkEvent> apiAddedLinkEvents = new LinkedList<LinkEvent>();
93 List<LinkEvent> apiRemovedLinkEvents = new LinkedList<LinkEvent>();
94 List<DeviceEvent> apiAddedDeviceEvents = new LinkedList<DeviceEvent>();
95 List<DeviceEvent> apiRemovedDeviceEvents = new LinkedList<DeviceEvent>();
96
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -080097 /**
98 * Constructor.
99 *
Ray Milkey269ffb92014-04-03 14:43:30 -0700100 * @param registryService the Registry Service to use.
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800101 * @param networkGraphListeners the collection of Network Graph Listeners
Ray Milkey269ffb92014-04-03 14:43:30 -0700102 * to use.
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800103 */
104 public TopologyManager(IControllerRegistryService registryService,
Ray Milkey269ffb92014-04-03 14:43:30 -0700105 CopyOnWriteArrayList<INetworkGraphListener> networkGraphListeners) {
106 datastore = new NetworkGraphDatastore();
107 this.registryService = registryService;
108 this.networkGraphListeners = networkGraphListeners;
Yuta HIGUCHI80829d12014-02-05 20:16:56 -0800109 }
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -0800110
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800111 /**
112 * Get the Network Graph.
113 *
114 * @return the Network Graph.
115 */
Pavlin Radoslavov6d224ee2014-02-18 16:43:15 -0800116 NetworkGraph getNetworkGraph() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700117 return networkGraph;
Pavlin Radoslavov6d224ee2014-02-18 16:43:15 -0800118 }
119
Yuta HIGUCHI4bfdd532014-02-07 13:47:36 -0800120 /**
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800121 * Event handler class.
122 */
123 private class EventHandler extends Thread implements
Ray Milkey269ffb92014-04-03 14:43:30 -0700124 IEventChannelListener<byte[], TopologyEvent> {
125 private BlockingQueue<EventEntry<TopologyEvent>> topologyEvents =
126 new LinkedBlockingQueue<EventEntry<TopologyEvent>>();
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800127
Ray Milkey269ffb92014-04-03 14:43:30 -0700128 /**
129 * Startup processing.
130 */
131 private void startup() {
132 //
133 // TODO: Read all state from the database:
134 //
135 // Collection<EventEntry<TopologyEvent>> collection =
136 // readWholeTopologyFromDB();
137 //
138 // For now, as a shortcut we read it from the datagrid
139 //
140 Collection<TopologyEvent> topologyEvents =
141 eventChannel.getAllEntries();
142 Collection<EventEntry<TopologyEvent>> collection =
143 new LinkedList<EventEntry<TopologyEvent>>();
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800144
Ray Milkey269ffb92014-04-03 14:43:30 -0700145 for (TopologyEvent topologyEvent : topologyEvents) {
146 EventEntry<TopologyEvent> eventEntry =
147 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
148 topologyEvent);
149 collection.add(eventEntry);
150 }
151 processEvents(collection);
152 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800153
Ray Milkey269ffb92014-04-03 14:43:30 -0700154 /**
155 * Run the thread.
156 */
157 @Override
158 public void run() {
159 Collection<EventEntry<TopologyEvent>> collection =
160 new LinkedList<EventEntry<TopologyEvent>>();
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800161
Ray Milkey269ffb92014-04-03 14:43:30 -0700162 this.setName("TopologyManager.EventHandler " + this.getId());
163 startup();
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800164
Ray Milkey269ffb92014-04-03 14:43:30 -0700165 //
166 // The main loop
167 //
168 try {
169 while (true) {
170 EventEntry<TopologyEvent> eventEntry = topologyEvents.take();
171 collection.add(eventEntry);
172 topologyEvents.drainTo(collection);
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800173
Ray Milkey269ffb92014-04-03 14:43:30 -0700174 processEvents(collection);
175 collection.clear();
176 }
177 } catch (Exception exception) {
178 log.debug("Exception processing Topology Events: ", exception);
179 }
180 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800181
Ray Milkey269ffb92014-04-03 14:43:30 -0700182 /**
183 * Process all topology events.
184 *
185 * @param events the events to process.
186 */
187 private void processEvents(Collection<EventEntry<TopologyEvent>> events) {
188 // Local state for computing the final set of events
189 Map<ByteBuffer, SwitchEvent> addedSwitchEvents = new HashMap<>();
190 Map<ByteBuffer, SwitchEvent> removedSwitchEvents = new HashMap<>();
191 Map<ByteBuffer, PortEvent> addedPortEvents = new HashMap<>();
192 Map<ByteBuffer, PortEvent> removedPortEvents = new HashMap<>();
193 Map<ByteBuffer, LinkEvent> addedLinkEvents = new HashMap<>();
194 Map<ByteBuffer, LinkEvent> removedLinkEvents = new HashMap<>();
195 Map<ByteBuffer, DeviceEvent> addedDeviceEvents = new HashMap<>();
196 Map<ByteBuffer, DeviceEvent> removedDeviceEvents = new HashMap<>();
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800197
Ray Milkey269ffb92014-04-03 14:43:30 -0700198 //
199 // Classify and suppress matching events
200 //
201 for (EventEntry<TopologyEvent> event : events) {
202 TopologyEvent topologyEvent = event.eventData();
203 SwitchEvent switchEvent = topologyEvent.switchEvent;
204 PortEvent portEvent = topologyEvent.portEvent;
205 LinkEvent linkEvent = topologyEvent.linkEvent;
206 DeviceEvent deviceEvent = topologyEvent.deviceEvent;
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800207
Ray Milkey269ffb92014-04-03 14:43:30 -0700208 //
209 // Extract the events
210 //
211 switch (event.eventType()) {
212 case ENTRY_ADD:
213 log.debug("Topology event ENTRY_ADD: {}", topologyEvent);
214 if (switchEvent != null) {
215 ByteBuffer id = switchEvent.getIDasByteBuffer();
216 addedSwitchEvents.put(id, switchEvent);
217 removedSwitchEvents.remove(id);
218 // Switch Events are not affected by event reordering
219 }
220 if (portEvent != null) {
221 ByteBuffer id = portEvent.getIDasByteBuffer();
222 addedPortEvents.put(id, portEvent);
223 removedPortEvents.remove(id);
224 reorderedAddedPortEvents.remove(id);
225 }
226 if (linkEvent != null) {
227 ByteBuffer id = linkEvent.getIDasByteBuffer();
228 addedLinkEvents.put(id, linkEvent);
229 removedLinkEvents.remove(id);
230 reorderedAddedLinkEvents.remove(id);
231 }
232 if (deviceEvent != null) {
233 ByteBuffer id = deviceEvent.getIDasByteBuffer();
234 addedDeviceEvents.put(id, deviceEvent);
235 removedDeviceEvents.remove(id);
236 reorderedAddedDeviceEvents.remove(id);
237 }
238 break;
239 case ENTRY_REMOVE:
240 log.debug("Topology event ENTRY_REMOVE: {}", topologyEvent);
241 if (switchEvent != null) {
242 ByteBuffer id = switchEvent.getIDasByteBuffer();
243 addedSwitchEvents.remove(id);
244 removedSwitchEvents.put(id, switchEvent);
245 // Switch Events are not affected by event reordering
246 }
247 if (portEvent != null) {
248 ByteBuffer id = portEvent.getIDasByteBuffer();
249 addedPortEvents.remove(id);
250 removedPortEvents.put(id, portEvent);
251 reorderedAddedPortEvents.remove(id);
252 }
253 if (linkEvent != null) {
254 ByteBuffer id = linkEvent.getIDasByteBuffer();
255 addedLinkEvents.remove(id);
256 removedLinkEvents.put(id, linkEvent);
257 reorderedAddedLinkEvents.remove(id);
258 }
259 if (deviceEvent != null) {
260 ByteBuffer id = deviceEvent.getIDasByteBuffer();
261 addedDeviceEvents.remove(id);
262 removedDeviceEvents.put(id, deviceEvent);
263 reorderedAddedDeviceEvents.remove(id);
264 }
265 break;
266 }
267 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800268
Ray Milkey269ffb92014-04-03 14:43:30 -0700269 //
270 // Lock the Network Graph while it is modified
271 //
272 networkGraph.acquireWriteLock();
Pavlin Radoslavov8ffb8bf2014-02-20 15:34:26 -0800273
Ray Milkey269ffb92014-04-03 14:43:30 -0700274 try {
275 //
276 // Apply the classified events.
277 //
278 // Apply the "add" events in the proper order:
279 // switch, port, link, device
280 //
Ray Milkeyb29e6262014-04-09 16:02:14 -0700281 for (SwitchEvent switchEvent : addedSwitchEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700282 addSwitch(switchEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700283 }
284 for (PortEvent portEvent : addedPortEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700285 addPort(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700286 }
287 for (LinkEvent linkEvent : addedLinkEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700288 addLink(linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700289 }
290 for (DeviceEvent deviceEvent : addedDeviceEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700291 addDevice(deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700292 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700293 //
294 // Apply the "remove" events in the reverse order:
295 // device, link, port, switch
296 //
Ray Milkeyb29e6262014-04-09 16:02:14 -0700297 for (DeviceEvent deviceEvent : removedDeviceEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700298 removeDevice(deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700299 }
300 for (LinkEvent linkEvent : removedLinkEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700301 removeLink(linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700302 }
303 for (PortEvent portEvent : removedPortEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700304 removePort(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700305 }
306 for (SwitchEvent switchEvent : removedSwitchEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700307 removeSwitch(switchEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700308 }
Yuta HIGUCHI3aca81a2014-02-23 12:41:19 -0800309
Ray Milkey269ffb92014-04-03 14:43:30 -0700310 //
311 // Apply reordered events
312 //
313 applyReorderedEvents(!addedSwitchEvents.isEmpty(),
314 !addedPortEvents.isEmpty());
Yuta HIGUCHI3aca81a2014-02-23 12:41:19 -0800315
Ray Milkey269ffb92014-04-03 14:43:30 -0700316 } finally {
317 //
318 // Network Graph modifications completed: Release the lock
319 //
320 networkGraph.releaseWriteLock();
321 }
Yuta HIGUCHI3aca81a2014-02-23 12:41:19 -0800322
Ray Milkey269ffb92014-04-03 14:43:30 -0700323 //
324 // Dispatch the Topology Notification Events to the applications
325 //
326 dispatchNetworkGraphEvents();
327 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800328
Ray Milkey269ffb92014-04-03 14:43:30 -0700329 /**
330 * Receive a notification that an entry is added.
331 *
332 * @param value the value for the entry.
333 */
334 @Override
335 public void entryAdded(TopologyEvent value) {
336 EventEntry<TopologyEvent> eventEntry =
337 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
338 value);
339 topologyEvents.add(eventEntry);
340 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800341
Ray Milkey269ffb92014-04-03 14:43:30 -0700342 /**
343 * Receive a notification that an entry is removed.
344 *
345 * @param value the value for the entry.
346 */
347 @Override
348 public void entryRemoved(TopologyEvent value) {
349 EventEntry<TopologyEvent> eventEntry =
350 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_REMOVE,
351 value);
352 topologyEvents.add(eventEntry);
353 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800354
Ray Milkey269ffb92014-04-03 14:43:30 -0700355 /**
356 * Receive a notification that an entry is updated.
357 *
358 * @param value the value for the entry.
359 */
360 @Override
361 public void entryUpdated(TopologyEvent value) {
362 // NOTE: The ADD and UPDATE events are processed in same way
363 entryAdded(value);
364 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800365 }
366
367 /**
368 * Startup processing.
369 *
370 * @param datagridService the datagrid service to use.
371 */
372 void startup(IDatagridService datagridService) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700373 eventChannel = datagridService.addListener(EVENT_CHANNEL_NAME,
374 eventHandler,
375 byte[].class,
376 TopologyEvent.class);
377 eventHandler.start();
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800378 }
379
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800380 /**
381 * Dispatch Network Graph Events to the listeners.
382 */
383 private void dispatchNetworkGraphEvents() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700384 if (apiAddedSwitchEvents.isEmpty() &&
385 apiRemovedSwitchEvents.isEmpty() &&
386 apiAddedPortEvents.isEmpty() &&
387 apiRemovedPortEvents.isEmpty() &&
388 apiAddedLinkEvents.isEmpty() &&
389 apiRemovedLinkEvents.isEmpty() &&
390 apiAddedDeviceEvents.isEmpty() &&
391 apiRemovedDeviceEvents.isEmpty()) {
392 return; // No events to dispatch
393 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800394
Ray Milkey269ffb92014-04-03 14:43:30 -0700395 if (log.isDebugEnabled()) {
396 //
397 // Debug statements
398 // TODO: Those statements should be removed in the future
399 //
Ray Milkeyb29e6262014-04-09 16:02:14 -0700400 for (SwitchEvent switchEvent : apiAddedSwitchEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700401 log.debug("Dispatch Network Graph Event: ADDED {}", switchEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700402 }
403 for (SwitchEvent switchEvent : apiRemovedSwitchEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700404 log.debug("Dispatch Network Graph Event: REMOVED {}", switchEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700405 }
406 for (PortEvent portEvent : apiAddedPortEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700407 log.debug("Dispatch Network Graph Event: ADDED {}", portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700408 }
409 for (PortEvent portEvent : apiRemovedPortEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700410 log.debug("Dispatch Network Graph Event: REMOVED {}", portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700411 }
412 for (LinkEvent linkEvent : apiAddedLinkEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700413 log.debug("Dispatch Network Graph Event: ADDED {}", linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700414 }
415 for (LinkEvent linkEvent : apiRemovedLinkEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700416 log.debug("Dispatch Network Graph Event: REMOVED {}", linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700417 }
418 for (DeviceEvent deviceEvent : apiAddedDeviceEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700419 log.debug("Dispatch Network Graph Event: ADDED {}", deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700420 }
421 for (DeviceEvent deviceEvent : apiRemovedDeviceEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700422 log.debug("Dispatch Network Graph Event: REMOVED {}", deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700423 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700424 }
adminbc181552014-02-21 18:36:42 -0800425
Ray Milkey269ffb92014-04-03 14:43:30 -0700426 // Deliver the events
427 for (INetworkGraphListener listener : this.networkGraphListeners) {
428 // TODO: Should copy before handing them over to listener?
429 listener.networkGraphEvents(apiAddedSwitchEvents,
430 apiRemovedSwitchEvents,
431 apiAddedPortEvents,
432 apiRemovedPortEvents,
433 apiAddedLinkEvents,
434 apiRemovedLinkEvents,
435 apiAddedDeviceEvents,
436 apiRemovedDeviceEvents);
437 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800438
Ray Milkey269ffb92014-04-03 14:43:30 -0700439 //
440 // Cleanup
441 //
442 apiAddedSwitchEvents.clear();
443 apiRemovedSwitchEvents.clear();
444 apiAddedPortEvents.clear();
445 apiRemovedPortEvents.clear();
446 apiAddedLinkEvents.clear();
447 apiRemovedLinkEvents.clear();
448 apiAddedDeviceEvents.clear();
449 apiRemovedDeviceEvents.clear();
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800450 }
451
452 /**
453 * Apply reordered events.
454 *
455 * @param hasAddedSwitchEvents true if there were Added Switch Events.
Ray Milkey269ffb92014-04-03 14:43:30 -0700456 * @param hasAddedPortEvents true if there were Added Port Events.
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800457 */
458 private void applyReorderedEvents(boolean hasAddedSwitchEvents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700459 boolean hasAddedPortEvents) {
Ray Milkeyb29e6262014-04-09 16:02:14 -0700460 if (!(hasAddedSwitchEvents || hasAddedPortEvents)) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700461 return; // Nothing to do
Ray Milkeyb29e6262014-04-09 16:02:14 -0700462 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800463
Ray Milkey269ffb92014-04-03 14:43:30 -0700464 //
465 // Try to apply the reordered events.
466 //
467 // NOTE: For simplicity we try to apply all events of a particular
468 // type if any "parent" type event was processed:
469 // - Apply reordered Port Events if Switches were added
470 // - Apply reordered Link and Device Events if Switches or Ports
471 // were added
472 //
adminbc181552014-02-21 18:36:42 -0800473
Ray Milkey269ffb92014-04-03 14:43:30 -0700474 //
475 // Apply reordered Port Events if Switches were added
476 //
477 if (hasAddedSwitchEvents) {
478 Map<ByteBuffer, PortEvent> portEvents = reorderedAddedPortEvents;
479 reorderedAddedPortEvents = new HashMap<>();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700480 for (PortEvent portEvent : portEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700481 addPort(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700482 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700483 }
484 //
485 // Apply reordered Link and Device Events if Switches or Ports
486 // were added.
487 //
488 Map<ByteBuffer, LinkEvent> linkEvents = reorderedAddedLinkEvents;
489 reorderedAddedLinkEvents = new HashMap<>();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700490 for (LinkEvent linkEvent : linkEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700491 addLink(linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700492 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700493 //
494 Map<ByteBuffer, DeviceEvent> deviceEvents = reorderedAddedDeviceEvents;
495 reorderedAddedDeviceEvents = new HashMap<>();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700496 for (DeviceEvent deviceEvent : deviceEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700497 addDevice(deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700498 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800499 }
500
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800501 /**
502 * Switch discovered event.
503 *
504 * @param switchEvent the switch event.
Ray Milkey269ffb92014-04-03 14:43:30 -0700505 * @param portEvents the corresponding port events for the switch.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800506 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800507 @Override
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800508 public void putSwitchDiscoveryEvent(SwitchEvent switchEvent,
Ray Milkey269ffb92014-04-03 14:43:30 -0700509 Collection<PortEvent> portEvents) {
510 if (datastore.addSwitch(switchEvent, portEvents)) {
511 // Send out notification
512 TopologyEvent topologyEvent = new TopologyEvent(switchEvent);
513 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800514
Ray Milkey269ffb92014-04-03 14:43:30 -0700515 // Send out notification for each port
516 for (PortEvent portEvent : portEvents) {
517 topologyEvent = new TopologyEvent(portEvent);
518 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
519 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800520
Ray Milkey269ffb92014-04-03 14:43:30 -0700521 //
522 // Keep track of the added ports
523 //
524 // Get the old Port Events
525 Map<ByteBuffer, PortEvent> oldPortEvents =
526 discoveredAddedPortEvents.get(switchEvent.getDpid());
Ray Milkeyb29e6262014-04-09 16:02:14 -0700527 if (oldPortEvents == null) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700528 oldPortEvents = new HashMap<>();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700529 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800530
Ray Milkey269ffb92014-04-03 14:43:30 -0700531 // Store the new Port Events in the local cache
532 Map<ByteBuffer, PortEvent> newPortEvents = new HashMap<>();
533 for (PortEvent portEvent : portEvents) {
534 ByteBuffer id = portEvent.getIDasByteBuffer();
535 newPortEvents.put(id, portEvent);
536 }
537 discoveredAddedPortEvents.put(switchEvent.getDpid(),
538 newPortEvents);
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800539
Ray Milkey269ffb92014-04-03 14:43:30 -0700540 //
541 // Extract the removed ports
542 //
543 List<PortEvent> removedPortEvents = new LinkedList<>();
544 for (Map.Entry<ByteBuffer, PortEvent> entry : oldPortEvents.entrySet()) {
545 ByteBuffer key = entry.getKey();
546 PortEvent portEvent = entry.getValue();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700547 if (!newPortEvents.containsKey(key)) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700548 removedPortEvents.add(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700549 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700550 }
551
552 // Cleanup old removed ports
Ray Milkeyb29e6262014-04-09 16:02:14 -0700553 for (PortEvent portEvent : removedPortEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700554 removePortDiscoveryEvent(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700555 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700556 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800557 }
558
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800559 /**
560 * Switch removed event.
561 *
562 * @param switchEvent the switch event.
563 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800564 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800565 public void removeSwitchDiscoveryEvent(SwitchEvent switchEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700566 // Get the old Port Events
567 Map<ByteBuffer, PortEvent> oldPortEvents =
568 discoveredAddedPortEvents.get(switchEvent.getDpid());
Ray Milkeyb29e6262014-04-09 16:02:14 -0700569 if (oldPortEvents == null) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700570 oldPortEvents = new HashMap<>();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700571 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800572
Ray Milkey269ffb92014-04-03 14:43:30 -0700573 if (datastore.deactivateSwitch(switchEvent, oldPortEvents.values())) {
574 // Send out notification
575 eventChannel.removeEntry(switchEvent.getID());
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800576
Ray Milkey269ffb92014-04-03 14:43:30 -0700577 //
578 // Send out notification for each port.
579 //
580 // NOTE: We don't use removePortDiscoveryEvent() for the cleanup,
581 // because it will attempt to remove the port from the database,
582 // and the deactiveSwitch() call above already removed all ports.
583 //
Ray Milkeyb29e6262014-04-09 16:02:14 -0700584 for (PortEvent portEvent : oldPortEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700585 eventChannel.removeEntry(portEvent.getID());
Ray Milkeyb29e6262014-04-09 16:02:14 -0700586 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700587 discoveredAddedPortEvents.remove(switchEvent.getDpid());
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800588
Ray Milkey269ffb92014-04-03 14:43:30 -0700589 // Cleanup for each link
590 Map<ByteBuffer, LinkEvent> oldLinkEvents =
591 discoveredAddedLinkEvents.get(switchEvent.getDpid());
592 if (oldLinkEvents != null) {
593 for (LinkEvent linkEvent : new ArrayList<>(oldLinkEvents.values())) {
594 removeLinkDiscoveryEvent(linkEvent);
595 }
596 discoveredAddedLinkEvents.remove(switchEvent.getDpid());
597 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800598
Ray Milkey269ffb92014-04-03 14:43:30 -0700599 // Cleanup for each device
600 Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
601 discoveredAddedDeviceEvents.get(switchEvent.getDpid());
602 if (oldDeviceEvents != null) {
603 for (DeviceEvent deviceEvent : new ArrayList<>(oldDeviceEvents.values())) {
604 removeDeviceDiscoveryEvent(deviceEvent);
605 }
606 discoveredAddedDeviceEvents.remove(switchEvent.getDpid());
607 }
608 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800609 }
610
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800611 /**
612 * Port discovered event.
613 *
614 * @param portEvent the port event.
615 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800616 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800617 public void putPortDiscoveryEvent(PortEvent portEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700618 if (datastore.addPort(portEvent)) {
619 // Send out notification
620 TopologyEvent topologyEvent = new TopologyEvent(portEvent);
621 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800622
Ray Milkey269ffb92014-04-03 14:43:30 -0700623 // Store the new Port Event in the local cache
624 Map<ByteBuffer, PortEvent> oldPortEvents =
625 discoveredAddedPortEvents.get(portEvent.getDpid());
626 if (oldPortEvents == null) {
627 oldPortEvents = new HashMap<>();
628 discoveredAddedPortEvents.put(portEvent.getDpid(),
629 oldPortEvents);
630 }
631 ByteBuffer id = portEvent.getIDasByteBuffer();
632 oldPortEvents.put(id, portEvent);
633 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800634 }
635
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800636 /**
637 * Port removed event.
638 *
639 * @param portEvent the port event.
640 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800641 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800642 public void removePortDiscoveryEvent(PortEvent portEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700643 if (datastore.deactivatePort(portEvent)) {
644 // Send out notification
645 eventChannel.removeEntry(portEvent.getID());
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800646
Ray Milkey269ffb92014-04-03 14:43:30 -0700647 // Cleanup the Port Event from the local cache
648 Map<ByteBuffer, PortEvent> oldPortEvents =
649 discoveredAddedPortEvents.get(portEvent.getDpid());
650 if (oldPortEvents != null) {
651 ByteBuffer id = portEvent.getIDasByteBuffer();
652 oldPortEvents.remove(id);
653 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800654
Ray Milkey269ffb92014-04-03 14:43:30 -0700655 // Cleanup for the incoming link
656 Map<ByteBuffer, LinkEvent> oldLinkEvents =
657 discoveredAddedLinkEvents.get(portEvent.getDpid());
658 if (oldLinkEvents != null) {
659 for (LinkEvent linkEvent : new ArrayList<>(oldLinkEvents.values())) {
660 if (linkEvent.getDst().equals(portEvent.id)) {
661 removeLinkDiscoveryEvent(linkEvent);
662 // XXX If we change our model to allow multiple Link on
663 // a Port, this loop must be fixed to allow continuing.
664 break;
665 }
666 }
667 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800668
Ray Milkey269ffb92014-04-03 14:43:30 -0700669 // Cleanup for the connected devices
670 // TODO: The implementation below is probably wrong
671 List<DeviceEvent> removedDeviceEvents = new LinkedList<>();
672 Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
673 discoveredAddedDeviceEvents.get(portEvent.getDpid());
674 if (oldDeviceEvents != null) {
675 for (DeviceEvent deviceEvent : new ArrayList<>(oldDeviceEvents.values())) {
676 for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
677 if (swp.equals(portEvent.id)) {
678 removedDeviceEvents.add(deviceEvent);
679 }
680 }
681 }
Ray Milkeyb29e6262014-04-09 16:02:14 -0700682 for (DeviceEvent deviceEvent : removedDeviceEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700683 removeDeviceDiscoveryEvent(deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700684 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700685 }
686 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800687 }
688
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800689 /**
690 * Link discovered event.
691 *
692 * @param linkEvent the link event.
693 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800694 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800695 public void putLinkDiscoveryEvent(LinkEvent linkEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700696 if (datastore.addLink(linkEvent)) {
697 // Send out notification
698 TopologyEvent topologyEvent = new TopologyEvent(linkEvent);
699 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800700
Ray Milkey269ffb92014-04-03 14:43:30 -0700701 // Store the new Link Event in the local cache
702 Map<ByteBuffer, LinkEvent> oldLinkEvents =
703 discoveredAddedLinkEvents.get(linkEvent.getDst().getDpid());
704 if (oldLinkEvents == null) {
705 oldLinkEvents = new HashMap<>();
706 discoveredAddedLinkEvents.put(linkEvent.getDst().getDpid(),
707 oldLinkEvents);
708 }
709 ByteBuffer id = linkEvent.getIDasByteBuffer();
710 oldLinkEvents.put(id, linkEvent);
711 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800712 }
713
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800714 /**
715 * Link removed event.
716 *
717 * @param linkEvent the link event.
718 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800719 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800720 public void removeLinkDiscoveryEvent(LinkEvent linkEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700721 if (datastore.removeLink(linkEvent)) {
722 // Send out notification
723 eventChannel.removeEntry(linkEvent.getID());
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800724
Ray Milkey269ffb92014-04-03 14:43:30 -0700725 // Cleanup the Link Event from the local cache
726 Map<ByteBuffer, LinkEvent> oldLinkEvents =
727 discoveredAddedLinkEvents.get(linkEvent.getDst().getDpid());
728 if (oldLinkEvents != null) {
729 ByteBuffer id = linkEvent.getIDasByteBuffer();
730 oldLinkEvents.remove(id);
731 }
732 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800733 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800734
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800735 /**
736 * Device discovered event.
737 *
738 * @param deviceEvent the device event.
739 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800740 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800741 public void putDeviceDiscoveryEvent(DeviceEvent deviceEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700742 if (datastore.addDevice(deviceEvent)) {
743 // Send out notification
744 TopologyEvent topologyEvent = new TopologyEvent(deviceEvent);
745 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
746 log.debug("Put the device info into the cache of the graph. mac {}", deviceEvent.getMac());
747
748 // Store the new Device Event in the local cache
749 // TODO: The implementation below is probably wrong
750 for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
751 Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
752 discoveredAddedDeviceEvents.get(swp.getDpid());
753 if (oldDeviceEvents == null) {
754 oldDeviceEvents = new HashMap<>();
755 discoveredAddedDeviceEvents.put(swp.getDpid(),
756 oldDeviceEvents);
757 }
758 ByteBuffer id = deviceEvent.getIDasByteBuffer();
759 oldDeviceEvents.put(id, deviceEvent);
760 }
761 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800762 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800763
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800764 /**
765 * Device removed event.
766 *
767 * @param deviceEvent the device event.
768 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800769 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800770 public void removeDeviceDiscoveryEvent(DeviceEvent deviceEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700771 if (datastore.removeDevice(deviceEvent)) {
772 // Send out notification
773 eventChannel.removeEntry(deviceEvent.getID());
774 log.debug("Remove the device info into the cache of the graph. mac {}", deviceEvent.getMac());
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800775
Ray Milkey269ffb92014-04-03 14:43:30 -0700776 // Cleanup the Device Event from the local cache
777 // TODO: The implementation below is probably wrong
778 ByteBuffer id = ByteBuffer.wrap(deviceEvent.getID());
779 for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
780 Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
781 discoveredAddedDeviceEvents.get(swp.getDpid());
782 if (oldDeviceEvents != null) {
783 oldDeviceEvents.remove(id);
784 }
785 }
786 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800787 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800788
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800789 /**
790 * Add a switch to the Network Graph.
791 *
792 * @param switchEvent the Switch Event with the switch to add.
793 */
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800794 private void addSwitch(SwitchEvent switchEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700795 Switch sw = networkGraph.getSwitch(switchEvent.getDpid());
796 if (sw == null) {
797 sw = new SwitchImpl(networkGraph, switchEvent.getDpid());
798 networkGraph.putSwitch(sw);
799 } else {
800 // TODO: Update the switch attributes
801 // TODO: Nothing to do for now
Ray Milkey1aa71f82014-04-08 16:23:24 -0700802 log.debug("Update switch attributes");
Ray Milkey269ffb92014-04-03 14:43:30 -0700803 }
804 apiAddedSwitchEvents.add(switchEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800805 }
806
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800807 /**
808 * Remove a switch from the Network Graph.
809 *
810 * @param switchEvent the Switch Event with the switch to remove.
811 */
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800812 private void removeSwitch(SwitchEvent switchEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700813 Switch sw = networkGraph.getSwitch(switchEvent.getDpid());
814 if (sw == null) {
815 log.warn("Switch {} already removed, ignoring", switchEvent);
816 return;
817 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800818
Ray Milkey269ffb92014-04-03 14:43:30 -0700819 //
820 // Remove all Ports on the Switch
821 //
822 ArrayList<PortEvent> portsToRemove = new ArrayList<>();
823 for (Port port : sw.getPorts()) {
824 log.warn("Port {} on Switch {} should be removed prior to removing Switch. Removing Port now.",
825 port, switchEvent);
826 PortEvent portEvent = new PortEvent(port.getDpid(),
827 port.getNumber());
828 portsToRemove.add(portEvent);
829 }
Ray Milkeyb29e6262014-04-09 16:02:14 -0700830 for (PortEvent portEvent : portsToRemove) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700831 removePort(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700832 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800833
Ray Milkey269ffb92014-04-03 14:43:30 -0700834 networkGraph.removeSwitch(switchEvent.getDpid());
835 apiRemovedSwitchEvents.add(switchEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800836 }
837
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800838 /**
839 * Add a port to the Network Graph.
840 *
841 * @param portEvent the Port Event with the port to add.
842 */
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800843 private void addPort(PortEvent portEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700844 Switch sw = networkGraph.getSwitch(portEvent.getDpid());
845 if (sw == null) {
846 // Reordered event: delay the event in local cache
847 ByteBuffer id = portEvent.getIDasByteBuffer();
848 reorderedAddedPortEvents.put(id, portEvent);
849 return;
850 }
851 SwitchImpl switchImpl = getSwitchImpl(sw);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800852
Ray Milkey269ffb92014-04-03 14:43:30 -0700853 Port port = sw.getPort(portEvent.getNumber());
854 if (port == null) {
855 port = new PortImpl(networkGraph, sw, portEvent.getNumber());
856 switchImpl.addPort(port);
857 } else {
858 // TODO: Update the port attributes
Ray Milkey1aa71f82014-04-08 16:23:24 -0700859 log.debug("Update port attributes");
Ray Milkey269ffb92014-04-03 14:43:30 -0700860 }
861 apiAddedPortEvents.add(portEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800862 }
863
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800864 /**
865 * Remove a port from the Network Graph.
866 *
867 * @param portEvent the Port Event with the port to remove.
868 */
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800869 private void removePort(PortEvent portEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700870 Switch sw = networkGraph.getSwitch(portEvent.getDpid());
871 if (sw == null) {
872 log.warn("Parent Switch for Port {} already removed, ignoring",
873 portEvent);
874 return;
875 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800876
Ray Milkey269ffb92014-04-03 14:43:30 -0700877 Port port = sw.getPort(portEvent.getNumber());
878 if (port == null) {
879 log.warn("Port {} already removed, ignoring", portEvent);
880 return;
881 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800882
Ray Milkey269ffb92014-04-03 14:43:30 -0700883 //
884 // Remove all Devices attached to the Port
885 //
886 ArrayList<DeviceEvent> devicesToRemove = new ArrayList<>();
887 for (Device device : port.getDevices()) {
888 log.debug("Removing Device {} on Port {}", device, portEvent);
889 DeviceEvent deviceEvent = new DeviceEvent(device.getMacAddress());
890 SwitchPort switchPort = new SwitchPort(port.getSwitch().getDpid(),
891 port.getNumber());
892 deviceEvent.addAttachmentPoint(switchPort);
893 devicesToRemove.add(deviceEvent);
894 }
Ray Milkeyb29e6262014-04-09 16:02:14 -0700895 for (DeviceEvent deviceEvent : devicesToRemove) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700896 removeDevice(deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700897 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800898
Ray Milkey269ffb92014-04-03 14:43:30 -0700899 //
900 // Remove all Links connected to the Port
901 //
902 Set<Link> links = new HashSet<>();
903 links.add(port.getOutgoingLink());
904 links.add(port.getIncomingLink());
905 ArrayList<LinkEvent> linksToRemove = new ArrayList<>();
906 for (Link link : links) {
Ray Milkeyb29e6262014-04-09 16:02:14 -0700907 if (link == null) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700908 continue;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700909 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700910 log.debug("Removing Link {} on Port {}", link, portEvent);
911 LinkEvent linkEvent = new LinkEvent(link.getSrcSwitch().getDpid(),
912 link.getSrcPort().getNumber(),
913 link.getDstSwitch().getDpid(),
914 link.getDstPort().getNumber());
915 linksToRemove.add(linkEvent);
916 }
Ray Milkeyb29e6262014-04-09 16:02:14 -0700917 for (LinkEvent linkEvent : linksToRemove) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700918 removeLink(linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700919 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800920
Ray Milkey269ffb92014-04-03 14:43:30 -0700921 // Remove the Port from the Switch
922 SwitchImpl switchImpl = getSwitchImpl(sw);
923 switchImpl.removePort(port);
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800924
Ray Milkey269ffb92014-04-03 14:43:30 -0700925 apiRemovedPortEvents.add(portEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800926 }
927
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800928 /**
929 * Add a link to the Network Graph.
930 *
931 * @param linkEvent the Link Event with the link to add.
932 */
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800933 private void addLink(LinkEvent linkEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700934 Port srcPort = networkGraph.getPort(linkEvent.getSrc().dpid,
935 linkEvent.getSrc().number);
936 Port dstPort = networkGraph.getPort(linkEvent.getDst().dpid,
937 linkEvent.getDst().number);
938 if ((srcPort == null) || (dstPort == null)) {
939 // Reordered event: delay the event in local cache
940 ByteBuffer id = linkEvent.getIDasByteBuffer();
941 reorderedAddedLinkEvents.put(id, linkEvent);
942 return;
943 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800944
Ray Milkey269ffb92014-04-03 14:43:30 -0700945 // Get the Link instance from the Destination Port Incoming Link
946 Link link = dstPort.getIncomingLink();
947 assert (link == srcPort.getOutgoingLink());
948 if (link == null) {
949 link = new LinkImpl(networkGraph, srcPort, dstPort);
950 PortImpl srcPortImpl = getPortImpl(srcPort);
951 PortImpl dstPortImpl = getPortImpl(dstPort);
952 srcPortImpl.setOutgoingLink(link);
953 dstPortImpl.setIncomingLink(link);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800954
Ray Milkey269ffb92014-04-03 14:43:30 -0700955 // Remove all Devices attached to the Ports
956 ArrayList<DeviceEvent> devicesToRemove = new ArrayList<>();
957 ArrayList<Port> ports = new ArrayList<>();
958 ports.add(srcPort);
959 ports.add(dstPort);
960 for (Port port : ports) {
961 for (Device device : port.getDevices()) {
962 log.error("Device {} on Port {} should have been removed prior to adding Link {}",
963 device, port, linkEvent);
964 DeviceEvent deviceEvent =
965 new DeviceEvent(device.getMacAddress());
966 SwitchPort switchPort =
967 new SwitchPort(port.getSwitch().getDpid(),
968 port.getNumber());
969 deviceEvent.addAttachmentPoint(switchPort);
970 devicesToRemove.add(deviceEvent);
971 }
972 }
Ray Milkeyb29e6262014-04-09 16:02:14 -0700973 for (DeviceEvent deviceEvent : devicesToRemove) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700974 removeDevice(deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700975 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700976 } else {
977 // TODO: Update the link attributes
Ray Milkey1aa71f82014-04-08 16:23:24 -0700978 log.debug("Update link attributes");
Ray Milkey269ffb92014-04-03 14:43:30 -0700979 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800980
Ray Milkey269ffb92014-04-03 14:43:30 -0700981 apiAddedLinkEvents.add(linkEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800982 }
983
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800984 /**
985 * Remove a link from the Network Graph.
986 *
987 * @param linkEvent the Link Event with the link to remove.
988 */
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800989 private void removeLink(LinkEvent linkEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700990 Port srcPort = networkGraph.getPort(linkEvent.getSrc().dpid,
991 linkEvent.getSrc().number);
992 if (srcPort == null) {
993 log.warn("Src Port for Link {} already removed, ignoring",
994 linkEvent);
995 return;
996 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800997
Ray Milkey269ffb92014-04-03 14:43:30 -0700998 Port dstPort = networkGraph.getPort(linkEvent.getDst().dpid,
999 linkEvent.getDst().number);
1000 if (dstPort == null) {
1001 log.warn("Dst Port for Link {} already removed, ignoring",
1002 linkEvent);
1003 return;
1004 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001005
Ray Milkey269ffb92014-04-03 14:43:30 -07001006 //
1007 // Remove the Link instance from the Destination Port Incoming Link
1008 // and the Source Port Outgoing Link.
1009 //
1010 Link link = dstPort.getIncomingLink();
1011 if (link == null) {
1012 log.warn("Link {} already removed on destination Port", linkEvent);
1013 }
1014 link = srcPort.getOutgoingLink();
1015 if (link == null) {
1016 log.warn("Link {} already removed on src Port", linkEvent);
1017 }
1018 getPortImpl(dstPort).setIncomingLink(null);
1019 getPortImpl(srcPort).setOutgoingLink(null);
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -08001020
Ray Milkey269ffb92014-04-03 14:43:30 -07001021 apiRemovedLinkEvents.add(linkEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001022 }
1023
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001024 /**
1025 * Add a device to the Network Graph.
Ray Milkey269ffb92014-04-03 14:43:30 -07001026 * <p/>
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001027 * TODO: Device-related work is incomplete.
1028 * TODO: Eventually, we might need to consider reordering
1029 * or addLink() and addDevice() events on the same port.
1030 *
1031 * @param deviceEvent the Device Event with the device to add.
1032 */
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001033 private void addDevice(DeviceEvent deviceEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -07001034 Device device = networkGraph.getDeviceByMac(deviceEvent.getMac());
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001035
Ray Milkey269ffb92014-04-03 14:43:30 -07001036 if (device == null) {
1037 log.debug("Existing device was not found in networkGraph. New device. mac {}", deviceEvent.getMac());
1038 device = new DeviceImpl(networkGraph, deviceEvent.getMac());
1039 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001040
Ray Milkey269ffb92014-04-03 14:43:30 -07001041 DeviceImpl deviceImpl = getDeviceImpl(device);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001042
Ray Milkey269ffb92014-04-03 14:43:30 -07001043 // Update the IP addresses
Ray Milkeyb29e6262014-04-09 16:02:14 -07001044 for (InetAddress ipAddr : deviceEvent.getIpAddresses()) {
Ray Milkey269ffb92014-04-03 14:43:30 -07001045 deviceImpl.addIpAddress(ipAddr);
Ray Milkeyb29e6262014-04-09 16:02:14 -07001046 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001047
Ray Milkey269ffb92014-04-03 14:43:30 -07001048 // Process each attachment point
1049 boolean attachmentFound = false;
1050 for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
1051 // Attached Ports must exist
1052 Port port = networkGraph.getPort(swp.dpid, swp.number);
1053 if (port == null) {
1054 // Reordered event: delay the event in local cache
1055 ByteBuffer id = deviceEvent.getIDasByteBuffer();
1056 reorderedAddedDeviceEvents.put(id, deviceEvent);
1057 continue;
1058 }
1059 // Attached Ports must not have Link
1060 if (port.getOutgoingLink() != null ||
1061 port.getIncomingLink() != null) {
1062 log.warn("Link (Out:{},In:{}) exist on the attachment point, skipping mutation.",
1063 port.getOutgoingLink(),
1064 port.getIncomingLink());
1065 continue;
1066 }
1067
1068 // Add Device <-> Port attachment
1069 PortImpl portImpl = getPortImpl(port);
1070 portImpl.addDevice(device);
1071 deviceImpl.addAttachmentPoint(port);
1072 attachmentFound = true;
1073 }
1074
1075 // Update the device in the Network Graph
1076 if (attachmentFound) {
1077 log.debug("Storing the info into networkGraph. mac {}", deviceEvent.getMac());
1078 networkGraph.putDevice(device);
1079 apiAddedDeviceEvents.add(deviceEvent);
1080 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001081 }
1082
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001083 /**
1084 * Remove a device from the Network Graph.
Ray Milkey269ffb92014-04-03 14:43:30 -07001085 * <p/>
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001086 * TODO: Device-related work is incomplete.
1087 *
1088 * @param deviceEvent the Device Event with the device to remove.
1089 */
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001090 private void removeDevice(DeviceEvent deviceEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -07001091 Device device = networkGraph.getDeviceByMac(deviceEvent.getMac());
1092 if (device == null) {
1093 log.warn("Device {} already removed, ignoring", deviceEvent);
1094 return;
1095 }
1096 DeviceImpl deviceImpl = getDeviceImpl(device);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001097
Ray Milkey269ffb92014-04-03 14:43:30 -07001098 // Process each attachment point
1099 for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
1100 // Attached Ports must exist
1101 Port port = networkGraph.getPort(swp.dpid, swp.number);
1102 if (port == null) {
1103 log.warn("Port for the attachment point {} did not exist. skipping attachment point mutation", swp);
1104 continue;
1105 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001106
Ray Milkey269ffb92014-04-03 14:43:30 -07001107 // Remove Device <-> Port attachment
1108 PortImpl portImpl = getPortImpl(port);
1109 portImpl.removeDevice(device);
1110 deviceImpl.removeAttachmentPoint(port);
1111 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -08001112
Ray Milkey269ffb92014-04-03 14:43:30 -07001113 networkGraph.removeDevice(device);
1114 apiRemovedDeviceEvents.add(deviceEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001115 }
Jonathan Hart22eb9882014-02-11 15:52:59 -08001116
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001117 /**
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001118 * Get the SwitchImpl-casted switch implementation.
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001119 *
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001120 * @param sw the Switch to cast.
1121 * @return the SwitchImpl-casted switch implementation.
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001122 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001123 private SwitchImpl getSwitchImpl(Switch sw) {
Ray Milkey269ffb92014-04-03 14:43:30 -07001124 if (sw instanceof SwitchImpl) {
1125 return (SwitchImpl) sw;
1126 }
1127 throw new ClassCastException("SwitchImpl expected, but found: " + sw);
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001128 }
1129
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001130 /**
1131 * Get the PortImpl-casted port implementation.
1132 *
1133 * @param port the Port to cast.
1134 * @return the PortImpl-casted port implementation.
1135 */
1136 private PortImpl getPortImpl(Port port) {
Ray Milkey269ffb92014-04-03 14:43:30 -07001137 if (port instanceof PortImpl) {
1138 return (PortImpl) port;
1139 }
1140 throw new ClassCastException("PortImpl expected, but found: " + port);
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001141 }
1142
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001143 /**
1144 * Get the LinkImpl-casted link implementation.
1145 *
1146 * @param link the Link to cast.
1147 * @return the LinkImpl-casted link implementation.
1148 */
1149 private LinkImpl getLinkImpl(Link link) {
Ray Milkey269ffb92014-04-03 14:43:30 -07001150 if (link instanceof LinkImpl) {
1151 return (LinkImpl) link;
1152 }
1153 throw new ClassCastException("LinkImpl expected, but found: " + link);
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001154 }
1155
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001156 /**
1157 * Get the DeviceImpl-casted device implementation.
1158 *
1159 * @param device the Device to cast.
1160 * @return the DeviceImpl-casted device implementation.
1161 */
1162 private DeviceImpl getDeviceImpl(Device device) {
Ray Milkey269ffb92014-04-03 14:43:30 -07001163 if (device instanceof DeviceImpl) {
1164 return (DeviceImpl) device;
1165 }
1166 throw new ClassCastException("DeviceImpl expected, but found: " + device);
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001167 }
1168
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001169 /**
1170 * Read the whole topology from the database.
1171 *
1172 * @return a collection of EventEntry-encapsulated Topology Events for
1173 * the whole topology.
1174 */
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001175 private Collection<EventEntry<TopologyEvent>> readWholeTopologyFromDB() {
Ray Milkey269ffb92014-04-03 14:43:30 -07001176 Collection<EventEntry<TopologyEvent>> collection =
1177 new LinkedList<EventEntry<TopologyEvent>>();
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001178
Ray Milkey269ffb92014-04-03 14:43:30 -07001179 // XXX May need to clear whole topology first, depending on
1180 // how we initially subscribe to replication events
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001181
Ray Milkey269ffb92014-04-03 14:43:30 -07001182 // Add all active switches
1183 for (KVSwitch sw : KVSwitch.getAllSwitches()) {
1184 if (sw.getStatus() != KVSwitch.STATUS.ACTIVE) {
1185 continue;
1186 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001187
Ray Milkey269ffb92014-04-03 14:43:30 -07001188 SwitchEvent switchEvent = new SwitchEvent(sw.getDpid());
1189 TopologyEvent topologyEvent = new TopologyEvent(switchEvent);
1190 EventEntry<TopologyEvent> eventEntry =
1191 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
1192 topologyEvent);
1193 collection.add(eventEntry);
1194 }
Yuta HIGUCHIa536e762014-02-17 21:47:28 -08001195
Ray Milkey269ffb92014-04-03 14:43:30 -07001196 // Add all active ports
1197 for (KVPort p : KVPort.getAllPorts()) {
1198 if (p.getStatus() != KVPort.STATUS.ACTIVE) {
1199 continue;
1200 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001201
Ray Milkey269ffb92014-04-03 14:43:30 -07001202 PortEvent portEvent = new PortEvent(p.getDpid(), p.getNumber());
1203 TopologyEvent topologyEvent = new TopologyEvent(portEvent);
1204 EventEntry<TopologyEvent> eventEntry =
1205 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
1206 topologyEvent);
1207 collection.add(eventEntry);
1208 }
Yuta HIGUCHIa536e762014-02-17 21:47:28 -08001209
Ray Milkey269ffb92014-04-03 14:43:30 -07001210 // TODO Is Device going to be in DB? If so, read from DB.
1211 // for (KVDevice d : KVDevice.getAllDevices()) {
1212 // DeviceEvent devEvent = new DeviceEvent( MACAddress.valueOf(d.getMac()) );
1213 // for (byte[] portId : d.getAllPortIds() ) {
1214 // devEvent.addAttachmentPoint( new SwitchPort( KVPort.getDpidFromKey(portId), KVPort.getNumberFromKey(portId) ));
1215 // }
1216 // }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001217
Ray Milkey269ffb92014-04-03 14:43:30 -07001218 for (KVLink l : KVLink.getAllLinks()) {
1219 LinkEvent linkEvent = new LinkEvent(l.getSrc().dpid,
1220 l.getSrc().number,
1221 l.getDst().dpid,
1222 l.getDst().number);
1223 TopologyEvent topologyEvent = new TopologyEvent(linkEvent);
1224 EventEntry<TopologyEvent> eventEntry =
1225 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
1226 topologyEvent);
1227 collection.add(eventEntry);
1228 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001229
Ray Milkey269ffb92014-04-03 14:43:30 -07001230 return collection;
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001231 }
Jonathan Hart062a2e82014-02-03 09:41:57 -08001232}