blob: bc1fc9ab7521a15424dd86b951d5ef61aa5ff3f4 [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 //
Ray Milkey5df613b2014-04-15 10:50:56 -0700140 Collection<TopologyEvent> allTopologyEvents =
Ray Milkey269ffb92014-04-03 14:43:30 -0700141 eventChannel.getAllEntries();
142 Collection<EventEntry<TopologyEvent>> collection =
143 new LinkedList<EventEntry<TopologyEvent>>();
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800144
Ray Milkey5df613b2014-04-15 10:50:56 -0700145 for (TopologyEvent topologyEvent : allTopologyEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700146 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;
Ray Milkey0b122ed2014-04-14 10:06:03 -0700266 default:
267 log.error("Unknown topology event {}",
268 event.eventType());
Ray Milkey269ffb92014-04-03 14:43:30 -0700269 }
270 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800271
Ray Milkey269ffb92014-04-03 14:43:30 -0700272 //
273 // Lock the Network Graph while it is modified
274 //
275 networkGraph.acquireWriteLock();
Pavlin Radoslavov8ffb8bf2014-02-20 15:34:26 -0800276
Ray Milkey269ffb92014-04-03 14:43:30 -0700277 try {
278 //
279 // Apply the classified events.
280 //
281 // Apply the "add" events in the proper order:
282 // switch, port, link, device
283 //
Ray Milkeyb29e6262014-04-09 16:02:14 -0700284 for (SwitchEvent switchEvent : addedSwitchEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700285 addSwitch(switchEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700286 }
287 for (PortEvent portEvent : addedPortEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700288 addPort(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700289 }
290 for (LinkEvent linkEvent : addedLinkEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700291 addLink(linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700292 }
293 for (DeviceEvent deviceEvent : addedDeviceEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700294 addDevice(deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700295 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700296 //
297 // Apply the "remove" events in the reverse order:
298 // device, link, port, switch
299 //
Ray Milkeyb29e6262014-04-09 16:02:14 -0700300 for (DeviceEvent deviceEvent : removedDeviceEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700301 removeDevice(deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700302 }
303 for (LinkEvent linkEvent : removedLinkEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700304 removeLink(linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700305 }
306 for (PortEvent portEvent : removedPortEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700307 removePort(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700308 }
309 for (SwitchEvent switchEvent : removedSwitchEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700310 removeSwitch(switchEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700311 }
Yuta HIGUCHI3aca81a2014-02-23 12:41:19 -0800312
Ray Milkey269ffb92014-04-03 14:43:30 -0700313 //
314 // Apply reordered events
315 //
316 applyReorderedEvents(!addedSwitchEvents.isEmpty(),
317 !addedPortEvents.isEmpty());
Yuta HIGUCHI3aca81a2014-02-23 12:41:19 -0800318
Ray Milkey269ffb92014-04-03 14:43:30 -0700319 } finally {
320 //
321 // Network Graph modifications completed: Release the lock
322 //
323 networkGraph.releaseWriteLock();
324 }
Yuta HIGUCHI3aca81a2014-02-23 12:41:19 -0800325
Ray Milkey269ffb92014-04-03 14:43:30 -0700326 //
327 // Dispatch the Topology Notification Events to the applications
328 //
329 dispatchNetworkGraphEvents();
330 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800331
Ray Milkey269ffb92014-04-03 14:43:30 -0700332 /**
333 * Receive a notification that an entry is added.
334 *
335 * @param value the value for the entry.
336 */
337 @Override
338 public void entryAdded(TopologyEvent value) {
339 EventEntry<TopologyEvent> eventEntry =
340 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
341 value);
342 topologyEvents.add(eventEntry);
343 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800344
Ray Milkey269ffb92014-04-03 14:43:30 -0700345 /**
346 * Receive a notification that an entry is removed.
347 *
348 * @param value the value for the entry.
349 */
350 @Override
351 public void entryRemoved(TopologyEvent value) {
352 EventEntry<TopologyEvent> eventEntry =
353 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_REMOVE,
354 value);
355 topologyEvents.add(eventEntry);
356 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800357
Ray Milkey269ffb92014-04-03 14:43:30 -0700358 /**
359 * Receive a notification that an entry is updated.
360 *
361 * @param value the value for the entry.
362 */
363 @Override
364 public void entryUpdated(TopologyEvent value) {
365 // NOTE: The ADD and UPDATE events are processed in same way
366 entryAdded(value);
367 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800368 }
369
370 /**
371 * Startup processing.
372 *
373 * @param datagridService the datagrid service to use.
374 */
375 void startup(IDatagridService datagridService) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700376 eventChannel = datagridService.addListener(EVENT_CHANNEL_NAME,
377 eventHandler,
378 byte[].class,
379 TopologyEvent.class);
380 eventHandler.start();
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800381 }
382
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800383 /**
384 * Dispatch Network Graph Events to the listeners.
385 */
386 private void dispatchNetworkGraphEvents() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700387 if (apiAddedSwitchEvents.isEmpty() &&
388 apiRemovedSwitchEvents.isEmpty() &&
389 apiAddedPortEvents.isEmpty() &&
390 apiRemovedPortEvents.isEmpty() &&
391 apiAddedLinkEvents.isEmpty() &&
392 apiRemovedLinkEvents.isEmpty() &&
393 apiAddedDeviceEvents.isEmpty() &&
394 apiRemovedDeviceEvents.isEmpty()) {
395 return; // No events to dispatch
396 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800397
Ray Milkey269ffb92014-04-03 14:43:30 -0700398 if (log.isDebugEnabled()) {
399 //
400 // Debug statements
401 // TODO: Those statements should be removed in the future
402 //
Ray Milkeyb29e6262014-04-09 16:02:14 -0700403 for (SwitchEvent switchEvent : apiAddedSwitchEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700404 log.debug("Dispatch Network Graph Event: ADDED {}", switchEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700405 }
406 for (SwitchEvent switchEvent : apiRemovedSwitchEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700407 log.debug("Dispatch Network Graph Event: REMOVED {}", switchEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700408 }
409 for (PortEvent portEvent : apiAddedPortEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700410 log.debug("Dispatch Network Graph Event: ADDED {}", portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700411 }
412 for (PortEvent portEvent : apiRemovedPortEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700413 log.debug("Dispatch Network Graph Event: REMOVED {}", portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700414 }
415 for (LinkEvent linkEvent : apiAddedLinkEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700416 log.debug("Dispatch Network Graph Event: ADDED {}", linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700417 }
418 for (LinkEvent linkEvent : apiRemovedLinkEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700419 log.debug("Dispatch Network Graph Event: REMOVED {}", linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700420 }
421 for (DeviceEvent deviceEvent : apiAddedDeviceEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700422 log.debug("Dispatch Network Graph Event: ADDED {}", deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700423 }
424 for (DeviceEvent deviceEvent : apiRemovedDeviceEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700425 log.debug("Dispatch Network Graph Event: REMOVED {}", deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700426 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700427 }
adminbc181552014-02-21 18:36:42 -0800428
Ray Milkey269ffb92014-04-03 14:43:30 -0700429 // Deliver the events
430 for (INetworkGraphListener listener : this.networkGraphListeners) {
431 // TODO: Should copy before handing them over to listener?
432 listener.networkGraphEvents(apiAddedSwitchEvents,
433 apiRemovedSwitchEvents,
434 apiAddedPortEvents,
435 apiRemovedPortEvents,
436 apiAddedLinkEvents,
437 apiRemovedLinkEvents,
438 apiAddedDeviceEvents,
439 apiRemovedDeviceEvents);
440 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800441
Ray Milkey269ffb92014-04-03 14:43:30 -0700442 //
443 // Cleanup
444 //
445 apiAddedSwitchEvents.clear();
446 apiRemovedSwitchEvents.clear();
447 apiAddedPortEvents.clear();
448 apiRemovedPortEvents.clear();
449 apiAddedLinkEvents.clear();
450 apiRemovedLinkEvents.clear();
451 apiAddedDeviceEvents.clear();
452 apiRemovedDeviceEvents.clear();
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800453 }
454
455 /**
456 * Apply reordered events.
457 *
458 * @param hasAddedSwitchEvents true if there were Added Switch Events.
Ray Milkey269ffb92014-04-03 14:43:30 -0700459 * @param hasAddedPortEvents true if there were Added Port Events.
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800460 */
461 private void applyReorderedEvents(boolean hasAddedSwitchEvents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700462 boolean hasAddedPortEvents) {
Ray Milkeyb29e6262014-04-09 16:02:14 -0700463 if (!(hasAddedSwitchEvents || hasAddedPortEvents)) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700464 return; // Nothing to do
Ray Milkeyb29e6262014-04-09 16:02:14 -0700465 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800466
Ray Milkey269ffb92014-04-03 14:43:30 -0700467 //
468 // Try to apply the reordered events.
469 //
470 // NOTE: For simplicity we try to apply all events of a particular
471 // type if any "parent" type event was processed:
472 // - Apply reordered Port Events if Switches were added
473 // - Apply reordered Link and Device Events if Switches or Ports
474 // were added
475 //
adminbc181552014-02-21 18:36:42 -0800476
Ray Milkey269ffb92014-04-03 14:43:30 -0700477 //
478 // Apply reordered Port Events if Switches were added
479 //
480 if (hasAddedSwitchEvents) {
481 Map<ByteBuffer, PortEvent> portEvents = reorderedAddedPortEvents;
482 reorderedAddedPortEvents = new HashMap<>();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700483 for (PortEvent portEvent : portEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700484 addPort(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700485 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700486 }
487 //
488 // Apply reordered Link and Device Events if Switches or Ports
489 // were added.
490 //
491 Map<ByteBuffer, LinkEvent> linkEvents = reorderedAddedLinkEvents;
492 reorderedAddedLinkEvents = new HashMap<>();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700493 for (LinkEvent linkEvent : linkEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700494 addLink(linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700495 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700496 //
497 Map<ByteBuffer, DeviceEvent> deviceEvents = reorderedAddedDeviceEvents;
498 reorderedAddedDeviceEvents = new HashMap<>();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700499 for (DeviceEvent deviceEvent : deviceEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700500 addDevice(deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700501 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800502 }
503
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800504 /**
505 * Switch discovered event.
506 *
507 * @param switchEvent the switch event.
Ray Milkey269ffb92014-04-03 14:43:30 -0700508 * @param portEvents the corresponding port events for the switch.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800509 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800510 @Override
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800511 public void putSwitchDiscoveryEvent(SwitchEvent switchEvent,
Ray Milkey269ffb92014-04-03 14:43:30 -0700512 Collection<PortEvent> portEvents) {
513 if (datastore.addSwitch(switchEvent, portEvents)) {
514 // Send out notification
515 TopologyEvent topologyEvent = new TopologyEvent(switchEvent);
516 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800517
Ray Milkey269ffb92014-04-03 14:43:30 -0700518 // Send out notification for each port
519 for (PortEvent portEvent : portEvents) {
520 topologyEvent = new TopologyEvent(portEvent);
521 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
522 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800523
Ray Milkey269ffb92014-04-03 14:43:30 -0700524 //
525 // Keep track of the added ports
526 //
527 // Get the old Port Events
528 Map<ByteBuffer, PortEvent> oldPortEvents =
529 discoveredAddedPortEvents.get(switchEvent.getDpid());
Ray Milkeyb29e6262014-04-09 16:02:14 -0700530 if (oldPortEvents == null) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700531 oldPortEvents = new HashMap<>();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700532 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800533
Ray Milkey269ffb92014-04-03 14:43:30 -0700534 // Store the new Port Events in the local cache
535 Map<ByteBuffer, PortEvent> newPortEvents = new HashMap<>();
536 for (PortEvent portEvent : portEvents) {
537 ByteBuffer id = portEvent.getIDasByteBuffer();
538 newPortEvents.put(id, portEvent);
539 }
540 discoveredAddedPortEvents.put(switchEvent.getDpid(),
541 newPortEvents);
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800542
Ray Milkey269ffb92014-04-03 14:43:30 -0700543 //
544 // Extract the removed ports
545 //
546 List<PortEvent> removedPortEvents = new LinkedList<>();
547 for (Map.Entry<ByteBuffer, PortEvent> entry : oldPortEvents.entrySet()) {
548 ByteBuffer key = entry.getKey();
549 PortEvent portEvent = entry.getValue();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700550 if (!newPortEvents.containsKey(key)) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700551 removedPortEvents.add(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700552 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700553 }
554
555 // Cleanup old removed ports
Ray Milkeyb29e6262014-04-09 16:02:14 -0700556 for (PortEvent portEvent : removedPortEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700557 removePortDiscoveryEvent(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700558 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700559 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800560 }
561
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800562 /**
563 * Switch removed event.
564 *
565 * @param switchEvent the switch event.
566 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800567 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800568 public void removeSwitchDiscoveryEvent(SwitchEvent switchEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700569 // Get the old Port Events
570 Map<ByteBuffer, PortEvent> oldPortEvents =
571 discoveredAddedPortEvents.get(switchEvent.getDpid());
Ray Milkeyb29e6262014-04-09 16:02:14 -0700572 if (oldPortEvents == null) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700573 oldPortEvents = new HashMap<>();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700574 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800575
Ray Milkey269ffb92014-04-03 14:43:30 -0700576 if (datastore.deactivateSwitch(switchEvent, oldPortEvents.values())) {
577 // Send out notification
578 eventChannel.removeEntry(switchEvent.getID());
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800579
Ray Milkey269ffb92014-04-03 14:43:30 -0700580 //
581 // Send out notification for each port.
582 //
583 // NOTE: We don't use removePortDiscoveryEvent() for the cleanup,
584 // because it will attempt to remove the port from the database,
585 // and the deactiveSwitch() call above already removed all ports.
586 //
Ray Milkeyb29e6262014-04-09 16:02:14 -0700587 for (PortEvent portEvent : oldPortEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700588 eventChannel.removeEntry(portEvent.getID());
Ray Milkeyb29e6262014-04-09 16:02:14 -0700589 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700590 discoveredAddedPortEvents.remove(switchEvent.getDpid());
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800591
Ray Milkey269ffb92014-04-03 14:43:30 -0700592 // Cleanup for each link
593 Map<ByteBuffer, LinkEvent> oldLinkEvents =
594 discoveredAddedLinkEvents.get(switchEvent.getDpid());
595 if (oldLinkEvents != null) {
596 for (LinkEvent linkEvent : new ArrayList<>(oldLinkEvents.values())) {
597 removeLinkDiscoveryEvent(linkEvent);
598 }
599 discoveredAddedLinkEvents.remove(switchEvent.getDpid());
600 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800601
Ray Milkey269ffb92014-04-03 14:43:30 -0700602 // Cleanup for each device
603 Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
604 discoveredAddedDeviceEvents.get(switchEvent.getDpid());
605 if (oldDeviceEvents != null) {
606 for (DeviceEvent deviceEvent : new ArrayList<>(oldDeviceEvents.values())) {
607 removeDeviceDiscoveryEvent(deviceEvent);
608 }
609 discoveredAddedDeviceEvents.remove(switchEvent.getDpid());
610 }
611 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800612 }
613
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800614 /**
615 * Port discovered event.
616 *
617 * @param portEvent the port event.
618 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800619 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800620 public void putPortDiscoveryEvent(PortEvent portEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700621 if (datastore.addPort(portEvent)) {
622 // Send out notification
623 TopologyEvent topologyEvent = new TopologyEvent(portEvent);
624 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800625
Ray Milkey269ffb92014-04-03 14:43:30 -0700626 // Store the new Port Event in the local cache
627 Map<ByteBuffer, PortEvent> oldPortEvents =
628 discoveredAddedPortEvents.get(portEvent.getDpid());
629 if (oldPortEvents == null) {
630 oldPortEvents = new HashMap<>();
631 discoveredAddedPortEvents.put(portEvent.getDpid(),
632 oldPortEvents);
633 }
634 ByteBuffer id = portEvent.getIDasByteBuffer();
635 oldPortEvents.put(id, portEvent);
636 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800637 }
638
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800639 /**
640 * Port removed event.
641 *
642 * @param portEvent the port event.
643 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800644 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800645 public void removePortDiscoveryEvent(PortEvent portEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700646 if (datastore.deactivatePort(portEvent)) {
647 // Send out notification
648 eventChannel.removeEntry(portEvent.getID());
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800649
Ray Milkey269ffb92014-04-03 14:43:30 -0700650 // Cleanup the Port Event from the local cache
651 Map<ByteBuffer, PortEvent> oldPortEvents =
652 discoveredAddedPortEvents.get(portEvent.getDpid());
653 if (oldPortEvents != null) {
654 ByteBuffer id = portEvent.getIDasByteBuffer();
655 oldPortEvents.remove(id);
656 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800657
Ray Milkey269ffb92014-04-03 14:43:30 -0700658 // Cleanup for the incoming link
659 Map<ByteBuffer, LinkEvent> oldLinkEvents =
660 discoveredAddedLinkEvents.get(portEvent.getDpid());
661 if (oldLinkEvents != null) {
662 for (LinkEvent linkEvent : new ArrayList<>(oldLinkEvents.values())) {
663 if (linkEvent.getDst().equals(portEvent.id)) {
664 removeLinkDiscoveryEvent(linkEvent);
665 // XXX If we change our model to allow multiple Link on
666 // a Port, this loop must be fixed to allow continuing.
667 break;
668 }
669 }
670 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800671
Ray Milkey269ffb92014-04-03 14:43:30 -0700672 // Cleanup for the connected devices
673 // TODO: The implementation below is probably wrong
674 List<DeviceEvent> removedDeviceEvents = new LinkedList<>();
675 Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
676 discoveredAddedDeviceEvents.get(portEvent.getDpid());
677 if (oldDeviceEvents != null) {
678 for (DeviceEvent deviceEvent : new ArrayList<>(oldDeviceEvents.values())) {
679 for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
680 if (swp.equals(portEvent.id)) {
681 removedDeviceEvents.add(deviceEvent);
682 }
683 }
684 }
Ray Milkeyb29e6262014-04-09 16:02:14 -0700685 for (DeviceEvent deviceEvent : removedDeviceEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700686 removeDeviceDiscoveryEvent(deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700687 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700688 }
689 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800690 }
691
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800692 /**
693 * Link discovered event.
694 *
695 * @param linkEvent the link event.
696 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800697 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800698 public void putLinkDiscoveryEvent(LinkEvent linkEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700699 if (datastore.addLink(linkEvent)) {
700 // Send out notification
701 TopologyEvent topologyEvent = new TopologyEvent(linkEvent);
702 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800703
Ray Milkey269ffb92014-04-03 14:43:30 -0700704 // Store the new Link Event in the local cache
705 Map<ByteBuffer, LinkEvent> oldLinkEvents =
706 discoveredAddedLinkEvents.get(linkEvent.getDst().getDpid());
707 if (oldLinkEvents == null) {
708 oldLinkEvents = new HashMap<>();
709 discoveredAddedLinkEvents.put(linkEvent.getDst().getDpid(),
710 oldLinkEvents);
711 }
712 ByteBuffer id = linkEvent.getIDasByteBuffer();
713 oldLinkEvents.put(id, linkEvent);
714 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800715 }
716
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800717 /**
718 * Link removed event.
719 *
720 * @param linkEvent the link event.
721 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800722 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800723 public void removeLinkDiscoveryEvent(LinkEvent linkEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700724 if (datastore.removeLink(linkEvent)) {
725 // Send out notification
726 eventChannel.removeEntry(linkEvent.getID());
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800727
Ray Milkey269ffb92014-04-03 14:43:30 -0700728 // Cleanup the Link Event from the local cache
729 Map<ByteBuffer, LinkEvent> oldLinkEvents =
730 discoveredAddedLinkEvents.get(linkEvent.getDst().getDpid());
731 if (oldLinkEvents != null) {
732 ByteBuffer id = linkEvent.getIDasByteBuffer();
733 oldLinkEvents.remove(id);
734 }
735 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800736 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800737
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800738 /**
739 * Device discovered event.
740 *
741 * @param deviceEvent the device event.
742 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800743 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800744 public void putDeviceDiscoveryEvent(DeviceEvent deviceEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700745 if (datastore.addDevice(deviceEvent)) {
746 // Send out notification
747 TopologyEvent topologyEvent = new TopologyEvent(deviceEvent);
748 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
749 log.debug("Put the device info into the cache of the graph. mac {}", deviceEvent.getMac());
750
751 // Store the new Device Event in the local cache
752 // TODO: The implementation below is probably wrong
753 for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
754 Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
755 discoveredAddedDeviceEvents.get(swp.getDpid());
756 if (oldDeviceEvents == null) {
757 oldDeviceEvents = new HashMap<>();
758 discoveredAddedDeviceEvents.put(swp.getDpid(),
759 oldDeviceEvents);
760 }
761 ByteBuffer id = deviceEvent.getIDasByteBuffer();
762 oldDeviceEvents.put(id, deviceEvent);
763 }
764 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800765 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800766
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800767 /**
768 * Device removed event.
769 *
770 * @param deviceEvent the device event.
771 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800772 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800773 public void removeDeviceDiscoveryEvent(DeviceEvent deviceEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700774 if (datastore.removeDevice(deviceEvent)) {
775 // Send out notification
776 eventChannel.removeEntry(deviceEvent.getID());
777 log.debug("Remove the device info into the cache of the graph. mac {}", deviceEvent.getMac());
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800778
Ray Milkey269ffb92014-04-03 14:43:30 -0700779 // Cleanup the Device Event from the local cache
780 // TODO: The implementation below is probably wrong
781 ByteBuffer id = ByteBuffer.wrap(deviceEvent.getID());
782 for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
783 Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
784 discoveredAddedDeviceEvents.get(swp.getDpid());
785 if (oldDeviceEvents != null) {
786 oldDeviceEvents.remove(id);
787 }
788 }
789 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800790 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800791
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800792 /**
793 * Add a switch to the Network Graph.
794 *
795 * @param switchEvent the Switch Event with the switch to add.
796 */
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800797 private void addSwitch(SwitchEvent switchEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700798 Switch sw = networkGraph.getSwitch(switchEvent.getDpid());
799 if (sw == null) {
800 sw = new SwitchImpl(networkGraph, switchEvent.getDpid());
801 networkGraph.putSwitch(sw);
802 } else {
803 // TODO: Update the switch attributes
804 // TODO: Nothing to do for now
Ray Milkey1aa71f82014-04-08 16:23:24 -0700805 log.debug("Update switch attributes");
Ray Milkey269ffb92014-04-03 14:43:30 -0700806 }
807 apiAddedSwitchEvents.add(switchEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800808 }
809
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800810 /**
811 * Remove a switch from the Network Graph.
812 *
813 * @param switchEvent the Switch Event with the switch to remove.
814 */
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800815 private void removeSwitch(SwitchEvent switchEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700816 Switch sw = networkGraph.getSwitch(switchEvent.getDpid());
817 if (sw == null) {
818 log.warn("Switch {} already removed, ignoring", switchEvent);
819 return;
820 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800821
Ray Milkey269ffb92014-04-03 14:43:30 -0700822 //
823 // Remove all Ports on the Switch
824 //
825 ArrayList<PortEvent> portsToRemove = new ArrayList<>();
826 for (Port port : sw.getPorts()) {
827 log.warn("Port {} on Switch {} should be removed prior to removing Switch. Removing Port now.",
828 port, switchEvent);
829 PortEvent portEvent = new PortEvent(port.getDpid(),
830 port.getNumber());
831 portsToRemove.add(portEvent);
832 }
Ray Milkeyb29e6262014-04-09 16:02:14 -0700833 for (PortEvent portEvent : portsToRemove) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700834 removePort(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700835 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800836
Ray Milkey269ffb92014-04-03 14:43:30 -0700837 networkGraph.removeSwitch(switchEvent.getDpid());
838 apiRemovedSwitchEvents.add(switchEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800839 }
840
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800841 /**
842 * Add a port to the Network Graph.
843 *
844 * @param portEvent the Port Event with the port to add.
845 */
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800846 private void addPort(PortEvent portEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700847 Switch sw = networkGraph.getSwitch(portEvent.getDpid());
848 if (sw == null) {
849 // Reordered event: delay the event in local cache
850 ByteBuffer id = portEvent.getIDasByteBuffer();
851 reorderedAddedPortEvents.put(id, portEvent);
852 return;
853 }
854 SwitchImpl switchImpl = getSwitchImpl(sw);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800855
Ray Milkey269ffb92014-04-03 14:43:30 -0700856 Port port = sw.getPort(portEvent.getNumber());
857 if (port == null) {
858 port = new PortImpl(networkGraph, sw, portEvent.getNumber());
859 switchImpl.addPort(port);
860 } else {
861 // TODO: Update the port attributes
Ray Milkey1aa71f82014-04-08 16:23:24 -0700862 log.debug("Update port attributes");
Ray Milkey269ffb92014-04-03 14:43:30 -0700863 }
864 apiAddedPortEvents.add(portEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800865 }
866
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800867 /**
868 * Remove a port from the Network Graph.
869 *
870 * @param portEvent the Port Event with the port to remove.
871 */
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800872 private void removePort(PortEvent portEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700873 Switch sw = networkGraph.getSwitch(portEvent.getDpid());
874 if (sw == null) {
875 log.warn("Parent Switch for Port {} already removed, ignoring",
876 portEvent);
877 return;
878 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800879
Ray Milkey269ffb92014-04-03 14:43:30 -0700880 Port port = sw.getPort(portEvent.getNumber());
881 if (port == null) {
882 log.warn("Port {} already removed, ignoring", portEvent);
883 return;
884 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800885
Ray Milkey269ffb92014-04-03 14:43:30 -0700886 //
887 // Remove all Devices attached to the Port
888 //
889 ArrayList<DeviceEvent> devicesToRemove = new ArrayList<>();
890 for (Device device : port.getDevices()) {
891 log.debug("Removing Device {} on Port {}", device, portEvent);
892 DeviceEvent deviceEvent = new DeviceEvent(device.getMacAddress());
893 SwitchPort switchPort = new SwitchPort(port.getSwitch().getDpid(),
894 port.getNumber());
895 deviceEvent.addAttachmentPoint(switchPort);
896 devicesToRemove.add(deviceEvent);
897 }
Ray Milkeyb29e6262014-04-09 16:02:14 -0700898 for (DeviceEvent deviceEvent : devicesToRemove) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700899 removeDevice(deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700900 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800901
Ray Milkey269ffb92014-04-03 14:43:30 -0700902 //
903 // Remove all Links connected to the Port
904 //
905 Set<Link> links = new HashSet<>();
906 links.add(port.getOutgoingLink());
907 links.add(port.getIncomingLink());
908 ArrayList<LinkEvent> linksToRemove = new ArrayList<>();
909 for (Link link : links) {
Ray Milkeyb29e6262014-04-09 16:02:14 -0700910 if (link == null) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700911 continue;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700912 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700913 log.debug("Removing Link {} on Port {}", link, portEvent);
914 LinkEvent linkEvent = new LinkEvent(link.getSrcSwitch().getDpid(),
915 link.getSrcPort().getNumber(),
916 link.getDstSwitch().getDpid(),
917 link.getDstPort().getNumber());
918 linksToRemove.add(linkEvent);
919 }
Ray Milkeyb29e6262014-04-09 16:02:14 -0700920 for (LinkEvent linkEvent : linksToRemove) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700921 removeLink(linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700922 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800923
Ray Milkey269ffb92014-04-03 14:43:30 -0700924 // Remove the Port from the Switch
925 SwitchImpl switchImpl = getSwitchImpl(sw);
926 switchImpl.removePort(port);
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800927
Ray Milkey269ffb92014-04-03 14:43:30 -0700928 apiRemovedPortEvents.add(portEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800929 }
930
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800931 /**
932 * Add a link to the Network Graph.
933 *
934 * @param linkEvent the Link Event with the link to add.
935 */
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800936 private void addLink(LinkEvent linkEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700937 Port srcPort = networkGraph.getPort(linkEvent.getSrc().dpid,
938 linkEvent.getSrc().number);
939 Port dstPort = networkGraph.getPort(linkEvent.getDst().dpid,
940 linkEvent.getDst().number);
941 if ((srcPort == null) || (dstPort == null)) {
942 // Reordered event: delay the event in local cache
943 ByteBuffer id = linkEvent.getIDasByteBuffer();
944 reorderedAddedLinkEvents.put(id, linkEvent);
945 return;
946 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800947
Ray Milkey269ffb92014-04-03 14:43:30 -0700948 // Get the Link instance from the Destination Port Incoming Link
949 Link link = dstPort.getIncomingLink();
950 assert (link == srcPort.getOutgoingLink());
951 if (link == null) {
952 link = new LinkImpl(networkGraph, srcPort, dstPort);
953 PortImpl srcPortImpl = getPortImpl(srcPort);
954 PortImpl dstPortImpl = getPortImpl(dstPort);
955 srcPortImpl.setOutgoingLink(link);
956 dstPortImpl.setIncomingLink(link);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800957
Ray Milkey269ffb92014-04-03 14:43:30 -0700958 // Remove all Devices attached to the Ports
959 ArrayList<DeviceEvent> devicesToRemove = new ArrayList<>();
960 ArrayList<Port> ports = new ArrayList<>();
961 ports.add(srcPort);
962 ports.add(dstPort);
963 for (Port port : ports) {
964 for (Device device : port.getDevices()) {
965 log.error("Device {} on Port {} should have been removed prior to adding Link {}",
966 device, port, linkEvent);
967 DeviceEvent deviceEvent =
968 new DeviceEvent(device.getMacAddress());
969 SwitchPort switchPort =
970 new SwitchPort(port.getSwitch().getDpid(),
971 port.getNumber());
972 deviceEvent.addAttachmentPoint(switchPort);
973 devicesToRemove.add(deviceEvent);
974 }
975 }
Ray Milkeyb29e6262014-04-09 16:02:14 -0700976 for (DeviceEvent deviceEvent : devicesToRemove) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700977 removeDevice(deviceEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700978 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700979 } else {
980 // TODO: Update the link attributes
Ray Milkey1aa71f82014-04-08 16:23:24 -0700981 log.debug("Update link attributes");
Ray Milkey269ffb92014-04-03 14:43:30 -0700982 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800983
Ray Milkey269ffb92014-04-03 14:43:30 -0700984 apiAddedLinkEvents.add(linkEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800985 }
986
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800987 /**
988 * Remove a link from the Network Graph.
989 *
990 * @param linkEvent the Link Event with the link to remove.
991 */
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800992 private void removeLink(LinkEvent linkEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700993 Port srcPort = networkGraph.getPort(linkEvent.getSrc().dpid,
994 linkEvent.getSrc().number);
995 if (srcPort == null) {
996 log.warn("Src Port for Link {} already removed, ignoring",
997 linkEvent);
998 return;
999 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001000
Ray Milkey269ffb92014-04-03 14:43:30 -07001001 Port dstPort = networkGraph.getPort(linkEvent.getDst().dpid,
1002 linkEvent.getDst().number);
1003 if (dstPort == null) {
1004 log.warn("Dst Port for Link {} already removed, ignoring",
1005 linkEvent);
1006 return;
1007 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001008
Ray Milkey269ffb92014-04-03 14:43:30 -07001009 //
1010 // Remove the Link instance from the Destination Port Incoming Link
1011 // and the Source Port Outgoing Link.
1012 //
1013 Link link = dstPort.getIncomingLink();
1014 if (link == null) {
1015 log.warn("Link {} already removed on destination Port", linkEvent);
1016 }
1017 link = srcPort.getOutgoingLink();
1018 if (link == null) {
1019 log.warn("Link {} already removed on src Port", linkEvent);
1020 }
1021 getPortImpl(dstPort).setIncomingLink(null);
1022 getPortImpl(srcPort).setOutgoingLink(null);
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -08001023
Ray Milkey269ffb92014-04-03 14:43:30 -07001024 apiRemovedLinkEvents.add(linkEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001025 }
1026
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001027 /**
1028 * Add a device to the Network Graph.
Ray Milkey269ffb92014-04-03 14:43:30 -07001029 * <p/>
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001030 * TODO: Device-related work is incomplete.
1031 * TODO: Eventually, we might need to consider reordering
1032 * or addLink() and addDevice() events on the same port.
1033 *
1034 * @param deviceEvent the Device Event with the device to add.
1035 */
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001036 private void addDevice(DeviceEvent deviceEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -07001037 Device device = networkGraph.getDeviceByMac(deviceEvent.getMac());
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001038
Ray Milkey269ffb92014-04-03 14:43:30 -07001039 if (device == null) {
1040 log.debug("Existing device was not found in networkGraph. New device. mac {}", deviceEvent.getMac());
1041 device = new DeviceImpl(networkGraph, deviceEvent.getMac());
1042 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001043
Ray Milkey269ffb92014-04-03 14:43:30 -07001044 DeviceImpl deviceImpl = getDeviceImpl(device);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001045
Ray Milkey269ffb92014-04-03 14:43:30 -07001046 // Update the IP addresses
Ray Milkeyb29e6262014-04-09 16:02:14 -07001047 for (InetAddress ipAddr : deviceEvent.getIpAddresses()) {
Ray Milkey269ffb92014-04-03 14:43:30 -07001048 deviceImpl.addIpAddress(ipAddr);
Ray Milkeyb29e6262014-04-09 16:02:14 -07001049 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001050
Ray Milkey269ffb92014-04-03 14:43:30 -07001051 // Process each attachment point
1052 boolean attachmentFound = false;
1053 for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
1054 // Attached Ports must exist
1055 Port port = networkGraph.getPort(swp.dpid, swp.number);
1056 if (port == null) {
1057 // Reordered event: delay the event in local cache
1058 ByteBuffer id = deviceEvent.getIDasByteBuffer();
1059 reorderedAddedDeviceEvents.put(id, deviceEvent);
1060 continue;
1061 }
1062 // Attached Ports must not have Link
1063 if (port.getOutgoingLink() != null ||
1064 port.getIncomingLink() != null) {
1065 log.warn("Link (Out:{},In:{}) exist on the attachment point, skipping mutation.",
1066 port.getOutgoingLink(),
1067 port.getIncomingLink());
1068 continue;
1069 }
1070
1071 // Add Device <-> Port attachment
1072 PortImpl portImpl = getPortImpl(port);
1073 portImpl.addDevice(device);
1074 deviceImpl.addAttachmentPoint(port);
1075 attachmentFound = true;
1076 }
1077
1078 // Update the device in the Network Graph
1079 if (attachmentFound) {
1080 log.debug("Storing the info into networkGraph. mac {}", deviceEvent.getMac());
1081 networkGraph.putDevice(device);
1082 apiAddedDeviceEvents.add(deviceEvent);
1083 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001084 }
1085
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001086 /**
1087 * Remove a device from the Network Graph.
Ray Milkey269ffb92014-04-03 14:43:30 -07001088 * <p/>
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001089 * TODO: Device-related work is incomplete.
1090 *
1091 * @param deviceEvent the Device Event with the device to remove.
1092 */
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001093 private void removeDevice(DeviceEvent deviceEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -07001094 Device device = networkGraph.getDeviceByMac(deviceEvent.getMac());
1095 if (device == null) {
1096 log.warn("Device {} already removed, ignoring", deviceEvent);
1097 return;
1098 }
1099 DeviceImpl deviceImpl = getDeviceImpl(device);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001100
Ray Milkey269ffb92014-04-03 14:43:30 -07001101 // Process each attachment point
1102 for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
1103 // Attached Ports must exist
1104 Port port = networkGraph.getPort(swp.dpid, swp.number);
1105 if (port == null) {
1106 log.warn("Port for the attachment point {} did not exist. skipping attachment point mutation", swp);
1107 continue;
1108 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001109
Ray Milkey269ffb92014-04-03 14:43:30 -07001110 // Remove Device <-> Port attachment
1111 PortImpl portImpl = getPortImpl(port);
1112 portImpl.removeDevice(device);
1113 deviceImpl.removeAttachmentPoint(port);
1114 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -08001115
Ray Milkey269ffb92014-04-03 14:43:30 -07001116 networkGraph.removeDevice(device);
1117 apiRemovedDeviceEvents.add(deviceEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001118 }
Jonathan Hart22eb9882014-02-11 15:52:59 -08001119
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001120 /**
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001121 * Get the SwitchImpl-casted switch implementation.
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001122 *
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001123 * @param sw the Switch to cast.
1124 * @return the SwitchImpl-casted switch implementation.
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001125 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001126 private SwitchImpl getSwitchImpl(Switch sw) {
Ray Milkey269ffb92014-04-03 14:43:30 -07001127 if (sw instanceof SwitchImpl) {
1128 return (SwitchImpl) sw;
1129 }
1130 throw new ClassCastException("SwitchImpl expected, but found: " + sw);
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001131 }
1132
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001133 /**
1134 * Get the PortImpl-casted port implementation.
1135 *
1136 * @param port the Port to cast.
1137 * @return the PortImpl-casted port implementation.
1138 */
1139 private PortImpl getPortImpl(Port port) {
Ray Milkey269ffb92014-04-03 14:43:30 -07001140 if (port instanceof PortImpl) {
1141 return (PortImpl) port;
1142 }
1143 throw new ClassCastException("PortImpl expected, but found: " + port);
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001144 }
1145
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001146 /**
1147 * Get the LinkImpl-casted link implementation.
1148 *
1149 * @param link the Link to cast.
1150 * @return the LinkImpl-casted link implementation.
1151 */
1152 private LinkImpl getLinkImpl(Link link) {
Ray Milkey269ffb92014-04-03 14:43:30 -07001153 if (link instanceof LinkImpl) {
1154 return (LinkImpl) link;
1155 }
1156 throw new ClassCastException("LinkImpl expected, but found: " + link);
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001157 }
1158
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001159 /**
1160 * Get the DeviceImpl-casted device implementation.
1161 *
1162 * @param device the Device to cast.
1163 * @return the DeviceImpl-casted device implementation.
1164 */
1165 private DeviceImpl getDeviceImpl(Device device) {
Ray Milkey269ffb92014-04-03 14:43:30 -07001166 if (device instanceof DeviceImpl) {
1167 return (DeviceImpl) device;
1168 }
1169 throw new ClassCastException("DeviceImpl expected, but found: " + device);
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001170 }
1171
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001172 /**
1173 * Read the whole topology from the database.
1174 *
1175 * @return a collection of EventEntry-encapsulated Topology Events for
1176 * the whole topology.
1177 */
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001178 private Collection<EventEntry<TopologyEvent>> readWholeTopologyFromDB() {
Ray Milkey269ffb92014-04-03 14:43:30 -07001179 Collection<EventEntry<TopologyEvent>> collection =
1180 new LinkedList<EventEntry<TopologyEvent>>();
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001181
Ray Milkey269ffb92014-04-03 14:43:30 -07001182 // XXX May need to clear whole topology first, depending on
1183 // how we initially subscribe to replication events
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001184
Ray Milkey269ffb92014-04-03 14:43:30 -07001185 // Add all active switches
1186 for (KVSwitch sw : KVSwitch.getAllSwitches()) {
1187 if (sw.getStatus() != KVSwitch.STATUS.ACTIVE) {
1188 continue;
1189 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001190
Ray Milkey269ffb92014-04-03 14:43:30 -07001191 SwitchEvent switchEvent = new SwitchEvent(sw.getDpid());
1192 TopologyEvent topologyEvent = new TopologyEvent(switchEvent);
1193 EventEntry<TopologyEvent> eventEntry =
1194 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
1195 topologyEvent);
1196 collection.add(eventEntry);
1197 }
Yuta HIGUCHIa536e762014-02-17 21:47:28 -08001198
Ray Milkey269ffb92014-04-03 14:43:30 -07001199 // Add all active ports
1200 for (KVPort p : KVPort.getAllPorts()) {
1201 if (p.getStatus() != KVPort.STATUS.ACTIVE) {
1202 continue;
1203 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001204
Ray Milkey269ffb92014-04-03 14:43:30 -07001205 PortEvent portEvent = new PortEvent(p.getDpid(), p.getNumber());
1206 TopologyEvent topologyEvent = new TopologyEvent(portEvent);
1207 EventEntry<TopologyEvent> eventEntry =
1208 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
1209 topologyEvent);
1210 collection.add(eventEntry);
1211 }
Yuta HIGUCHIa536e762014-02-17 21:47:28 -08001212
Ray Milkey269ffb92014-04-03 14:43:30 -07001213 // TODO Is Device going to be in DB? If so, read from DB.
1214 // for (KVDevice d : KVDevice.getAllDevices()) {
1215 // DeviceEvent devEvent = new DeviceEvent( MACAddress.valueOf(d.getMac()) );
1216 // for (byte[] portId : d.getAllPortIds() ) {
1217 // devEvent.addAttachmentPoint( new SwitchPort( KVPort.getDpidFromKey(portId), KVPort.getNumberFromKey(portId) ));
1218 // }
1219 // }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001220
Ray Milkey269ffb92014-04-03 14:43:30 -07001221 for (KVLink l : KVLink.getAllLinks()) {
1222 LinkEvent linkEvent = new LinkEvent(l.getSrc().dpid,
1223 l.getSrc().number,
1224 l.getDst().dpid,
1225 l.getDst().number);
1226 TopologyEvent topologyEvent = new TopologyEvent(linkEvent);
1227 EventEntry<TopologyEvent> eventEntry =
1228 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
1229 topologyEvent);
1230 collection.add(eventEntry);
1231 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001232
Ray Milkey269ffb92014-04-03 14:43:30 -07001233 return collection;
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001234 }
Jonathan Hart062a2e82014-02-03 09:41:57 -08001235}