blob: 67e8e5da2818444d7539c74697d430fb4c12ca88 [file] [log] [blame]
Jonathan Hart472062d2014-04-03 10:56:48 -07001package net.onrc.onos.core.topology;
Jonathan Hart062a2e82014-02-03 09:41:57 -08002
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08003import java.nio.ByteBuffer;
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -08004import java.util.ArrayList;
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -08005import java.util.Collection;
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08006import java.util.HashMap;
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -08007import java.util.HashSet;
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -08008import java.util.LinkedList;
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -08009import java.util.List;
Pavlin Radoslavov018d5332014-02-19 23:08:35 -080010import java.util.Map;
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -080011import java.util.Set;
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080012import java.util.concurrent.BlockingQueue;
Yuta HIGUCHIa536e762014-02-17 21:47:28 -080013import java.util.concurrent.CopyOnWriteArrayList;
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080014import java.util.concurrent.LinkedBlockingQueue;
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -080015
TeruU28adcc32014-04-15 17:57:35 -070016import net.floodlightcontroller.util.MACAddress;
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;
TeruU28adcc32014-04-15 17:57:35 -070020import net.onrc.onos.core.datastore.topology.KVDevice;
Jonathan Hart6df90172014-04-03 10:13:11 -070021import net.onrc.onos.core.datastore.topology.KVLink;
22import net.onrc.onos.core.datastore.topology.KVPort;
23import net.onrc.onos.core.datastore.topology.KVSwitch;
Jonathan Hartdeda0ba2014-04-03 11:14:12 -070024import net.onrc.onos.core.registry.IControllerRegistryService;
Jonathan Hart472062d2014-04-03 10:56:48 -070025import net.onrc.onos.core.topology.PortEvent.SwitchPort;
Jonathan Hart23701d12014-04-03 10:45:48 -070026import net.onrc.onos.core.util.EventEntry;
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.
Ray Milkey269ffb92014-04-03 14:43:30 -070033 * <p/>
Yuta HIGUCHI4bfdd532014-02-07 13:47:36 -080034 * - Maintain Invariant/Relationships between Topology Objects.
Ray Milkey269ffb92014-04-03 14:43:30 -070035 * <p/>
Yuta HIGUCHI765cd0d2014-02-06 12:46:41 -080036 * TODO To be synchronized based on TopologyEvent Notification.
Ray Milkey269ffb92014-04-03 14:43:30 -070037 * <p/>
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).
Ray Milkey269ffb92014-04-03 14:43:30 -070040 * <p/>
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 HIGUCHI181d34d2014-02-05 15:05:46 -080043 */
Pavlin Radoslavov87dcc262014-02-19 21:13:23 -080044public class TopologyManager implements NetworkGraphDiscoveryInterface {
Jonathan Hart062a2e82014-02-03 09:41:57 -080045
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080046 private static final Logger log = LoggerFactory
Ray Milkey269ffb92014-04-03 14:43:30 -070047 .getLogger(TopologyManager.class);
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -080048
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080049 private IEventChannel<byte[], TopologyEvent> eventChannel;
Jonathan Hart10a7e2b2014-02-21 18:30:08 -080050 public static final String EVENT_CHANNEL_NAME = "onos.topology";
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080051 private EventHandler eventHandler = new EventHandler();
52
Jonathan Hart22eb9882014-02-11 15:52:59 -080053 private final NetworkGraphDatastore datastore;
Pavlin Radoslavov6d224ee2014-02-18 16:43:15 -080054 private final NetworkGraphImpl networkGraph = new NetworkGraphImpl();
Yuta HIGUCHI170229f2014-02-17 15:47:54 -080055 private final IControllerRegistryService registryService;
Yuta HIGUCHIa536e762014-02-17 21:47:28 -080056 private CopyOnWriteArrayList<INetworkGraphListener> networkGraphListeners;
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -080057
Pavlin Radoslavov706add22014-02-20 12:15:59 -080058 //
59 // Local state for keeping track of reordered events.
60 // NOTE: Switch Events are not affected by the event reordering.
61 //
62 private Map<ByteBuffer, PortEvent> reorderedAddedPortEvents =
Ray Milkey269ffb92014-04-03 14:43:30 -070063 new HashMap<ByteBuffer, PortEvent>();
Pavlin Radoslavov706add22014-02-20 12:15:59 -080064 private Map<ByteBuffer, LinkEvent> reorderedAddedLinkEvents =
Ray Milkey269ffb92014-04-03 14:43:30 -070065 new HashMap<ByteBuffer, LinkEvent>();
Pavlin Radoslavov706add22014-02-20 12:15:59 -080066 private Map<ByteBuffer, DeviceEvent> reorderedAddedDeviceEvents =
Ray Milkey269ffb92014-04-03 14:43:30 -070067 new HashMap<ByteBuffer, DeviceEvent>();
Pavlin Radoslavov018d5332014-02-19 23:08:35 -080068
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -080069 //
Pavlin Radoslavov26d83402014-02-20 15:24:30 -080070 // Local state for keeping track of locally discovered events so we can
71 // cleanup properly when a Switch or Port is removed.
72 //
73 // We keep all Port, Link and Device events per Switch DPID:
74 // - If a switch goes down, we remove all corresponding Port, Link and
75 // Device events.
76 // - If a port on a switch goes down, we remove all corresponding Link
77 // and Device events.
78 //
79 private Map<Long, Map<ByteBuffer, PortEvent>> discoveredAddedPortEvents =
Ray Milkey269ffb92014-04-03 14:43:30 -070080 new HashMap<>();
Pavlin Radoslavov26d83402014-02-20 15:24:30 -080081 private Map<Long, Map<ByteBuffer, LinkEvent>> discoveredAddedLinkEvents =
Ray Milkey269ffb92014-04-03 14:43:30 -070082 new HashMap<>();
Pavlin Radoslavov26d83402014-02-20 15:24:30 -080083 private Map<Long, Map<ByteBuffer, DeviceEvent>> discoveredAddedDeviceEvents =
Ray Milkey269ffb92014-04-03 14:43:30 -070084 new HashMap<>();
Pavlin Radoslavov26d83402014-02-20 15:24:30 -080085
86 //
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -080087 // Local state for keeping track of the application event notifications
88 //
89 List<SwitchEvent> apiAddedSwitchEvents = new LinkedList<SwitchEvent>();
90 List<SwitchEvent> apiRemovedSwitchEvents = new LinkedList<SwitchEvent>();
91 List<PortEvent> apiAddedPortEvents = new LinkedList<PortEvent>();
92 List<PortEvent> apiRemovedPortEvents = new LinkedList<PortEvent>();
93 List<LinkEvent> apiAddedLinkEvents = new LinkedList<LinkEvent>();
94 List<LinkEvent> apiRemovedLinkEvents = new LinkedList<LinkEvent>();
95 List<DeviceEvent> apiAddedDeviceEvents = new LinkedList<DeviceEvent>();
96 List<DeviceEvent> apiRemovedDeviceEvents = new LinkedList<DeviceEvent>();
97
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -080098 /**
99 * Constructor.
100 *
Ray Milkey269ffb92014-04-03 14:43:30 -0700101 * @param registryService the Registry Service to use.
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800102 * @param networkGraphListeners the collection of Network Graph Listeners
Ray Milkey269ffb92014-04-03 14:43:30 -0700103 * to use.
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800104 */
105 public TopologyManager(IControllerRegistryService registryService,
Ray Milkey269ffb92014-04-03 14:43:30 -0700106 CopyOnWriteArrayList<INetworkGraphListener> networkGraphListeners) {
107 datastore = new NetworkGraphDatastore();
108 this.registryService = registryService;
109 this.networkGraphListeners = networkGraphListeners;
Yuta HIGUCHI80829d12014-02-05 20:16:56 -0800110 }
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -0800111
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800112 /**
113 * Get the Network Graph.
114 *
115 * @return the Network Graph.
116 */
Pavlin Radoslavov6d224ee2014-02-18 16:43:15 -0800117 NetworkGraph getNetworkGraph() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700118 return networkGraph;
Pavlin Radoslavov6d224ee2014-02-18 16:43:15 -0800119 }
120
Yuta HIGUCHI4bfdd532014-02-07 13:47:36 -0800121 /**
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800122 * Event handler class.
123 */
124 private class EventHandler extends Thread implements
Ray Milkey269ffb92014-04-03 14:43:30 -0700125 IEventChannelListener<byte[], TopologyEvent> {
126 private BlockingQueue<EventEntry<TopologyEvent>> topologyEvents =
127 new LinkedBlockingQueue<EventEntry<TopologyEvent>>();
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800128
Ray Milkey269ffb92014-04-03 14:43:30 -0700129 /**
130 * Startup processing.
131 */
132 private void startup() {
133 //
134 // TODO: Read all state from the database:
135 //
136 // Collection<EventEntry<TopologyEvent>> collection =
137 // readWholeTopologyFromDB();
138 //
139 // For now, as a shortcut we read it from the datagrid
140 //
Ray Milkey5df613b2014-04-15 10:50:56 -0700141 Collection<TopologyEvent> allTopologyEvents =
Ray Milkey269ffb92014-04-03 14:43:30 -0700142 eventChannel.getAllEntries();
143 Collection<EventEntry<TopologyEvent>> collection =
144 new LinkedList<EventEntry<TopologyEvent>>();
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800145
Ray Milkey5df613b2014-04-15 10:50:56 -0700146 for (TopologyEvent topologyEvent : allTopologyEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700147 EventEntry<TopologyEvent> eventEntry =
148 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
149 topologyEvent);
150 collection.add(eventEntry);
151 }
152 processEvents(collection);
153 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800154
Ray Milkey269ffb92014-04-03 14:43:30 -0700155 /**
156 * Run the thread.
157 */
158 @Override
159 public void run() {
160 Collection<EventEntry<TopologyEvent>> collection =
161 new LinkedList<EventEntry<TopologyEvent>>();
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800162
Ray Milkey269ffb92014-04-03 14:43:30 -0700163 this.setName("TopologyManager.EventHandler " + this.getId());
164 startup();
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800165
Ray Milkey269ffb92014-04-03 14:43:30 -0700166 //
167 // The main loop
168 //
169 try {
170 while (true) {
171 EventEntry<TopologyEvent> eventEntry = topologyEvents.take();
172 collection.add(eventEntry);
173 topologyEvents.drainTo(collection);
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800174
Ray Milkey269ffb92014-04-03 14:43:30 -0700175 processEvents(collection);
176 collection.clear();
177 }
178 } catch (Exception exception) {
179 log.debug("Exception processing Topology Events: ", exception);
180 }
181 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800182
Ray Milkey269ffb92014-04-03 14:43:30 -0700183 /**
184 * Process all topology events.
185 *
186 * @param events the events to process.
187 */
188 private void processEvents(Collection<EventEntry<TopologyEvent>> events) {
189 // Local state for computing the final set of events
190 Map<ByteBuffer, SwitchEvent> addedSwitchEvents = new HashMap<>();
191 Map<ByteBuffer, SwitchEvent> removedSwitchEvents = new HashMap<>();
192 Map<ByteBuffer, PortEvent> addedPortEvents = new HashMap<>();
193 Map<ByteBuffer, PortEvent> removedPortEvents = new HashMap<>();
194 Map<ByteBuffer, LinkEvent> addedLinkEvents = new HashMap<>();
195 Map<ByteBuffer, LinkEvent> removedLinkEvents = new HashMap<>();
196 Map<ByteBuffer, DeviceEvent> addedDeviceEvents = new HashMap<>();
197 Map<ByteBuffer, DeviceEvent> removedDeviceEvents = new HashMap<>();
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800198
Ray Milkey269ffb92014-04-03 14:43:30 -0700199 //
200 // Classify and suppress matching events
201 //
202 for (EventEntry<TopologyEvent> event : events) {
203 TopologyEvent topologyEvent = event.eventData();
204 SwitchEvent switchEvent = topologyEvent.switchEvent;
205 PortEvent portEvent = topologyEvent.portEvent;
206 LinkEvent linkEvent = topologyEvent.linkEvent;
207 DeviceEvent deviceEvent = topologyEvent.deviceEvent;
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800208
Ray Milkey269ffb92014-04-03 14:43:30 -0700209 //
210 // Extract the events
211 //
212 switch (event.eventType()) {
213 case ENTRY_ADD:
214 log.debug("Topology event ENTRY_ADD: {}", topologyEvent);
215 if (switchEvent != null) {
216 ByteBuffer id = switchEvent.getIDasByteBuffer();
217 addedSwitchEvents.put(id, switchEvent);
218 removedSwitchEvents.remove(id);
219 // Switch Events are not affected by event reordering
220 }
221 if (portEvent != null) {
222 ByteBuffer id = portEvent.getIDasByteBuffer();
223 addedPortEvents.put(id, portEvent);
224 removedPortEvents.remove(id);
225 reorderedAddedPortEvents.remove(id);
226 }
227 if (linkEvent != null) {
228 ByteBuffer id = linkEvent.getIDasByteBuffer();
229 addedLinkEvents.put(id, linkEvent);
230 removedLinkEvents.remove(id);
231 reorderedAddedLinkEvents.remove(id);
232 }
233 if (deviceEvent != null) {
234 ByteBuffer id = deviceEvent.getIDasByteBuffer();
235 addedDeviceEvents.put(id, deviceEvent);
236 removedDeviceEvents.remove(id);
237 reorderedAddedDeviceEvents.remove(id);
238 }
239 break;
240 case ENTRY_REMOVE:
241 log.debug("Topology event ENTRY_REMOVE: {}", topologyEvent);
242 if (switchEvent != null) {
243 ByteBuffer id = switchEvent.getIDasByteBuffer();
244 addedSwitchEvents.remove(id);
245 removedSwitchEvents.put(id, switchEvent);
246 // Switch Events are not affected by event reordering
247 }
248 if (portEvent != null) {
249 ByteBuffer id = portEvent.getIDasByteBuffer();
250 addedPortEvents.remove(id);
251 removedPortEvents.put(id, portEvent);
252 reorderedAddedPortEvents.remove(id);
253 }
254 if (linkEvent != null) {
255 ByteBuffer id = linkEvent.getIDasByteBuffer();
256 addedLinkEvents.remove(id);
257 removedLinkEvents.put(id, linkEvent);
258 reorderedAddedLinkEvents.remove(id);
259 }
260 if (deviceEvent != null) {
261 ByteBuffer id = deviceEvent.getIDasByteBuffer();
262 addedDeviceEvents.remove(id);
263 removedDeviceEvents.put(id, deviceEvent);
264 reorderedAddedDeviceEvents.remove(id);
265 }
266 break;
Ray Milkey0b122ed2014-04-14 10:06:03 -0700267 default:
268 log.error("Unknown topology event {}",
269 event.eventType());
Ray Milkey269ffb92014-04-03 14:43:30 -0700270 }
271 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800272
Ray Milkey269ffb92014-04-03 14:43:30 -0700273 //
274 // Lock the Network Graph while it is modified
275 //
276 networkGraph.acquireWriteLock();
Pavlin Radoslavov8ffb8bf2014-02-20 15:34:26 -0800277
Ray Milkey269ffb92014-04-03 14:43:30 -0700278 try {
279 //
280 // Apply the classified events.
281 //
282 // Apply the "add" events in the proper order:
283 // switch, port, link, device
284 //
Ray Milkeyb29e6262014-04-09 16:02:14 -0700285 for (SwitchEvent switchEvent : addedSwitchEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700286 addSwitch(switchEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700287 }
288 for (PortEvent portEvent : addedPortEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700289 addPort(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700290 }
291 for (LinkEvent linkEvent : addedLinkEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700292 addLink(linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700293 }
294 for (DeviceEvent deviceEvent : addedDeviceEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700295 addDevice(deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700296 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700297 //
298 // Apply the "remove" events in the reverse order:
299 // device, link, port, switch
300 //
Ray Milkeyb29e6262014-04-09 16:02:14 -0700301 for (DeviceEvent deviceEvent : removedDeviceEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700302 removeDevice(deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700303 }
304 for (LinkEvent linkEvent : removedLinkEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700305 removeLink(linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700306 }
307 for (PortEvent portEvent : removedPortEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700308 removePort(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700309 }
310 for (SwitchEvent switchEvent : removedSwitchEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700311 removeSwitch(switchEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700312 }
Yuta HIGUCHI3aca81a2014-02-23 12:41:19 -0800313
Ray Milkey269ffb92014-04-03 14:43:30 -0700314 //
315 // Apply reordered events
316 //
317 applyReorderedEvents(!addedSwitchEvents.isEmpty(),
318 !addedPortEvents.isEmpty());
Yuta HIGUCHI3aca81a2014-02-23 12:41:19 -0800319
Ray Milkey269ffb92014-04-03 14:43:30 -0700320 } finally {
321 //
322 // Network Graph modifications completed: Release the lock
323 //
324 networkGraph.releaseWriteLock();
325 }
Yuta HIGUCHI3aca81a2014-02-23 12:41:19 -0800326
Ray Milkey269ffb92014-04-03 14:43:30 -0700327 //
328 // Dispatch the Topology Notification Events to the applications
329 //
330 dispatchNetworkGraphEvents();
331 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800332
Ray Milkey269ffb92014-04-03 14:43:30 -0700333 /**
334 * Receive a notification that an entry is added.
335 *
336 * @param value the value for the entry.
337 */
338 @Override
339 public void entryAdded(TopologyEvent value) {
340 EventEntry<TopologyEvent> eventEntry =
341 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
342 value);
343 topologyEvents.add(eventEntry);
344 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800345
Ray Milkey269ffb92014-04-03 14:43:30 -0700346 /**
347 * Receive a notification that an entry is removed.
348 *
349 * @param value the value for the entry.
350 */
351 @Override
352 public void entryRemoved(TopologyEvent value) {
353 EventEntry<TopologyEvent> eventEntry =
354 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_REMOVE,
355 value);
356 topologyEvents.add(eventEntry);
357 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800358
Ray Milkey269ffb92014-04-03 14:43:30 -0700359 /**
360 * Receive a notification that an entry is updated.
361 *
362 * @param value the value for the entry.
363 */
364 @Override
365 public void entryUpdated(TopologyEvent value) {
366 // NOTE: The ADD and UPDATE events are processed in same way
367 entryAdded(value);
368 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800369 }
370
371 /**
372 * Startup processing.
373 *
374 * @param datagridService the datagrid service to use.
375 */
376 void startup(IDatagridService datagridService) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700377 eventChannel = datagridService.addListener(EVENT_CHANNEL_NAME,
378 eventHandler,
379 byte[].class,
380 TopologyEvent.class);
381 eventHandler.start();
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800382 }
383
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800384 /**
385 * Dispatch Network Graph Events to the listeners.
386 */
387 private void dispatchNetworkGraphEvents() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700388 if (apiAddedSwitchEvents.isEmpty() &&
389 apiRemovedSwitchEvents.isEmpty() &&
390 apiAddedPortEvents.isEmpty() &&
391 apiRemovedPortEvents.isEmpty() &&
392 apiAddedLinkEvents.isEmpty() &&
393 apiRemovedLinkEvents.isEmpty() &&
394 apiAddedDeviceEvents.isEmpty() &&
395 apiRemovedDeviceEvents.isEmpty()) {
396 return; // No events to dispatch
397 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800398
Ray Milkey269ffb92014-04-03 14:43:30 -0700399 if (log.isDebugEnabled()) {
400 //
401 // Debug statements
402 // TODO: Those statements should be removed in the future
403 //
Ray Milkeyb29e6262014-04-09 16:02:14 -0700404 for (SwitchEvent switchEvent : apiAddedSwitchEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700405 log.debug("Dispatch Network Graph Event: ADDED {}", switchEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700406 }
407 for (SwitchEvent switchEvent : apiRemovedSwitchEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700408 log.debug("Dispatch Network Graph Event: REMOVED {}", switchEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700409 }
410 for (PortEvent portEvent : apiAddedPortEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700411 log.debug("Dispatch Network Graph Event: ADDED {}", portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700412 }
413 for (PortEvent portEvent : apiRemovedPortEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700414 log.debug("Dispatch Network Graph Event: REMOVED {}", portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700415 }
416 for (LinkEvent linkEvent : apiAddedLinkEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700417 log.debug("Dispatch Network Graph Event: ADDED {}", linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700418 }
419 for (LinkEvent linkEvent : apiRemovedLinkEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700420 log.debug("Dispatch Network Graph Event: REMOVED {}", linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700421 }
422 for (DeviceEvent deviceEvent : apiAddedDeviceEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700423 log.debug("Dispatch Network Graph Event: ADDED {}", deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700424 }
425 for (DeviceEvent deviceEvent : apiRemovedDeviceEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700426 log.debug("Dispatch Network Graph Event: REMOVED {}", deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700427 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700428 }
adminbc181552014-02-21 18:36:42 -0800429
Ray Milkey269ffb92014-04-03 14:43:30 -0700430 // Deliver the events
431 for (INetworkGraphListener listener : this.networkGraphListeners) {
432 // TODO: Should copy before handing them over to listener?
433 listener.networkGraphEvents(apiAddedSwitchEvents,
434 apiRemovedSwitchEvents,
435 apiAddedPortEvents,
436 apiRemovedPortEvents,
437 apiAddedLinkEvents,
438 apiRemovedLinkEvents,
439 apiAddedDeviceEvents,
440 apiRemovedDeviceEvents);
441 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800442
Ray Milkey269ffb92014-04-03 14:43:30 -0700443 //
444 // Cleanup
445 //
446 apiAddedSwitchEvents.clear();
447 apiRemovedSwitchEvents.clear();
448 apiAddedPortEvents.clear();
449 apiRemovedPortEvents.clear();
450 apiAddedLinkEvents.clear();
451 apiRemovedLinkEvents.clear();
452 apiAddedDeviceEvents.clear();
453 apiRemovedDeviceEvents.clear();
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800454 }
455
456 /**
457 * Apply reordered events.
458 *
459 * @param hasAddedSwitchEvents true if there were Added Switch Events.
Ray Milkey269ffb92014-04-03 14:43:30 -0700460 * @param hasAddedPortEvents true if there were Added Port Events.
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800461 */
462 private void applyReorderedEvents(boolean hasAddedSwitchEvents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700463 boolean hasAddedPortEvents) {
Ray Milkeyb29e6262014-04-09 16:02:14 -0700464 if (!(hasAddedSwitchEvents || hasAddedPortEvents)) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700465 return; // Nothing to do
Ray Milkeyb29e6262014-04-09 16:02:14 -0700466 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800467
Ray Milkey269ffb92014-04-03 14:43:30 -0700468 //
469 // Try to apply the reordered events.
470 //
471 // NOTE: For simplicity we try to apply all events of a particular
472 // type if any "parent" type event was processed:
473 // - Apply reordered Port Events if Switches were added
474 // - Apply reordered Link and Device Events if Switches or Ports
475 // were added
476 //
adminbc181552014-02-21 18:36:42 -0800477
Ray Milkey269ffb92014-04-03 14:43:30 -0700478 //
479 // Apply reordered Port Events if Switches were added
480 //
481 if (hasAddedSwitchEvents) {
482 Map<ByteBuffer, PortEvent> portEvents = reorderedAddedPortEvents;
483 reorderedAddedPortEvents = new HashMap<>();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700484 for (PortEvent portEvent : portEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700485 addPort(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700486 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700487 }
488 //
489 // Apply reordered Link and Device Events if Switches or Ports
490 // were added.
491 //
492 Map<ByteBuffer, LinkEvent> linkEvents = reorderedAddedLinkEvents;
493 reorderedAddedLinkEvents = new HashMap<>();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700494 for (LinkEvent linkEvent : linkEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700495 addLink(linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700496 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700497 //
498 Map<ByteBuffer, DeviceEvent> deviceEvents = reorderedAddedDeviceEvents;
499 reorderedAddedDeviceEvents = new HashMap<>();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700500 for (DeviceEvent deviceEvent : deviceEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700501 addDevice(deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700502 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800503 }
504
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800505 /**
506 * Switch discovered event.
507 *
508 * @param switchEvent the switch event.
Ray Milkey269ffb92014-04-03 14:43:30 -0700509 * @param portEvents the corresponding port events for the switch.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800510 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800511 @Override
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800512 public void putSwitchDiscoveryEvent(SwitchEvent switchEvent,
Ray Milkey269ffb92014-04-03 14:43:30 -0700513 Collection<PortEvent> portEvents) {
514 if (datastore.addSwitch(switchEvent, portEvents)) {
515 // Send out notification
516 TopologyEvent topologyEvent = new TopologyEvent(switchEvent);
517 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800518
Ray Milkey269ffb92014-04-03 14:43:30 -0700519 // Send out notification for each port
520 for (PortEvent portEvent : portEvents) {
521 topologyEvent = new TopologyEvent(portEvent);
522 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
523 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800524
Ray Milkey269ffb92014-04-03 14:43:30 -0700525 //
526 // Keep track of the added ports
527 //
528 // Get the old Port Events
529 Map<ByteBuffer, PortEvent> oldPortEvents =
530 discoveredAddedPortEvents.get(switchEvent.getDpid());
Ray Milkeyb29e6262014-04-09 16:02:14 -0700531 if (oldPortEvents == null) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700532 oldPortEvents = new HashMap<>();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700533 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800534
Ray Milkey269ffb92014-04-03 14:43:30 -0700535 // Store the new Port Events in the local cache
536 Map<ByteBuffer, PortEvent> newPortEvents = new HashMap<>();
537 for (PortEvent portEvent : portEvents) {
538 ByteBuffer id = portEvent.getIDasByteBuffer();
539 newPortEvents.put(id, portEvent);
540 }
541 discoveredAddedPortEvents.put(switchEvent.getDpid(),
542 newPortEvents);
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800543
Ray Milkey269ffb92014-04-03 14:43:30 -0700544 //
545 // Extract the removed ports
546 //
547 List<PortEvent> removedPortEvents = new LinkedList<>();
548 for (Map.Entry<ByteBuffer, PortEvent> entry : oldPortEvents.entrySet()) {
549 ByteBuffer key = entry.getKey();
550 PortEvent portEvent = entry.getValue();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700551 if (!newPortEvents.containsKey(key)) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700552 removedPortEvents.add(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700553 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700554 }
555
556 // Cleanup old removed ports
Ray Milkeyb29e6262014-04-09 16:02:14 -0700557 for (PortEvent portEvent : removedPortEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700558 removePortDiscoveryEvent(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700559 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700560 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800561 }
562
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800563 /**
564 * Switch removed event.
565 *
566 * @param switchEvent the switch event.
567 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800568 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800569 public void removeSwitchDiscoveryEvent(SwitchEvent switchEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700570 // Get the old Port Events
571 Map<ByteBuffer, PortEvent> oldPortEvents =
572 discoveredAddedPortEvents.get(switchEvent.getDpid());
Ray Milkeyb29e6262014-04-09 16:02:14 -0700573 if (oldPortEvents == null) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700574 oldPortEvents = new HashMap<>();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700575 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800576
Ray Milkey269ffb92014-04-03 14:43:30 -0700577 if (datastore.deactivateSwitch(switchEvent, oldPortEvents.values())) {
578 // Send out notification
579 eventChannel.removeEntry(switchEvent.getID());
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800580
Ray Milkey269ffb92014-04-03 14:43:30 -0700581 //
582 // Send out notification for each port.
583 //
584 // NOTE: We don't use removePortDiscoveryEvent() for the cleanup,
585 // because it will attempt to remove the port from the database,
586 // and the deactiveSwitch() call above already removed all ports.
587 //
Ray Milkeyb29e6262014-04-09 16:02:14 -0700588 for (PortEvent portEvent : oldPortEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700589 eventChannel.removeEntry(portEvent.getID());
Ray Milkeyb29e6262014-04-09 16:02:14 -0700590 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700591 discoveredAddedPortEvents.remove(switchEvent.getDpid());
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800592
Ray Milkey269ffb92014-04-03 14:43:30 -0700593 // Cleanup for each link
594 Map<ByteBuffer, LinkEvent> oldLinkEvents =
595 discoveredAddedLinkEvents.get(switchEvent.getDpid());
596 if (oldLinkEvents != null) {
597 for (LinkEvent linkEvent : new ArrayList<>(oldLinkEvents.values())) {
598 removeLinkDiscoveryEvent(linkEvent);
599 }
600 discoveredAddedLinkEvents.remove(switchEvent.getDpid());
601 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800602
Ray Milkey269ffb92014-04-03 14:43:30 -0700603 // Cleanup for each device
604 Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
605 discoveredAddedDeviceEvents.get(switchEvent.getDpid());
606 if (oldDeviceEvents != null) {
607 for (DeviceEvent deviceEvent : new ArrayList<>(oldDeviceEvents.values())) {
608 removeDeviceDiscoveryEvent(deviceEvent);
609 }
610 discoveredAddedDeviceEvents.remove(switchEvent.getDpid());
611 }
612 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800613 }
614
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800615 /**
616 * Port discovered event.
617 *
618 * @param portEvent the port event.
619 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800620 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800621 public void putPortDiscoveryEvent(PortEvent portEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700622 if (datastore.addPort(portEvent)) {
623 // Send out notification
624 TopologyEvent topologyEvent = new TopologyEvent(portEvent);
625 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800626
Ray Milkey269ffb92014-04-03 14:43:30 -0700627 // Store the new Port Event in the local cache
628 Map<ByteBuffer, PortEvent> oldPortEvents =
629 discoveredAddedPortEvents.get(portEvent.getDpid());
630 if (oldPortEvents == null) {
631 oldPortEvents = new HashMap<>();
632 discoveredAddedPortEvents.put(portEvent.getDpid(),
633 oldPortEvents);
634 }
635 ByteBuffer id = portEvent.getIDasByteBuffer();
636 oldPortEvents.put(id, portEvent);
637 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800638 }
639
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800640 /**
641 * Port removed event.
642 *
643 * @param portEvent the port event.
644 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800645 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800646 public void removePortDiscoveryEvent(PortEvent portEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700647 if (datastore.deactivatePort(portEvent)) {
648 // Send out notification
649 eventChannel.removeEntry(portEvent.getID());
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800650
Ray Milkey269ffb92014-04-03 14:43:30 -0700651 // Cleanup the Port Event from the local cache
652 Map<ByteBuffer, PortEvent> oldPortEvents =
653 discoveredAddedPortEvents.get(portEvent.getDpid());
654 if (oldPortEvents != null) {
655 ByteBuffer id = portEvent.getIDasByteBuffer();
656 oldPortEvents.remove(id);
657 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800658
Ray Milkey269ffb92014-04-03 14:43:30 -0700659 // Cleanup for the incoming link
660 Map<ByteBuffer, LinkEvent> oldLinkEvents =
661 discoveredAddedLinkEvents.get(portEvent.getDpid());
662 if (oldLinkEvents != null) {
663 for (LinkEvent linkEvent : new ArrayList<>(oldLinkEvents.values())) {
664 if (linkEvent.getDst().equals(portEvent.id)) {
665 removeLinkDiscoveryEvent(linkEvent);
666 // XXX If we change our model to allow multiple Link on
667 // a Port, this loop must be fixed to allow continuing.
668 break;
669 }
670 }
671 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800672
Ray Milkey269ffb92014-04-03 14:43:30 -0700673 // Cleanup for the connected devices
674 // TODO: The implementation below is probably wrong
675 List<DeviceEvent> removedDeviceEvents = new LinkedList<>();
676 Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
677 discoveredAddedDeviceEvents.get(portEvent.getDpid());
678 if (oldDeviceEvents != null) {
679 for (DeviceEvent deviceEvent : new ArrayList<>(oldDeviceEvents.values())) {
680 for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
681 if (swp.equals(portEvent.id)) {
682 removedDeviceEvents.add(deviceEvent);
683 }
684 }
685 }
Ray Milkeyb29e6262014-04-09 16:02:14 -0700686 for (DeviceEvent deviceEvent : removedDeviceEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700687 removeDeviceDiscoveryEvent(deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700688 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700689 }
690 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800691 }
692
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800693 /**
694 * Link discovered event.
695 *
696 * @param linkEvent the link event.
697 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800698 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800699 public void putLinkDiscoveryEvent(LinkEvent linkEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700700 if (datastore.addLink(linkEvent)) {
701 // Send out notification
702 TopologyEvent topologyEvent = new TopologyEvent(linkEvent);
703 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800704
Ray Milkey269ffb92014-04-03 14:43:30 -0700705 // Store the new Link Event in the local cache
706 Map<ByteBuffer, LinkEvent> oldLinkEvents =
707 discoveredAddedLinkEvents.get(linkEvent.getDst().getDpid());
708 if (oldLinkEvents == null) {
709 oldLinkEvents = new HashMap<>();
710 discoveredAddedLinkEvents.put(linkEvent.getDst().getDpid(),
711 oldLinkEvents);
712 }
713 ByteBuffer id = linkEvent.getIDasByteBuffer();
714 oldLinkEvents.put(id, linkEvent);
715 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800716 }
717
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800718 /**
719 * Link removed event.
720 *
721 * @param linkEvent the link event.
722 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800723 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800724 public void removeLinkDiscoveryEvent(LinkEvent linkEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700725 if (datastore.removeLink(linkEvent)) {
726 // Send out notification
727 eventChannel.removeEntry(linkEvent.getID());
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800728
Ray Milkey269ffb92014-04-03 14:43:30 -0700729 // Cleanup the Link Event from the local cache
730 Map<ByteBuffer, LinkEvent> oldLinkEvents =
731 discoveredAddedLinkEvents.get(linkEvent.getDst().getDpid());
732 if (oldLinkEvents != null) {
733 ByteBuffer id = linkEvent.getIDasByteBuffer();
734 oldLinkEvents.remove(id);
735 }
736 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800737 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800738
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800739 /**
740 * Device discovered event.
741 *
742 * @param deviceEvent the device event.
743 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800744 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800745 public void putDeviceDiscoveryEvent(DeviceEvent deviceEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700746 if (datastore.addDevice(deviceEvent)) {
747 // Send out notification
748 TopologyEvent topologyEvent = new TopologyEvent(deviceEvent);
749 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
750 log.debug("Put the device info into the cache of the graph. mac {}", deviceEvent.getMac());
751
752 // Store the new Device Event in the local cache
753 // TODO: The implementation below is probably wrong
754 for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
755 Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
756 discoveredAddedDeviceEvents.get(swp.getDpid());
757 if (oldDeviceEvents == null) {
758 oldDeviceEvents = new HashMap<>();
759 discoveredAddedDeviceEvents.put(swp.getDpid(),
760 oldDeviceEvents);
761 }
762 ByteBuffer id = deviceEvent.getIDasByteBuffer();
763 oldDeviceEvents.put(id, deviceEvent);
764 }
765 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800766 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800767
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800768 /**
769 * Device removed event.
770 *
771 * @param deviceEvent the device event.
772 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800773 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800774 public void removeDeviceDiscoveryEvent(DeviceEvent deviceEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700775 if (datastore.removeDevice(deviceEvent)) {
776 // Send out notification
777 eventChannel.removeEntry(deviceEvent.getID());
778 log.debug("Remove the device info into the cache of the graph. mac {}", deviceEvent.getMac());
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800779
Ray Milkey269ffb92014-04-03 14:43:30 -0700780 // Cleanup the Device Event from the local cache
781 // TODO: The implementation below is probably wrong
782 ByteBuffer id = ByteBuffer.wrap(deviceEvent.getID());
783 for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
784 Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
785 discoveredAddedDeviceEvents.get(swp.getDpid());
786 if (oldDeviceEvents != null) {
787 oldDeviceEvents.remove(id);
788 }
789 }
790 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800791 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800792
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800793 /**
794 * Add a switch to the Network Graph.
795 *
796 * @param switchEvent the Switch Event with the switch to add.
797 */
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800798 private void addSwitch(SwitchEvent switchEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700799 Switch sw = networkGraph.getSwitch(switchEvent.getDpid());
800 if (sw == null) {
801 sw = new SwitchImpl(networkGraph, switchEvent.getDpid());
802 networkGraph.putSwitch(sw);
803 } else {
804 // TODO: Update the switch attributes
805 // TODO: Nothing to do for now
Ray Milkey1aa71f82014-04-08 16:23:24 -0700806 log.debug("Update switch attributes");
Ray Milkey269ffb92014-04-03 14:43:30 -0700807 }
808 apiAddedSwitchEvents.add(switchEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800809 }
810
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800811 /**
812 * Remove a switch from the Network Graph.
813 *
814 * @param switchEvent the Switch Event with the switch to remove.
815 */
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800816 private void removeSwitch(SwitchEvent switchEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700817 Switch sw = networkGraph.getSwitch(switchEvent.getDpid());
818 if (sw == null) {
819 log.warn("Switch {} already removed, ignoring", switchEvent);
820 return;
821 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800822
Ray Milkey269ffb92014-04-03 14:43:30 -0700823 //
824 // Remove all Ports on the Switch
825 //
826 ArrayList<PortEvent> portsToRemove = new ArrayList<>();
827 for (Port port : sw.getPorts()) {
828 log.warn("Port {} on Switch {} should be removed prior to removing Switch. Removing Port now.",
829 port, switchEvent);
830 PortEvent portEvent = new PortEvent(port.getDpid(),
831 port.getNumber());
832 portsToRemove.add(portEvent);
833 }
Ray Milkeyb29e6262014-04-09 16:02:14 -0700834 for (PortEvent portEvent : portsToRemove) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700835 removePort(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700836 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800837
Ray Milkey269ffb92014-04-03 14:43:30 -0700838 networkGraph.removeSwitch(switchEvent.getDpid());
839 apiRemovedSwitchEvents.add(switchEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800840 }
841
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800842 /**
843 * Add a port to the Network Graph.
844 *
845 * @param portEvent the Port Event with the port to add.
846 */
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800847 private void addPort(PortEvent portEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700848 Switch sw = networkGraph.getSwitch(portEvent.getDpid());
849 if (sw == null) {
850 // Reordered event: delay the event in local cache
851 ByteBuffer id = portEvent.getIDasByteBuffer();
852 reorderedAddedPortEvents.put(id, portEvent);
853 return;
854 }
855 SwitchImpl switchImpl = getSwitchImpl(sw);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800856
Ray Milkey269ffb92014-04-03 14:43:30 -0700857 Port port = sw.getPort(portEvent.getNumber());
858 if (port == null) {
859 port = new PortImpl(networkGraph, sw, portEvent.getNumber());
860 switchImpl.addPort(port);
861 } else {
862 // TODO: Update the port attributes
Ray Milkey1aa71f82014-04-08 16:23:24 -0700863 log.debug("Update port attributes");
Ray Milkey269ffb92014-04-03 14:43:30 -0700864 }
865 apiAddedPortEvents.add(portEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800866 }
867
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800868 /**
869 * Remove a port from the Network Graph.
870 *
871 * @param portEvent the Port Event with the port to remove.
872 */
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800873 private void removePort(PortEvent portEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700874 Switch sw = networkGraph.getSwitch(portEvent.getDpid());
875 if (sw == null) {
876 log.warn("Parent Switch for Port {} already removed, ignoring",
877 portEvent);
878 return;
879 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800880
Ray Milkey269ffb92014-04-03 14:43:30 -0700881 Port port = sw.getPort(portEvent.getNumber());
882 if (port == null) {
883 log.warn("Port {} already removed, ignoring", portEvent);
884 return;
885 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800886
Ray Milkey269ffb92014-04-03 14:43:30 -0700887 //
888 // Remove all Devices attached to the Port
889 //
890 ArrayList<DeviceEvent> devicesToRemove = new ArrayList<>();
891 for (Device device : port.getDevices()) {
892 log.debug("Removing Device {} on Port {}", device, portEvent);
893 DeviceEvent deviceEvent = new DeviceEvent(device.getMacAddress());
894 SwitchPort switchPort = new SwitchPort(port.getSwitch().getDpid(),
895 port.getNumber());
896 deviceEvent.addAttachmentPoint(switchPort);
897 devicesToRemove.add(deviceEvent);
898 }
Ray Milkeyb29e6262014-04-09 16:02:14 -0700899 for (DeviceEvent deviceEvent : devicesToRemove) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700900 removeDevice(deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700901 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800902
Ray Milkey269ffb92014-04-03 14:43:30 -0700903 //
904 // Remove all Links connected to the Port
905 //
906 Set<Link> links = new HashSet<>();
907 links.add(port.getOutgoingLink());
908 links.add(port.getIncomingLink());
909 ArrayList<LinkEvent> linksToRemove = new ArrayList<>();
910 for (Link link : links) {
Ray Milkeyb29e6262014-04-09 16:02:14 -0700911 if (link == null) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700912 continue;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700913 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700914 log.debug("Removing Link {} on Port {}", link, portEvent);
915 LinkEvent linkEvent = new LinkEvent(link.getSrcSwitch().getDpid(),
916 link.getSrcPort().getNumber(),
917 link.getDstSwitch().getDpid(),
918 link.getDstPort().getNumber());
919 linksToRemove.add(linkEvent);
920 }
Ray Milkeyb29e6262014-04-09 16:02:14 -0700921 for (LinkEvent linkEvent : linksToRemove) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700922 removeLink(linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700923 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800924
Ray Milkey269ffb92014-04-03 14:43:30 -0700925 // Remove the Port from the Switch
926 SwitchImpl switchImpl = getSwitchImpl(sw);
927 switchImpl.removePort(port);
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800928
Ray Milkey269ffb92014-04-03 14:43:30 -0700929 apiRemovedPortEvents.add(portEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800930 }
931
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800932 /**
933 * Add a link to the Network Graph.
934 *
935 * @param linkEvent the Link Event with the link to add.
936 */
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800937 private void addLink(LinkEvent linkEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700938 Port srcPort = networkGraph.getPort(linkEvent.getSrc().dpid,
939 linkEvent.getSrc().number);
940 Port dstPort = networkGraph.getPort(linkEvent.getDst().dpid,
941 linkEvent.getDst().number);
942 if ((srcPort == null) || (dstPort == null)) {
943 // Reordered event: delay the event in local cache
944 ByteBuffer id = linkEvent.getIDasByteBuffer();
945 reorderedAddedLinkEvents.put(id, linkEvent);
946 return;
947 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800948
Ray Milkey269ffb92014-04-03 14:43:30 -0700949 // Get the Link instance from the Destination Port Incoming Link
950 Link link = dstPort.getIncomingLink();
951 assert (link == srcPort.getOutgoingLink());
952 if (link == null) {
953 link = new LinkImpl(networkGraph, srcPort, dstPort);
Jonathan Hart25bd53e2014-04-30 23:44:09 -0700954 networkGraph.putLink(link);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800955
Ray Milkey269ffb92014-04-03 14:43:30 -0700956 // Remove all Devices attached to the Ports
957 ArrayList<DeviceEvent> devicesToRemove = new ArrayList<>();
958 ArrayList<Port> ports = new ArrayList<>();
959 ports.add(srcPort);
960 ports.add(dstPort);
961 for (Port port : ports) {
962 for (Device device : port.getDevices()) {
963 log.error("Device {} on Port {} should have been removed prior to adding Link {}",
964 device, port, linkEvent);
965 DeviceEvent deviceEvent =
966 new DeviceEvent(device.getMacAddress());
967 SwitchPort switchPort =
968 new SwitchPort(port.getSwitch().getDpid(),
969 port.getNumber());
970 deviceEvent.addAttachmentPoint(switchPort);
971 devicesToRemove.add(deviceEvent);
972 }
973 }
Ray Milkeyb29e6262014-04-09 16:02:14 -0700974 for (DeviceEvent deviceEvent : devicesToRemove) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700975 removeDevice(deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700976 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700977 } else {
978 // TODO: Update the link attributes
Ray Milkey1aa71f82014-04-08 16:23:24 -0700979 log.debug("Update link attributes");
Ray Milkey269ffb92014-04-03 14:43:30 -0700980 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800981
Ray Milkey269ffb92014-04-03 14:43:30 -0700982 apiAddedLinkEvents.add(linkEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800983 }
984
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800985 /**
986 * Remove a link from the Network Graph.
987 *
988 * @param linkEvent the Link Event with the link to remove.
989 */
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800990 private void removeLink(LinkEvent linkEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700991 Port srcPort = networkGraph.getPort(linkEvent.getSrc().dpid,
992 linkEvent.getSrc().number);
993 if (srcPort == null) {
994 log.warn("Src Port for Link {} already removed, ignoring",
995 linkEvent);
996 return;
997 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800998
Ray Milkey269ffb92014-04-03 14:43:30 -0700999 Port dstPort = networkGraph.getPort(linkEvent.getDst().dpid,
1000 linkEvent.getDst().number);
1001 if (dstPort == null) {
1002 log.warn("Dst Port for Link {} already removed, ignoring",
1003 linkEvent);
1004 return;
1005 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001006
Ray Milkey269ffb92014-04-03 14:43:30 -07001007 //
1008 // Remove the Link instance from the Destination Port Incoming Link
1009 // and the Source Port Outgoing Link.
1010 //
1011 Link link = dstPort.getIncomingLink();
1012 if (link == null) {
1013 log.warn("Link {} already removed on destination Port", linkEvent);
1014 }
1015 link = srcPort.getOutgoingLink();
1016 if (link == null) {
1017 log.warn("Link {} already removed on src Port", linkEvent);
1018 }
Jonathan Hart25bd53e2014-04-30 23:44:09 -07001019
1020 // TODO should we check that we get the same link from each port?
1021 if (link != null) {
1022 networkGraph.removeLink(link);
1023 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -08001024
Ray Milkey269ffb92014-04-03 14:43:30 -07001025 apiRemovedLinkEvents.add(linkEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001026 }
1027
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001028 /**
1029 * Add a device to the Network Graph.
Ray Milkey269ffb92014-04-03 14:43:30 -07001030 * <p/>
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001031 * TODO: Device-related work is incomplete.
1032 * TODO: Eventually, we might need to consider reordering
1033 * or addLink() and addDevice() events on the same port.
1034 *
1035 * @param deviceEvent the Device Event with the device to add.
1036 */
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001037 private void addDevice(DeviceEvent deviceEvent) {
TeruU28adcc32014-04-15 17:57:35 -07001038 log.debug("Adding a device to the Network Graph with mac {}", deviceEvent.getMac());
Ray Milkey269ffb92014-04-03 14:43:30 -07001039 Device device = networkGraph.getDeviceByMac(deviceEvent.getMac());
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001040
Ray Milkey269ffb92014-04-03 14:43:30 -07001041 if (device == null) {
TeruU28adcc32014-04-15 17:57:35 -07001042 log.debug("Existing device was not found in the NetworkGraph: Adding new device: mac {}", deviceEvent.getMac());
Ray Milkey269ffb92014-04-03 14:43:30 -07001043 device = new DeviceImpl(networkGraph, deviceEvent.getMac());
1044 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001045
Ray Milkey269ffb92014-04-03 14:43:30 -07001046 DeviceImpl deviceImpl = getDeviceImpl(device);
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) {
TeruU28adcc32014-04-15 17:57:35 -07001077 log.debug("Storing the device info into the NetworkGraph: mac {}", deviceEvent.getMac());
Ray Milkey269ffb92014-04-03 14:43:30 -07001078 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) {
TeruU28adcc32014-04-15 17:57:35 -07001091 log.debug("Removing a device to the Network Graph: mac {}", deviceEvent.getMac());
Ray Milkey269ffb92014-04-03 14:43:30 -07001092 Device device = networkGraph.getDeviceByMac(deviceEvent.getMac());
1093 if (device == null) {
1094 log.warn("Device {} already removed, ignoring", deviceEvent);
1095 return;
1096 }
1097 DeviceImpl deviceImpl = getDeviceImpl(device);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001098
Ray Milkey269ffb92014-04-03 14:43:30 -07001099 // Process each attachment point
1100 for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
1101 // Attached Ports must exist
1102 Port port = networkGraph.getPort(swp.dpid, swp.number);
1103 if (port == null) {
1104 log.warn("Port for the attachment point {} did not exist. skipping attachment point mutation", swp);
1105 continue;
1106 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001107
Ray Milkey269ffb92014-04-03 14:43:30 -07001108 // Remove Device <-> Port attachment
1109 PortImpl portImpl = getPortImpl(port);
1110 portImpl.removeDevice(device);
1111 deviceImpl.removeAttachmentPoint(port);
1112 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -08001113
TeruU28adcc32014-04-15 17:57:35 -07001114 log.debug("Removing the device info into the NetworkGraph: mac {}", deviceEvent.getMac());
Ray Milkey269ffb92014-04-03 14:43:30 -07001115 networkGraph.removeDevice(device);
1116 apiRemovedDeviceEvents.add(deviceEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001117 }
Jonathan Hart22eb9882014-02-11 15:52:59 -08001118
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001119 /**
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001120 * Get the SwitchImpl-casted switch implementation.
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001121 *
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001122 * @param sw the Switch to cast.
1123 * @return the SwitchImpl-casted switch implementation.
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001124 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001125 private SwitchImpl getSwitchImpl(Switch sw) {
Ray Milkey269ffb92014-04-03 14:43:30 -07001126 if (sw instanceof SwitchImpl) {
1127 return (SwitchImpl) sw;
1128 }
1129 throw new ClassCastException("SwitchImpl expected, but found: " + sw);
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001130 }
1131
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001132 /**
1133 * Get the PortImpl-casted port implementation.
1134 *
1135 * @param port the Port to cast.
1136 * @return the PortImpl-casted port implementation.
1137 */
1138 private PortImpl getPortImpl(Port port) {
Ray Milkey269ffb92014-04-03 14:43:30 -07001139 if (port instanceof PortImpl) {
1140 return (PortImpl) port;
1141 }
1142 throw new ClassCastException("PortImpl expected, but found: " + port);
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001143 }
1144
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001145 /**
1146 * Get the LinkImpl-casted link implementation.
1147 *
1148 * @param link the Link to cast.
1149 * @return the LinkImpl-casted link implementation.
1150 */
1151 private LinkImpl getLinkImpl(Link link) {
Ray Milkey269ffb92014-04-03 14:43:30 -07001152 if (link instanceof LinkImpl) {
1153 return (LinkImpl) link;
1154 }
1155 throw new ClassCastException("LinkImpl expected, but found: " + link);
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001156 }
1157
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001158 /**
1159 * Get the DeviceImpl-casted device implementation.
1160 *
1161 * @param device the Device to cast.
1162 * @return the DeviceImpl-casted device implementation.
1163 */
1164 private DeviceImpl getDeviceImpl(Device device) {
Ray Milkey269ffb92014-04-03 14:43:30 -07001165 if (device instanceof DeviceImpl) {
1166 return (DeviceImpl) device;
1167 }
1168 throw new ClassCastException("DeviceImpl expected, but found: " + device);
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001169 }
1170
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001171 /**
1172 * Read the whole topology from the database.
1173 *
1174 * @return a collection of EventEntry-encapsulated Topology Events for
1175 * the whole topology.
1176 */
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001177 private Collection<EventEntry<TopologyEvent>> readWholeTopologyFromDB() {
Ray Milkey269ffb92014-04-03 14:43:30 -07001178 Collection<EventEntry<TopologyEvent>> collection =
1179 new LinkedList<EventEntry<TopologyEvent>>();
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001180
Ray Milkey269ffb92014-04-03 14:43:30 -07001181 // XXX May need to clear whole topology first, depending on
1182 // how we initially subscribe to replication events
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001183
Ray Milkey269ffb92014-04-03 14:43:30 -07001184 // Add all active switches
1185 for (KVSwitch sw : KVSwitch.getAllSwitches()) {
1186 if (sw.getStatus() != KVSwitch.STATUS.ACTIVE) {
1187 continue;
1188 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001189
Ray Milkey269ffb92014-04-03 14:43:30 -07001190 SwitchEvent switchEvent = new SwitchEvent(sw.getDpid());
1191 TopologyEvent topologyEvent = new TopologyEvent(switchEvent);
1192 EventEntry<TopologyEvent> eventEntry =
1193 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
1194 topologyEvent);
1195 collection.add(eventEntry);
1196 }
Yuta HIGUCHIa536e762014-02-17 21:47:28 -08001197
Ray Milkey269ffb92014-04-03 14:43:30 -07001198 // Add all active ports
1199 for (KVPort p : KVPort.getAllPorts()) {
1200 if (p.getStatus() != KVPort.STATUS.ACTIVE) {
1201 continue;
1202 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001203
Ray Milkey269ffb92014-04-03 14:43:30 -07001204 PortEvent portEvent = new PortEvent(p.getDpid(), p.getNumber());
1205 TopologyEvent topologyEvent = new TopologyEvent(portEvent);
1206 EventEntry<TopologyEvent> eventEntry =
1207 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
1208 topologyEvent);
1209 collection.add(eventEntry);
1210 }
Yuta HIGUCHIa536e762014-02-17 21:47:28 -08001211
TeruU28adcc32014-04-15 17:57:35 -07001212 for (KVDevice d : KVDevice.getAllDevices()) {
1213 DeviceEvent devEvent = new DeviceEvent(MACAddress.valueOf(d.getMac()));
1214 for (byte[] portId : d.getAllPortIds()) {
1215 devEvent.addAttachmentPoint(new SwitchPort(KVPort.getDpidFromKey(portId), KVPort.getNumberFromKey(portId)));
1216 }
1217 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001218
Ray Milkey269ffb92014-04-03 14:43:30 -07001219 for (KVLink l : KVLink.getAllLinks()) {
1220 LinkEvent linkEvent = new LinkEvent(l.getSrc().dpid,
1221 l.getSrc().number,
1222 l.getDst().dpid,
1223 l.getDst().number);
1224 TopologyEvent topologyEvent = new TopologyEvent(linkEvent);
1225 EventEntry<TopologyEvent> eventEntry =
1226 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
1227 topologyEvent);
1228 collection.add(eventEntry);
1229 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001230
Ray Milkey269ffb92014-04-03 14:43:30 -07001231 return collection;
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001232 }
Jonathan Hart062a2e82014-02-03 09:41:57 -08001233}