blob: 10fa6be686f82df31c62e688da01615a4082233f [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;
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07005import java.util.Arrays;
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -08006import java.util.Collection;
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07007import java.util.Comparator;
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08008import java.util.HashMap;
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -08009import java.util.HashSet;
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080010import java.util.LinkedList;
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -080011import java.util.List;
Pavlin Radoslavov018d5332014-02-19 23:08:35 -080012import java.util.Map;
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -080013import java.util.Set;
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -070014import java.util.TreeSet;
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080015import java.util.concurrent.BlockingQueue;
Yuta HIGUCHIa536e762014-02-17 21:47:28 -080016import java.util.concurrent.CopyOnWriteArrayList;
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080017import java.util.concurrent.LinkedBlockingQueue;
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -080018
Yuta HIGUCHIbc67a052014-06-30 10:37:09 -070019import javax.annotation.concurrent.GuardedBy;
20
TeruU28adcc32014-04-15 17:57:35 -070021import net.floodlightcontroller.util.MACAddress;
Jonathan Hart6df90172014-04-03 10:13:11 -070022import net.onrc.onos.core.datagrid.IDatagridService;
23import net.onrc.onos.core.datagrid.IEventChannel;
24import net.onrc.onos.core.datagrid.IEventChannelListener;
TeruU28adcc32014-04-15 17:57:35 -070025import net.onrc.onos.core.datastore.topology.KVDevice;
Jonathan Hart6df90172014-04-03 10:13:11 -070026import net.onrc.onos.core.datastore.topology.KVLink;
27import net.onrc.onos.core.datastore.topology.KVPort;
28import net.onrc.onos.core.datastore.topology.KVSwitch;
Pavlin Radoslavovd4f40372014-07-18 16:58:40 -070029import net.onrc.onos.core.metrics.OnosMetrics;
30import net.onrc.onos.core.metrics.OnosMetrics.MetricsComponent;
31import net.onrc.onos.core.metrics.OnosMetrics.MetricsFeature;
Jonathan Hartdeda0ba2014-04-03 11:14:12 -070032import net.onrc.onos.core.registry.IControllerRegistryService;
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -070033import net.onrc.onos.core.util.Dpid;
Jonathan Hart23701d12014-04-03 10:45:48 -070034import net.onrc.onos.core.util.EventEntry;
Yuta HIGUCHIe2a4e172014-07-03 10:50:39 -070035import net.onrc.onos.core.util.PortNumber;
Yuta HIGUCHI5c8cbeb2014-06-27 11:13:48 -070036import net.onrc.onos.core.util.SwitchPort;
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -070037import net.onrc.onos.core.util.serializers.KryoFactory;
Yuta HIGUCHI5c8cbeb2014-06-27 11:13:48 -070038
Jonathan Hart062a2e82014-02-03 09:41:57 -080039import org.slf4j.Logger;
40import org.slf4j.LoggerFactory;
41
Pavlin Radoslavovd4f40372014-07-18 16:58:40 -070042import com.codahale.metrics.Gauge;
43import com.codahale.metrics.Meter;
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -070044import com.esotericsoftware.kryo.Kryo;
45
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -080046/**
Jonathan Harte37e4e22014-05-13 19:12:02 -070047 * The TopologyManager receives topology updates from the southbound discovery
48 * modules and from other ONOS instances. These updates are processed and
49 * applied to the in-memory topology instance.
Ray Milkey269ffb92014-04-03 14:43:30 -070050 * <p/>
Yuta HIGUCHI4bfdd532014-02-07 13:47:36 -080051 * - Maintain Invariant/Relationships between Topology Objects.
Ray Milkey269ffb92014-04-03 14:43:30 -070052 * <p/>
Yuta HIGUCHI765cd0d2014-02-06 12:46:41 -080053 * TODO To be synchronized based on TopologyEvent Notification.
Ray Milkey269ffb92014-04-03 14:43:30 -070054 * <p/>
Yuta HIGUCHIcb951982014-02-11 13:31:44 -080055 * TODO TBD: Caller is expected to maintain parent/child calling order. Parent
Yuta HIGUCHI1c700102014-02-12 16:30:52 -080056 * Object must exist before adding sub component(Add Switch -> Port).
Ray Milkey269ffb92014-04-03 14:43:30 -070057 * <p/>
Yuta HIGUCHI4bfdd532014-02-07 13:47:36 -080058 * TODO TBD: This class may delay the requested change to handle event
59 * re-ordering. e.g.) Link Add came in, but Switch was not there.
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -080060 */
Jonathan Harte37e4e22014-05-13 19:12:02 -070061public class TopologyManager implements TopologyDiscoveryInterface {
Jonathan Hart062a2e82014-02-03 09:41:57 -080062
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080063 private static final Logger log = LoggerFactory
Ray Milkey269ffb92014-04-03 14:43:30 -070064 .getLogger(TopologyManager.class);
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -080065
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080066 private IEventChannel<byte[], TopologyEvent> eventChannel;
Jonathan Hart10a7e2b2014-02-21 18:30:08 -080067 public static final String EVENT_CHANNEL_NAME = "onos.topology";
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080068 private EventHandler eventHandler = new EventHandler();
69
weibitf7c31a42014-06-23 16:51:01 -070070 private TopologyDatastore datastore;
Jonathan Harte37e4e22014-05-13 19:12:02 -070071 private final TopologyImpl topology = new TopologyImpl();
Yuta HIGUCHI170229f2014-02-17 15:47:54 -080072 private final IControllerRegistryService registryService;
Jonathan Harte37e4e22014-05-13 19:12:02 -070073 private CopyOnWriteArrayList<ITopologyListener> topologyListeners;
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -070074 private Kryo kryo = KryoFactory.newKryoObject();
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -080075
Pavlin Radoslavov706add22014-02-20 12:15:59 -080076 //
Pavlin Radoslavovd4f40372014-07-18 16:58:40 -070077 // Metrics
78 //
79 private static final MetricsComponent METRICS_COMPONENT =
80 OnosMetrics.registerComponent("Topology");
81 private static final MetricsFeature METRICS_FEATURE_EVENT_NOTIFICATION =
82 METRICS_COMPONENT.registerFeature("EventNotification");
83 //
Pavlin Radoslavovc49917c2014-07-23 12:16:29 -070084 // Timestamp of the last Topology event (ms from the Epoch)
85 private volatile long lastEventTimestampEpochMs = 0;
86 private final Gauge<Long> gaugeLastEventTimestampEpochMs =
Pavlin Radoslavovd4f40372014-07-18 16:58:40 -070087 OnosMetrics.registerMetric(METRICS_COMPONENT,
88 METRICS_FEATURE_EVENT_NOTIFICATION,
Pavlin Radoslavovc49917c2014-07-23 12:16:29 -070089 "LastEventTimestamp.EpochMs",
Pavlin Radoslavovd4f40372014-07-18 16:58:40 -070090 new Gauge<Long>() {
91 @Override
92 public Long getValue() {
Pavlin Radoslavovc49917c2014-07-23 12:16:29 -070093 return lastEventTimestampEpochMs;
Pavlin Radoslavovd4f40372014-07-18 16:58:40 -070094 }
95 });
96 // Rate of the Topology events published to the Topology listeners
97 private final Meter listenerEventRate =
98 OnosMetrics.createMeter(METRICS_COMPONENT,
99 METRICS_FEATURE_EVENT_NOTIFICATION,
100 "ListenerEventRate");
101
102 //
Pavlin Radoslavov706add22014-02-20 12:15:59 -0800103 // Local state for keeping track of reordered events.
104 // NOTE: Switch Events are not affected by the event reordering.
105 //
106 private Map<ByteBuffer, PortEvent> reorderedAddedPortEvents =
Ray Milkey269ffb92014-04-03 14:43:30 -0700107 new HashMap<ByteBuffer, PortEvent>();
Pavlin Radoslavov706add22014-02-20 12:15:59 -0800108 private Map<ByteBuffer, LinkEvent> reorderedAddedLinkEvents =
Ray Milkey269ffb92014-04-03 14:43:30 -0700109 new HashMap<ByteBuffer, LinkEvent>();
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700110 private Map<ByteBuffer, HostEvent> reorderedAddedHostEvents =
111 new HashMap<ByteBuffer, HostEvent>();
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800112
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800113 //
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800114 // Local state for keeping track of locally discovered events so we can
115 // cleanup properly when a Switch or Port is removed.
116 //
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700117 // We keep all Port, (incoming) Link and Host events per Switch DPID:
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800118 // - If a switch goes down, we remove all corresponding Port, Link and
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700119 // Host events.
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800120 // - If a port on a switch goes down, we remove all corresponding Link
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700121 // and Host events discovered by this instance.
Yuta HIGUCHIbc67a052014-06-30 10:37:09 -0700122 //
123 // How to handle side-effect of remote events.
124 // - Remote Port Down event -> Link Down
125 // Not handled. (XXX Shouldn't it be removed from discovered.. Map)
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700126 // - Remote Host Added -> lose ownership of Host)
Yuta HIGUCHIbc67a052014-06-30 10:37:09 -0700127 // Not handled. (XXX Shouldn't it be removed from discovered.. Map)
128 //
129 // XXX Domain knowledge based invariant maintenance should be moved to
130 // driver module, since the invariant may be different on optical, etc.
131 //
132 // What happens on leadership change?
133 // - Probably should: remove from discovered.. Maps, but not send DELETE events
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700134 // XXX Switch/Port can be rediscovered by new leader, but Link, Host?
Yuta HIGUCHIbc67a052014-06-30 10:37:09 -0700135 // - Current: There is no way to recognize leadership change?
136 // ZookeeperRegistry.requestControl(long, ControlChangeCallback)
137 // is the only way to register listener, and it allows only 1 listener,
138 // which is already used by Controller class.
139 //
140 // FIXME Replace with concurrent variant.
141 // #removeSwitchDiscoveryEvent(SwitchEvent) runs in different thread.
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800142 //
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -0700143 private Map<Dpid, Map<ByteBuffer, PortEvent>> discoveredAddedPortEvents =
Ray Milkey269ffb92014-04-03 14:43:30 -0700144 new HashMap<>();
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -0700145 private Map<Dpid, Map<ByteBuffer, LinkEvent>> discoveredAddedLinkEvents =
Ray Milkey269ffb92014-04-03 14:43:30 -0700146 new HashMap<>();
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700147 private Map<Dpid, Map<ByteBuffer, HostEvent>> discoveredAddedHostEvents =
Ray Milkey269ffb92014-04-03 14:43:30 -0700148 new HashMap<>();
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800149
150 //
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800151 // Local state for keeping track of the application event notifications
152 //
Yuta HIGUCHIbc67a052014-06-30 10:37:09 -0700153 // - Queue of events, which will be dispatched to local listeners
154 // on next notification.
Yuta HIGUCHI703696c2014-06-25 20:36:45 -0700155
156 private List<SwitchEvent> apiAddedSwitchEvents = new LinkedList<>();
157 private List<SwitchEvent> apiRemovedSwitchEvents = new LinkedList<>();
158 private List<PortEvent> apiAddedPortEvents = new LinkedList<>();
159 private List<PortEvent> apiRemovedPortEvents = new LinkedList<>();
160 private List<LinkEvent> apiAddedLinkEvents = new LinkedList<>();
161 private List<LinkEvent> apiRemovedLinkEvents = new LinkedList<>();
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700162 private List<HostEvent> apiAddedHostEvents = new LinkedList<>();
163 private List<HostEvent> apiRemovedHostEvents = new LinkedList<>();
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800164
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800165 /**
166 * Constructor.
167 *
Jonathan Harte37e4e22014-05-13 19:12:02 -0700168 * @param registryService the Registry Service to use.
169 * @param topologyListeners the collection of topology listeners to use.
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800170 */
171 public TopologyManager(IControllerRegistryService registryService,
Jonathan Harte37e4e22014-05-13 19:12:02 -0700172 CopyOnWriteArrayList<ITopologyListener> topologyListeners) {
173 datastore = new TopologyDatastore();
Ray Milkey269ffb92014-04-03 14:43:30 -0700174 this.registryService = registryService;
Jonathan Harte37e4e22014-05-13 19:12:02 -0700175 this.topologyListeners = topologyListeners;
Yuta HIGUCHI80829d12014-02-05 20:16:56 -0800176 }
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -0800177
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800178 /**
Jonathan Harte37e4e22014-05-13 19:12:02 -0700179 * Get the Topology.
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800180 *
Jonathan Harte37e4e22014-05-13 19:12:02 -0700181 * @return the Topology.
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800182 */
Jonathan Harte37e4e22014-05-13 19:12:02 -0700183 Topology getTopology() {
184 return topology;
Pavlin Radoslavov6d224ee2014-02-18 16:43:15 -0800185 }
186
Yuta HIGUCHI4bfdd532014-02-07 13:47:36 -0800187 /**
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800188 * Event handler class.
189 */
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700190 class EventHandler extends Thread implements
Ray Milkey269ffb92014-04-03 14:43:30 -0700191 IEventChannelListener<byte[], TopologyEvent> {
192 private BlockingQueue<EventEntry<TopologyEvent>> topologyEvents =
193 new LinkedBlockingQueue<EventEntry<TopologyEvent>>();
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800194
Ray Milkey269ffb92014-04-03 14:43:30 -0700195 /**
196 * Startup processing.
197 */
198 private void startup() {
199 //
200 // TODO: Read all state from the database:
201 //
202 // Collection<EventEntry<TopologyEvent>> collection =
203 // readWholeTopologyFromDB();
204 //
205 // For now, as a shortcut we read it from the datagrid
206 //
Ray Milkey5df613b2014-04-15 10:50:56 -0700207 Collection<TopologyEvent> allTopologyEvents =
Ray Milkey269ffb92014-04-03 14:43:30 -0700208 eventChannel.getAllEntries();
209 Collection<EventEntry<TopologyEvent>> collection =
210 new LinkedList<EventEntry<TopologyEvent>>();
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800211
Ray Milkey5df613b2014-04-15 10:50:56 -0700212 for (TopologyEvent topologyEvent : allTopologyEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700213 EventEntry<TopologyEvent> eventEntry =
214 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
215 topologyEvent);
216 collection.add(eventEntry);
217 }
218 processEvents(collection);
219 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800220
Ray Milkey269ffb92014-04-03 14:43:30 -0700221 /**
222 * Run the thread.
223 */
224 @Override
225 public void run() {
226 Collection<EventEntry<TopologyEvent>> collection =
227 new LinkedList<EventEntry<TopologyEvent>>();
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800228
Ray Milkey269ffb92014-04-03 14:43:30 -0700229 this.setName("TopologyManager.EventHandler " + this.getId());
230 startup();
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800231
Ray Milkey269ffb92014-04-03 14:43:30 -0700232 //
233 // The main loop
234 //
Pavlin Radoslavov8e881a42014-06-24 16:58:07 -0700235 while (true) {
236 try {
237 EventEntry<TopologyEvent> eventEntry =
238 topologyEvents.take();
Ray Milkey269ffb92014-04-03 14:43:30 -0700239 collection.add(eventEntry);
240 topologyEvents.drainTo(collection);
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800241
Ray Milkey269ffb92014-04-03 14:43:30 -0700242 processEvents(collection);
243 collection.clear();
Pavlin Radoslavov8e881a42014-06-24 16:58:07 -0700244 } catch (Exception exception) {
245 log.debug("Exception processing Topology Events: ",
246 exception);
Ray Milkey269ffb92014-04-03 14:43:30 -0700247 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700248 }
249 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800250
Ray Milkey269ffb92014-04-03 14:43:30 -0700251 /**
252 * Process all topology events.
253 *
254 * @param events the events to process.
255 */
256 private void processEvents(Collection<EventEntry<TopologyEvent>> events) {
257 // Local state for computing the final set of events
258 Map<ByteBuffer, SwitchEvent> addedSwitchEvents = new HashMap<>();
259 Map<ByteBuffer, SwitchEvent> removedSwitchEvents = new HashMap<>();
260 Map<ByteBuffer, PortEvent> addedPortEvents = new HashMap<>();
261 Map<ByteBuffer, PortEvent> removedPortEvents = new HashMap<>();
262 Map<ByteBuffer, LinkEvent> addedLinkEvents = new HashMap<>();
263 Map<ByteBuffer, LinkEvent> removedLinkEvents = new HashMap<>();
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700264 Map<ByteBuffer, HostEvent> addedHostEvents = new HashMap<>();
265 Map<ByteBuffer, HostEvent> removedHostEvents = new HashMap<>();
Pavlin Radoslavov695f8952014-07-23 16:57:01 -0700266 Map<ByteBuffer, MastershipEvent> addedMastershipEvents =
267 new HashMap<>();
268 Map<ByteBuffer, MastershipEvent> removedMastershipEvents =
269 new HashMap<>();
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800270
Ray Milkey269ffb92014-04-03 14:43:30 -0700271 //
272 // Classify and suppress matching events
273 //
274 for (EventEntry<TopologyEvent> event : events) {
275 TopologyEvent topologyEvent = event.eventData();
Pavlin Radoslavova5637c02014-07-30 15:55:11 -0700276 SwitchEvent switchEvent = topologyEvent.getSwitchEvent();
277 PortEvent portEvent = topologyEvent.getPortEvent();
278 LinkEvent linkEvent = topologyEvent.getLinkEvent();
279 HostEvent hostEvent = topologyEvent.getHostEvent();
280 MastershipEvent mastershipEvent = topologyEvent.getMastershipEvent();
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800281
Ray Milkey269ffb92014-04-03 14:43:30 -0700282 //
283 // Extract the events
284 //
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700285 // FIXME Following event squashing logic based only on ID
286 // potentially lose attribute change.
Ray Milkey269ffb92014-04-03 14:43:30 -0700287 switch (event.eventType()) {
288 case ENTRY_ADD:
289 log.debug("Topology event ENTRY_ADD: {}", topologyEvent);
290 if (switchEvent != null) {
291 ByteBuffer id = switchEvent.getIDasByteBuffer();
292 addedSwitchEvents.put(id, switchEvent);
293 removedSwitchEvents.remove(id);
294 // Switch Events are not affected by event reordering
295 }
296 if (portEvent != null) {
297 ByteBuffer id = portEvent.getIDasByteBuffer();
298 addedPortEvents.put(id, portEvent);
299 removedPortEvents.remove(id);
300 reorderedAddedPortEvents.remove(id);
301 }
302 if (linkEvent != null) {
303 ByteBuffer id = linkEvent.getIDasByteBuffer();
304 addedLinkEvents.put(id, linkEvent);
305 removedLinkEvents.remove(id);
306 reorderedAddedLinkEvents.remove(id);
307 }
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700308 if (hostEvent != null) {
309 ByteBuffer id = hostEvent.getIDasByteBuffer();
310 addedHostEvents.put(id, hostEvent);
311 removedHostEvents.remove(id);
312 reorderedAddedHostEvents.remove(id);
Ray Milkey269ffb92014-04-03 14:43:30 -0700313 }
Pavlin Radoslavov695f8952014-07-23 16:57:01 -0700314 if (mastershipEvent != null) {
315 ByteBuffer id = mastershipEvent.getIDasByteBuffer();
316 addedMastershipEvents.put(id, mastershipEvent);
317 removedMastershipEvents.remove(id);
318 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700319 break;
320 case ENTRY_REMOVE:
321 log.debug("Topology event ENTRY_REMOVE: {}", topologyEvent);
322 if (switchEvent != null) {
323 ByteBuffer id = switchEvent.getIDasByteBuffer();
324 addedSwitchEvents.remove(id);
325 removedSwitchEvents.put(id, switchEvent);
326 // Switch Events are not affected by event reordering
327 }
328 if (portEvent != null) {
329 ByteBuffer id = portEvent.getIDasByteBuffer();
330 addedPortEvents.remove(id);
331 removedPortEvents.put(id, portEvent);
332 reorderedAddedPortEvents.remove(id);
333 }
334 if (linkEvent != null) {
335 ByteBuffer id = linkEvent.getIDasByteBuffer();
336 addedLinkEvents.remove(id);
337 removedLinkEvents.put(id, linkEvent);
338 reorderedAddedLinkEvents.remove(id);
339 }
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700340 if (hostEvent != null) {
341 ByteBuffer id = hostEvent.getIDasByteBuffer();
342 addedHostEvents.remove(id);
343 removedHostEvents.put(id, hostEvent);
344 reorderedAddedHostEvents.remove(id);
Ray Milkey269ffb92014-04-03 14:43:30 -0700345 }
Pavlin Radoslavov695f8952014-07-23 16:57:01 -0700346 if (mastershipEvent != null) {
347 ByteBuffer id = mastershipEvent.getIDasByteBuffer();
348 addedMastershipEvents.remove(id);
349 removedMastershipEvents.put(id, mastershipEvent);
350 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700351 break;
Ray Milkey0b122ed2014-04-14 10:06:03 -0700352 default:
353 log.error("Unknown topology event {}",
354 event.eventType());
Ray Milkey269ffb92014-04-03 14:43:30 -0700355 }
356 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800357
Ray Milkey269ffb92014-04-03 14:43:30 -0700358 //
Jonathan Harte37e4e22014-05-13 19:12:02 -0700359 // Lock the topology while it is modified
Ray Milkey269ffb92014-04-03 14:43:30 -0700360 //
Jonathan Harte37e4e22014-05-13 19:12:02 -0700361 topology.acquireWriteLock();
Pavlin Radoslavov8ffb8bf2014-02-20 15:34:26 -0800362
Ray Milkey269ffb92014-04-03 14:43:30 -0700363 try {
364 //
365 // Apply the classified events.
366 //
367 // Apply the "add" events in the proper order:
Pavlin Radoslavov695f8952014-07-23 16:57:01 -0700368 // mastership, switch, port, link, host
Ray Milkey269ffb92014-04-03 14:43:30 -0700369 //
Pavlin Radoslavov695f8952014-07-23 16:57:01 -0700370 // TODO: Currently, the Mastership events are not used,
371 // so their processing ordering is not important (undefined).
372 //
373 for (MastershipEvent mastershipEvent :
374 addedMastershipEvents.values()) {
375 processAddedMastershipEvent(mastershipEvent);
376 }
Ray Milkeyb29e6262014-04-09 16:02:14 -0700377 for (SwitchEvent switchEvent : addedSwitchEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700378 addSwitch(switchEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700379 }
380 for (PortEvent portEvent : addedPortEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700381 addPort(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700382 }
383 for (LinkEvent linkEvent : addedLinkEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700384 addLink(linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700385 }
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700386 for (HostEvent hostEvent : addedHostEvents.values()) {
387 addHost(hostEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700388 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700389 //
390 // Apply the "remove" events in the reverse order:
Pavlin Radoslavov695f8952014-07-23 16:57:01 -0700391 // host, link, port, switch, mastership
Ray Milkey269ffb92014-04-03 14:43:30 -0700392 //
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700393 for (HostEvent hostEvent : removedHostEvents.values()) {
394 removeHost(hostEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700395 }
396 for (LinkEvent linkEvent : removedLinkEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700397 removeLink(linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700398 }
399 for (PortEvent portEvent : removedPortEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700400 removePort(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700401 }
402 for (SwitchEvent switchEvent : removedSwitchEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700403 removeSwitch(switchEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700404 }
Pavlin Radoslavov695f8952014-07-23 16:57:01 -0700405 for (MastershipEvent mastershipEvent :
406 removedMastershipEvents.values()) {
407 processRemovedMastershipEvent(mastershipEvent);
408 }
Yuta HIGUCHI3aca81a2014-02-23 12:41:19 -0800409
Ray Milkey269ffb92014-04-03 14:43:30 -0700410 //
411 // Apply reordered events
412 //
413 applyReorderedEvents(!addedSwitchEvents.isEmpty(),
414 !addedPortEvents.isEmpty());
Yuta HIGUCHI3aca81a2014-02-23 12:41:19 -0800415
Ray Milkey269ffb92014-04-03 14:43:30 -0700416 } finally {
417 //
Jonathan Harte37e4e22014-05-13 19:12:02 -0700418 // Topology modifications completed: Release the lock
Ray Milkey269ffb92014-04-03 14:43:30 -0700419 //
Jonathan Harte37e4e22014-05-13 19:12:02 -0700420 topology.releaseWriteLock();
Ray Milkey269ffb92014-04-03 14:43:30 -0700421 }
Yuta HIGUCHI3aca81a2014-02-23 12:41:19 -0800422
Ray Milkey269ffb92014-04-03 14:43:30 -0700423 //
424 // Dispatch the Topology Notification Events to the applications
425 //
Jonathan Harte37e4e22014-05-13 19:12:02 -0700426 dispatchTopologyEvents();
Ray Milkey269ffb92014-04-03 14:43:30 -0700427 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800428
Ray Milkey269ffb92014-04-03 14:43:30 -0700429 /**
430 * Receive a notification that an entry is added.
431 *
432 * @param value the value for the entry.
433 */
434 @Override
435 public void entryAdded(TopologyEvent value) {
436 EventEntry<TopologyEvent> eventEntry =
437 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
438 value);
439 topologyEvents.add(eventEntry);
440 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800441
Ray Milkey269ffb92014-04-03 14:43:30 -0700442 /**
443 * Receive a notification that an entry is removed.
444 *
445 * @param value the value for the entry.
446 */
447 @Override
448 public void entryRemoved(TopologyEvent value) {
449 EventEntry<TopologyEvent> eventEntry =
450 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_REMOVE,
451 value);
452 topologyEvents.add(eventEntry);
453 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800454
Ray Milkey269ffb92014-04-03 14:43:30 -0700455 /**
456 * Receive a notification that an entry is updated.
457 *
458 * @param value the value for the entry.
459 */
460 @Override
461 public void entryUpdated(TopologyEvent value) {
462 // NOTE: The ADD and UPDATE events are processed in same way
463 entryAdded(value);
464 }
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800465 }
466
467 /**
468 * Startup processing.
469 *
470 * @param datagridService the datagrid service to use.
471 */
472 void startup(IDatagridService datagridService) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700473 eventChannel = datagridService.addListener(EVENT_CHANNEL_NAME,
474 eventHandler,
475 byte[].class,
476 TopologyEvent.class);
477 eventHandler.start();
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800478 }
479
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800480 /**
Jonathan Harte37e4e22014-05-13 19:12:02 -0700481 * Dispatch Topology Events to the listeners.
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800482 */
Jonathan Harte37e4e22014-05-13 19:12:02 -0700483 private void dispatchTopologyEvents() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700484 if (apiAddedSwitchEvents.isEmpty() &&
485 apiRemovedSwitchEvents.isEmpty() &&
486 apiAddedPortEvents.isEmpty() &&
487 apiRemovedPortEvents.isEmpty() &&
488 apiAddedLinkEvents.isEmpty() &&
489 apiRemovedLinkEvents.isEmpty() &&
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700490 apiAddedHostEvents.isEmpty() &&
491 apiRemovedHostEvents.isEmpty()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700492 return; // No events to dispatch
493 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800494
Ray Milkey269ffb92014-04-03 14:43:30 -0700495 if (log.isDebugEnabled()) {
496 //
497 // Debug statements
498 // TODO: Those statements should be removed in the future
499 //
Ray Milkeyb29e6262014-04-09 16:02:14 -0700500 for (SwitchEvent switchEvent : apiAddedSwitchEvents) {
Jonathan Harte37e4e22014-05-13 19:12:02 -0700501 log.debug("Dispatch Topology Event: ADDED {}", switchEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700502 }
503 for (SwitchEvent switchEvent : apiRemovedSwitchEvents) {
Jonathan Harte37e4e22014-05-13 19:12:02 -0700504 log.debug("Dispatch Topology Event: REMOVED {}", switchEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700505 }
506 for (PortEvent portEvent : apiAddedPortEvents) {
Jonathan Harte37e4e22014-05-13 19:12:02 -0700507 log.debug("Dispatch Topology Event: ADDED {}", portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700508 }
509 for (PortEvent portEvent : apiRemovedPortEvents) {
Jonathan Harte37e4e22014-05-13 19:12:02 -0700510 log.debug("Dispatch Topology Event: REMOVED {}", portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700511 }
512 for (LinkEvent linkEvent : apiAddedLinkEvents) {
Jonathan Harte37e4e22014-05-13 19:12:02 -0700513 log.debug("Dispatch Topology Event: ADDED {}", linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700514 }
515 for (LinkEvent linkEvent : apiRemovedLinkEvents) {
Jonathan Harte37e4e22014-05-13 19:12:02 -0700516 log.debug("Dispatch Topology Event: REMOVED {}", linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700517 }
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700518 for (HostEvent hostEvent : apiAddedHostEvents) {
519 log.debug("Dispatch Topology Event: ADDED {}", hostEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700520 }
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700521 for (HostEvent hostEvent : apiRemovedHostEvents) {
522 log.debug("Dispatch Topology Event: REMOVED {}", hostEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700523 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700524 }
adminbc181552014-02-21 18:36:42 -0800525
Pavlin Radoslavovd4f40372014-07-18 16:58:40 -0700526 //
527 // Update the metrics
528 //
529 long totalEvents =
530 apiAddedSwitchEvents.size() + apiRemovedSwitchEvents.size() +
531 apiAddedPortEvents.size() + apiRemovedPortEvents.size() +
532 apiAddedLinkEvents.size() + apiRemovedLinkEvents.size() +
533 apiAddedHostEvents.size() + apiRemovedHostEvents.size();
534 this.listenerEventRate.mark(totalEvents);
Pavlin Radoslavovc49917c2014-07-23 12:16:29 -0700535 this.lastEventTimestampEpochMs = System.currentTimeMillis();
Pavlin Radoslavovd4f40372014-07-18 16:58:40 -0700536
537 //
Ray Milkey269ffb92014-04-03 14:43:30 -0700538 // Deliver the events
Pavlin Radoslavovd4f40372014-07-18 16:58:40 -0700539 //
Jonathan Harte37e4e22014-05-13 19:12:02 -0700540 for (ITopologyListener listener : this.topologyListeners) {
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -0700541 TopologyEvents events =
Pavlin Radoslavovc61544e2014-07-23 16:27:27 -0700542 new TopologyEvents(kryo.copy(apiAddedSwitchEvents),
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -0700543 kryo.copy(apiRemovedSwitchEvents),
544 kryo.copy(apiAddedPortEvents),
545 kryo.copy(apiRemovedPortEvents),
546 kryo.copy(apiAddedLinkEvents),
547 kryo.copy(apiRemovedLinkEvents),
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700548 kryo.copy(apiAddedHostEvents),
549 kryo.copy(apiRemovedHostEvents));
Pavlin Radoslavov4eaab992014-07-03 18:39:42 -0700550 listener.topologyEvents(events);
Ray Milkey269ffb92014-04-03 14:43:30 -0700551 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800552
Ray Milkey269ffb92014-04-03 14:43:30 -0700553 //
554 // Cleanup
555 //
556 apiAddedSwitchEvents.clear();
557 apiRemovedSwitchEvents.clear();
558 apiAddedPortEvents.clear();
559 apiRemovedPortEvents.clear();
560 apiAddedLinkEvents.clear();
561 apiRemovedLinkEvents.clear();
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700562 apiAddedHostEvents.clear();
563 apiRemovedHostEvents.clear();
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800564 }
565
566 /**
567 * Apply reordered events.
568 *
569 * @param hasAddedSwitchEvents true if there were Added Switch Events.
Ray Milkey269ffb92014-04-03 14:43:30 -0700570 * @param hasAddedPortEvents true if there were Added Port Events.
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800571 */
Yuta HIGUCHIbc67a052014-06-30 10:37:09 -0700572 @GuardedBy("topology.writeLock")
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800573 private void applyReorderedEvents(boolean hasAddedSwitchEvents,
Ray Milkey269ffb92014-04-03 14:43:30 -0700574 boolean hasAddedPortEvents) {
Ray Milkeyb29e6262014-04-09 16:02:14 -0700575 if (!(hasAddedSwitchEvents || hasAddedPortEvents)) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700576 return; // Nothing to do
Ray Milkeyb29e6262014-04-09 16:02:14 -0700577 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800578
Ray Milkey269ffb92014-04-03 14:43:30 -0700579 //
580 // Try to apply the reordered events.
581 //
582 // NOTE: For simplicity we try to apply all events of a particular
583 // type if any "parent" type event was processed:
584 // - Apply reordered Port Events if Switches were added
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700585 // - Apply reordered Link and Host Events if Switches or Ports
Ray Milkey269ffb92014-04-03 14:43:30 -0700586 // were added
587 //
adminbc181552014-02-21 18:36:42 -0800588
Ray Milkey269ffb92014-04-03 14:43:30 -0700589 //
590 // Apply reordered Port Events if Switches were added
591 //
592 if (hasAddedSwitchEvents) {
593 Map<ByteBuffer, PortEvent> portEvents = reorderedAddedPortEvents;
594 reorderedAddedPortEvents = new HashMap<>();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700595 for (PortEvent portEvent : portEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700596 addPort(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700597 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700598 }
599 //
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700600 // Apply reordered Link and Host Events if Switches or Ports
Ray Milkey269ffb92014-04-03 14:43:30 -0700601 // were added.
602 //
603 Map<ByteBuffer, LinkEvent> linkEvents = reorderedAddedLinkEvents;
604 reorderedAddedLinkEvents = new HashMap<>();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700605 for (LinkEvent linkEvent : linkEvents.values()) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700606 addLink(linkEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700607 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700608 //
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700609 Map<ByteBuffer, HostEvent> hostEvents = reorderedAddedHostEvents;
610 reorderedAddedHostEvents = new HashMap<>();
611 for (HostEvent hostEvent : hostEvents.values()) {
612 addHost(hostEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700613 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800614 }
615
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800616 /**
617 * Switch discovered event.
618 *
619 * @param switchEvent the switch event.
Ray Milkey269ffb92014-04-03 14:43:30 -0700620 * @param portEvents the corresponding port events for the switch.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800621 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800622 @Override
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800623 public void putSwitchDiscoveryEvent(SwitchEvent switchEvent,
Ray Milkey269ffb92014-04-03 14:43:30 -0700624 Collection<PortEvent> portEvents) {
625 if (datastore.addSwitch(switchEvent, portEvents)) {
Jonathan Hart92c819f2014-05-30 10:53:30 -0700626 log.debug("Sending add switch: {}", switchEvent);
Ray Milkey269ffb92014-04-03 14:43:30 -0700627 // Send out notification
Pavlin Radoslavova5637c02014-07-30 15:55:11 -0700628 TopologyEvent topologyEvent =
629 new TopologyEvent(switchEvent,
630 registryService.getOnosInstanceId());
Ray Milkey269ffb92014-04-03 14:43:30 -0700631 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800632
Ray Milkey269ffb92014-04-03 14:43:30 -0700633 // Send out notification for each port
634 for (PortEvent portEvent : portEvents) {
Jonathan Hart92c819f2014-05-30 10:53:30 -0700635 log.debug("Sending add port: {}", portEvent);
Pavlin Radoslavova5637c02014-07-30 15:55:11 -0700636 topologyEvent =
637 new TopologyEvent(portEvent,
638 registryService.getOnosInstanceId());
Ray Milkey269ffb92014-04-03 14:43:30 -0700639 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
640 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800641
Ray Milkey269ffb92014-04-03 14:43:30 -0700642 //
643 // Keep track of the added ports
644 //
645 // Get the old Port Events
646 Map<ByteBuffer, PortEvent> oldPortEvents =
647 discoveredAddedPortEvents.get(switchEvent.getDpid());
Ray Milkeyb29e6262014-04-09 16:02:14 -0700648 if (oldPortEvents == null) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700649 oldPortEvents = new HashMap<>();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700650 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800651
Ray Milkey269ffb92014-04-03 14:43:30 -0700652 // Store the new Port Events in the local cache
653 Map<ByteBuffer, PortEvent> newPortEvents = new HashMap<>();
654 for (PortEvent portEvent : portEvents) {
655 ByteBuffer id = portEvent.getIDasByteBuffer();
656 newPortEvents.put(id, portEvent);
657 }
658 discoveredAddedPortEvents.put(switchEvent.getDpid(),
659 newPortEvents);
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800660
Ray Milkey269ffb92014-04-03 14:43:30 -0700661 //
662 // Extract the removed ports
663 //
664 List<PortEvent> removedPortEvents = new LinkedList<>();
665 for (Map.Entry<ByteBuffer, PortEvent> entry : oldPortEvents.entrySet()) {
666 ByteBuffer key = entry.getKey();
667 PortEvent portEvent = entry.getValue();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700668 if (!newPortEvents.containsKey(key)) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700669 removedPortEvents.add(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700670 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700671 }
672
673 // Cleanup old removed ports
Ray Milkeyb29e6262014-04-09 16:02:14 -0700674 for (PortEvent portEvent : removedPortEvents) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700675 removePortDiscoveryEvent(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700676 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700677 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800678 }
679
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800680 /**
Yuta HIGUCHIbc67a052014-06-30 10:37:09 -0700681 * {@inheritDoc}
682 * <p/>
683 * Called by {@link TopologyPublisher.SwitchCleanup} thread.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800684 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800685 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800686 public void removeSwitchDiscoveryEvent(SwitchEvent switchEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700687 // Get the old Port Events
688 Map<ByteBuffer, PortEvent> oldPortEvents =
689 discoveredAddedPortEvents.get(switchEvent.getDpid());
Ray Milkeyb29e6262014-04-09 16:02:14 -0700690 if (oldPortEvents == null) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700691 oldPortEvents = new HashMap<>();
Ray Milkeyb29e6262014-04-09 16:02:14 -0700692 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800693
Ray Milkey269ffb92014-04-03 14:43:30 -0700694 if (datastore.deactivateSwitch(switchEvent, oldPortEvents.values())) {
Jonathan Hart92c819f2014-05-30 10:53:30 -0700695 log.debug("Sending remove switch: {}", switchEvent);
Ray Milkey269ffb92014-04-03 14:43:30 -0700696 // Send out notification
697 eventChannel.removeEntry(switchEvent.getID());
Pavlin Radoslavov018d5332014-02-19 23:08:35 -0800698
Ray Milkey269ffb92014-04-03 14:43:30 -0700699 //
700 // Send out notification for each port.
701 //
702 // NOTE: We don't use removePortDiscoveryEvent() for the cleanup,
703 // because it will attempt to remove the port from the database,
704 // and the deactiveSwitch() call above already removed all ports.
705 //
Ray Milkeyb29e6262014-04-09 16:02:14 -0700706 for (PortEvent portEvent : oldPortEvents.values()) {
Jonathan Hart92c819f2014-05-30 10:53:30 -0700707 log.debug("Sending remove port:", portEvent);
Ray Milkey269ffb92014-04-03 14:43:30 -0700708 eventChannel.removeEntry(portEvent.getID());
Ray Milkeyb29e6262014-04-09 16:02:14 -0700709 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700710 discoveredAddedPortEvents.remove(switchEvent.getDpid());
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800711
Ray Milkey269ffb92014-04-03 14:43:30 -0700712 // Cleanup for each link
713 Map<ByteBuffer, LinkEvent> oldLinkEvents =
714 discoveredAddedLinkEvents.get(switchEvent.getDpid());
715 if (oldLinkEvents != null) {
716 for (LinkEvent linkEvent : new ArrayList<>(oldLinkEvents.values())) {
717 removeLinkDiscoveryEvent(linkEvent);
718 }
719 discoveredAddedLinkEvents.remove(switchEvent.getDpid());
720 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800721
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700722 // Cleanup for each host
723 Map<ByteBuffer, HostEvent> oldHostEvents =
724 discoveredAddedHostEvents.get(switchEvent.getDpid());
725 if (oldHostEvents != null) {
726 for (HostEvent hostEvent : new ArrayList<>(oldHostEvents.values())) {
727 removeHostDiscoveryEvent(hostEvent);
Ray Milkey269ffb92014-04-03 14:43:30 -0700728 }
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700729 discoveredAddedHostEvents.remove(switchEvent.getDpid());
Ray Milkey269ffb92014-04-03 14:43:30 -0700730 }
731 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800732 }
733
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800734 /**
735 * Port discovered event.
736 *
737 * @param portEvent the port event.
738 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800739 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800740 public void putPortDiscoveryEvent(PortEvent portEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700741 if (datastore.addPort(portEvent)) {
Jonathan Hart92c819f2014-05-30 10:53:30 -0700742 log.debug("Sending add port: {}", portEvent);
Ray Milkey269ffb92014-04-03 14:43:30 -0700743 // Send out notification
Pavlin Radoslavova5637c02014-07-30 15:55:11 -0700744 TopologyEvent topologyEvent =
745 new TopologyEvent(portEvent,
746 registryService.getOnosInstanceId());
Ray Milkey269ffb92014-04-03 14:43:30 -0700747 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800748
Ray Milkey269ffb92014-04-03 14:43:30 -0700749 // Store the new Port Event in the local cache
750 Map<ByteBuffer, PortEvent> oldPortEvents =
751 discoveredAddedPortEvents.get(portEvent.getDpid());
752 if (oldPortEvents == null) {
753 oldPortEvents = new HashMap<>();
754 discoveredAddedPortEvents.put(portEvent.getDpid(),
755 oldPortEvents);
756 }
757 ByteBuffer id = portEvent.getIDasByteBuffer();
758 oldPortEvents.put(id, portEvent);
759 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800760 }
761
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800762 /**
763 * Port removed event.
764 *
765 * @param portEvent the port event.
766 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800767 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800768 public void removePortDiscoveryEvent(PortEvent portEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700769 if (datastore.deactivatePort(portEvent)) {
Jonathan Hart92c819f2014-05-30 10:53:30 -0700770 log.debug("Sending remove port: {}", portEvent);
Ray Milkey269ffb92014-04-03 14:43:30 -0700771 // Send out notification
772 eventChannel.removeEntry(portEvent.getID());
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800773
Ray Milkey269ffb92014-04-03 14:43:30 -0700774 // Cleanup the Port Event from the local cache
775 Map<ByteBuffer, PortEvent> oldPortEvents =
776 discoveredAddedPortEvents.get(portEvent.getDpid());
777 if (oldPortEvents != null) {
778 ByteBuffer id = portEvent.getIDasByteBuffer();
779 oldPortEvents.remove(id);
780 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800781
Ray Milkey269ffb92014-04-03 14:43:30 -0700782 // Cleanup for the incoming link
783 Map<ByteBuffer, LinkEvent> oldLinkEvents =
784 discoveredAddedLinkEvents.get(portEvent.getDpid());
785 if (oldLinkEvents != null) {
786 for (LinkEvent linkEvent : new ArrayList<>(oldLinkEvents.values())) {
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700787 if (linkEvent.getDst().equals(portEvent.getSwitchPort())) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700788 removeLinkDiscoveryEvent(linkEvent);
789 // XXX If we change our model to allow multiple Link on
790 // a Port, this loop must be fixed to allow continuing.
791 break;
792 }
793 }
794 }
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800795
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700796 // Cleanup for the connected hosts
Ray Milkey269ffb92014-04-03 14:43:30 -0700797 // TODO: The implementation below is probably wrong
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700798 List<HostEvent> removedHostEvents = new LinkedList<>();
799 Map<ByteBuffer, HostEvent> oldHostEvents =
800 discoveredAddedHostEvents.get(portEvent.getDpid());
801 if (oldHostEvents != null) {
802 for (HostEvent hostEvent : new ArrayList<>(oldHostEvents.values())) {
803 for (SwitchPort swp : hostEvent.getAttachmentPoints()) {
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700804 if (swp.equals(portEvent.getSwitchPort())) {
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700805 removedHostEvents.add(hostEvent);
Ray Milkey269ffb92014-04-03 14:43:30 -0700806 }
807 }
808 }
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700809 for (HostEvent hostEvent : removedHostEvents) {
810 removeHostDiscoveryEvent(hostEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700811 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700812 }
813 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800814 }
815
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800816 /**
817 * Link discovered event.
818 *
819 * @param linkEvent the link event.
820 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800821 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800822 public void putLinkDiscoveryEvent(LinkEvent linkEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700823 if (datastore.addLink(linkEvent)) {
Jonathan Hart92c819f2014-05-30 10:53:30 -0700824 log.debug("Sending add link: {}", linkEvent);
Ray Milkey269ffb92014-04-03 14:43:30 -0700825 // Send out notification
Pavlin Radoslavova5637c02014-07-30 15:55:11 -0700826 TopologyEvent topologyEvent =
827 new TopologyEvent(linkEvent,
828 registryService.getOnosInstanceId());
Ray Milkey269ffb92014-04-03 14:43:30 -0700829 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800830
Ray Milkey269ffb92014-04-03 14:43:30 -0700831 // Store the new Link Event in the local cache
832 Map<ByteBuffer, LinkEvent> oldLinkEvents =
833 discoveredAddedLinkEvents.get(linkEvent.getDst().getDpid());
834 if (oldLinkEvents == null) {
835 oldLinkEvents = new HashMap<>();
836 discoveredAddedLinkEvents.put(linkEvent.getDst().getDpid(),
837 oldLinkEvents);
838 }
839 ByteBuffer id = linkEvent.getIDasByteBuffer();
840 oldLinkEvents.put(id, linkEvent);
841 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800842 }
843
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800844 /**
845 * Link removed event.
846 *
847 * @param linkEvent the link event.
848 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800849 @Override
Pavlin Radoslavov6ea84a42014-02-19 15:50:01 -0800850 public void removeLinkDiscoveryEvent(LinkEvent linkEvent) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700851 if (datastore.removeLink(linkEvent)) {
Jonathan Hart92c819f2014-05-30 10:53:30 -0700852 log.debug("Sending remove link: {}", linkEvent);
Ray Milkey269ffb92014-04-03 14:43:30 -0700853 // Send out notification
854 eventChannel.removeEntry(linkEvent.getID());
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800855
Ray Milkey269ffb92014-04-03 14:43:30 -0700856 // Cleanup the Link Event from the local cache
857 Map<ByteBuffer, LinkEvent> oldLinkEvents =
858 discoveredAddedLinkEvents.get(linkEvent.getDst().getDpid());
859 if (oldLinkEvents != null) {
860 ByteBuffer id = linkEvent.getIDasByteBuffer();
861 oldLinkEvents.remove(id);
862 }
863 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800864 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800865
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800866 /**
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700867 * Host discovered event.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800868 *
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700869 * @param hostEvent the host event.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800870 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800871 @Override
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700872 public void putHostDiscoveryEvent(HostEvent hostEvent) {
873 if (datastore.addHost(hostEvent)) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700874 // Send out notification
Pavlin Radoslavova5637c02014-07-30 15:55:11 -0700875 TopologyEvent topologyEvent =
876 new TopologyEvent(hostEvent,
877 registryService.getOnosInstanceId());
Ray Milkey269ffb92014-04-03 14:43:30 -0700878 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700879 log.debug("Put the host info into the cache of the topology. mac {}", hostEvent.getMac());
Ray Milkey269ffb92014-04-03 14:43:30 -0700880
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700881 // Store the new Host Event in the local cache
Ray Milkey269ffb92014-04-03 14:43:30 -0700882 // TODO: The implementation below is probably wrong
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700883 for (SwitchPort swp : hostEvent.getAttachmentPoints()) {
884 Map<ByteBuffer, HostEvent> oldHostEvents =
885 discoveredAddedHostEvents.get(swp.getDpid());
886 if (oldHostEvents == null) {
887 oldHostEvents = new HashMap<>();
888 discoveredAddedHostEvents.put(swp.getDpid(),
889 oldHostEvents);
Ray Milkey269ffb92014-04-03 14:43:30 -0700890 }
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700891 ByteBuffer id = hostEvent.getIDasByteBuffer();
892 oldHostEvents.put(id, hostEvent);
Ray Milkey269ffb92014-04-03 14:43:30 -0700893 }
894 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800895 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800896
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800897 /**
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700898 * Host removed event.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800899 *
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700900 * @param hostEvent the host event.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800901 */
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800902 @Override
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700903 public void removeHostDiscoveryEvent(HostEvent hostEvent) {
904 if (datastore.removeHost(hostEvent)) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700905 // Send out notification
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700906 eventChannel.removeEntry(hostEvent.getID());
907 log.debug("Remove the host info into the cache of the topology. mac {}", hostEvent.getMac());
Pavlin Radoslavov26d83402014-02-20 15:24:30 -0800908
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700909 // Cleanup the Host Event from the local cache
Ray Milkey269ffb92014-04-03 14:43:30 -0700910 // TODO: The implementation below is probably wrong
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700911 ByteBuffer id = ByteBuffer.wrap(hostEvent.getID());
912 for (SwitchPort swp : hostEvent.getAttachmentPoints()) {
913 Map<ByteBuffer, HostEvent> oldHostEvents =
914 discoveredAddedHostEvents.get(swp.getDpid());
915 if (oldHostEvents != null) {
916 oldHostEvents.remove(id);
Ray Milkey269ffb92014-04-03 14:43:30 -0700917 }
918 }
919 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -0800920 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800921
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700922 //
923 // Methods to update topology replica
924 //
925
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800926 /**
Pavlin Radoslavov695f8952014-07-23 16:57:01 -0700927 * Mastership updated event.
928 *
929 * @param mastershipEvent the mastership event.
930 */
931 @Override
932 public void putSwitchMastershipEvent(MastershipEvent mastershipEvent) {
933 // Send out notification
Pavlin Radoslavova5637c02014-07-30 15:55:11 -0700934 TopologyEvent topologyEvent =
935 new TopologyEvent(mastershipEvent,
936 registryService.getOnosInstanceId());
Pavlin Radoslavov695f8952014-07-23 16:57:01 -0700937 eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
938 }
939
940 /**
941 * Mastership removed event.
942 *
943 * @param mastershipEvent the mastership event.
944 */
945 @Override
946 public void removeSwitchMastershipEvent(MastershipEvent mastershipEvent) {
947 // Send out notification
948 eventChannel.removeEntry(mastershipEvent.getID());
949 }
950
951 /**
Yuta HIGUCHI7926ba32014-07-09 11:39:32 -0700952 * Adds a switch to the topology replica.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800953 *
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700954 * @param switchEvent the SwitchEvent with the switch to add.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800955 */
Yuta HIGUCHIbc67a052014-06-30 10:37:09 -0700956 @GuardedBy("topology.writeLock")
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800957 private void addSwitch(SwitchEvent switchEvent) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700958 if (log.isDebugEnabled()) {
959 SwitchEvent sw = topology.getSwitchEvent(switchEvent.getDpid());
960 if (sw != null) {
961 log.debug("Update {}", switchEvent);
962 } else {
963 log.debug("Added {}", switchEvent);
964 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700965 }
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700966 topology.putSwitch(switchEvent.freeze());
Ray Milkey269ffb92014-04-03 14:43:30 -0700967 apiAddedSwitchEvents.add(switchEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800968 }
969
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800970 /**
Yuta HIGUCHI7926ba32014-07-09 11:39:32 -0700971 * Removes a switch from the topology replica.
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700972 * <p/>
973 * It will call {@link #removePort(PortEvent)} for each ports on this switch.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800974 *
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700975 * @param switchEvent the SwitchEvent with the switch to remove.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -0800976 */
Yuta HIGUCHIbc67a052014-06-30 10:37:09 -0700977 @GuardedBy("topology.writeLock")
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -0800978 private void removeSwitch(SwitchEvent switchEvent) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700979 final Dpid dpid = switchEvent.getDpid();
980
981 SwitchEvent swInTopo = topology.getSwitchEvent(dpid);
982 if (swInTopo == null) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700983 log.warn("Switch {} already removed, ignoring", switchEvent);
984 return;
985 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -0800986
Ray Milkey269ffb92014-04-03 14:43:30 -0700987 //
988 // Remove all Ports on the Switch
989 //
990 ArrayList<PortEvent> portsToRemove = new ArrayList<>();
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -0700991 for (Port port : topology.getPorts(dpid)) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700992 log.warn("Port {} on Switch {} should be removed prior to removing Switch. Removing Port now.",
993 port, switchEvent);
Yuta HIGUCHIcd14dda2014-07-24 09:57:22 -0700994 PortEvent portEvent = new PortEvent(port.getSwitchPort());
Ray Milkey269ffb92014-04-03 14:43:30 -0700995 portsToRemove.add(portEvent);
996 }
Ray Milkeyb29e6262014-04-09 16:02:14 -0700997 for (PortEvent portEvent : portsToRemove) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700998 removePort(portEvent);
Ray Milkeyb29e6262014-04-09 16:02:14 -0700999 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001000
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001001 log.debug("Removed {}", swInTopo);
1002 topology.removeSwitch(dpid);
1003 apiRemovedSwitchEvents.add(swInTopo);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001004 }
1005
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001006 /**
Yuta HIGUCHI7926ba32014-07-09 11:39:32 -07001007 * Adds a port to the topology replica.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001008 *
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -07001009 * @param portEvent the PortEvent with the port to add.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001010 */
Yuta HIGUCHIbc67a052014-06-30 10:37:09 -07001011 @GuardedBy("topology.writeLock")
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001012 private void addPort(PortEvent portEvent) {
Jonathan Harte37e4e22014-05-13 19:12:02 -07001013 Switch sw = topology.getSwitch(portEvent.getDpid());
Ray Milkey269ffb92014-04-03 14:43:30 -07001014 if (sw == null) {
Jonathan Hartf1675202014-05-23 14:59:07 -07001015 log.debug("{} reordered because switch is null", portEvent);
Ray Milkey269ffb92014-04-03 14:43:30 -07001016 // Reordered event: delay the event in local cache
1017 ByteBuffer id = portEvent.getIDasByteBuffer();
1018 reorderedAddedPortEvents.put(id, portEvent);
1019 return;
1020 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001021
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001022 if (log.isDebugEnabled()) {
1023 PortEvent port = topology.getPortEvent(portEvent.getSwitchPort());
1024 if (port != null) {
1025 log.debug("Update {}", portEvent);
1026 } else {
1027 log.debug("Added {}", portEvent);
1028 }
Ray Milkey269ffb92014-04-03 14:43:30 -07001029 }
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001030 topology.putPort(portEvent.freeze());
Ray Milkey269ffb92014-04-03 14:43:30 -07001031 apiAddedPortEvents.add(portEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001032 }
1033
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001034 /**
Yuta HIGUCHI7926ba32014-07-09 11:39:32 -07001035 * Removes a port from the topology replica.
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -07001036 * <p/>
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001037 * It will remove attachment points from each hosts on this port
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -07001038 * and call {@link #removeLink(LinkEvent)} for each links on this port.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001039 *
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -07001040 * @param portEvent the PortEvent with the port to remove.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001041 */
Yuta HIGUCHIbc67a052014-06-30 10:37:09 -07001042 @GuardedBy("topology.writeLock")
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001043 private void removePort(PortEvent portEvent) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001044 SwitchEvent sw = topology.getSwitchEvent(portEvent.getDpid());
Ray Milkey269ffb92014-04-03 14:43:30 -07001045 if (sw == null) {
1046 log.warn("Parent Switch for Port {} already removed, ignoring",
1047 portEvent);
1048 return;
1049 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001050
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001051 final SwitchPort switchPort = portEvent.getSwitchPort();
1052 PortEvent portInTopo = topology.getPortEvent(switchPort);
1053 if (portInTopo == null) {
Ray Milkey269ffb92014-04-03 14:43:30 -07001054 log.warn("Port {} already removed, ignoring", portEvent);
1055 return;
1056 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001057
Ray Milkey269ffb92014-04-03 14:43:30 -07001058 //
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001059 // Remove all Host attachment points bound to this Port
Ray Milkey269ffb92014-04-03 14:43:30 -07001060 //
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001061 List<HostEvent> hostsToUpdate = new ArrayList<>();
1062 for (Host host : topology.getHosts(switchPort)) {
1063 log.debug("Removing Host {} on Port {}", host, portInTopo);
1064 HostEvent hostEvent = topology.getHostEvent(host.getMacAddress());
1065 hostsToUpdate.add(hostEvent);
Ray Milkey269ffb92014-04-03 14:43:30 -07001066 }
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001067 for (HostEvent hostEvent : hostsToUpdate) {
1068 HostEvent newHostEvent = new HostEvent(hostEvent);
1069 newHostEvent.removeAttachmentPoint(switchPort);
1070 newHostEvent.freeze();
1071
1072 // TODO should this event be fired inside #addHost?
1073 if (newHostEvent.getAttachmentPoints().isEmpty()) {
1074 // No more attachment point left -> remove Host
1075 removeHost(hostEvent);
1076 } else {
1077 // Update Host
1078 addHost(newHostEvent);
1079 }
Ray Milkeyb29e6262014-04-09 16:02:14 -07001080 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001081
Ray Milkey269ffb92014-04-03 14:43:30 -07001082 //
1083 // Remove all Links connected to the Port
1084 //
1085 Set<Link> links = new HashSet<>();
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001086 links.addAll(topology.getOutgoingLinks(switchPort));
1087 links.addAll(topology.getIncomingLinks(switchPort));
Ray Milkey269ffb92014-04-03 14:43:30 -07001088 for (Link link : links) {
Ray Milkeyb29e6262014-04-09 16:02:14 -07001089 if (link == null) {
Ray Milkey269ffb92014-04-03 14:43:30 -07001090 continue;
Ray Milkeyb29e6262014-04-09 16:02:14 -07001091 }
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001092 LinkEvent linkEvent = topology.getLinkEvent(link.getLinkTuple());
1093 if (linkEvent != null) {
1094 log.debug("Removing Link {} on Port {}", link, portInTopo);
1095 removeLink(linkEvent);
1096 }
Ray Milkeyb29e6262014-04-09 16:02:14 -07001097 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001098
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001099 // Remove the Port from Topology
1100 log.debug("Removed {}", portInTopo);
1101 topology.removePort(switchPort);
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -08001102
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001103 apiRemovedPortEvents.add(portInTopo);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001104 }
1105
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001106 /**
Yuta HIGUCHI7926ba32014-07-09 11:39:32 -07001107 * Adds a link to the topology replica.
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -07001108 * <p/>
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001109 * It will remove attachment points from each hosts using the same ports.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001110 *
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -07001111 * @param linkEvent the LinkEvent with the link to add.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001112 */
Yuta HIGUCHIbc67a052014-06-30 10:37:09 -07001113 @GuardedBy("topology.writeLock")
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001114 private void addLink(LinkEvent linkEvent) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001115 PortEvent srcPort = topology.getPortEvent(linkEvent.getSrc());
1116 PortEvent dstPort = topology.getPortEvent(linkEvent.getDst());
Ray Milkey269ffb92014-04-03 14:43:30 -07001117 if ((srcPort == null) || (dstPort == null)) {
Jonathan Hartf1675202014-05-23 14:59:07 -07001118 log.debug("{} reordered because {} port is null", linkEvent,
1119 (srcPort == null) ? "src" : "dst");
1120
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -07001121 // XXX domain knowledge: port must be present before link.
Ray Milkey269ffb92014-04-03 14:43:30 -07001122 // Reordered event: delay the event in local cache
1123 ByteBuffer id = linkEvent.getIDasByteBuffer();
1124 reorderedAddedLinkEvents.put(id, linkEvent);
1125 return;
1126 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001127
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001128 // XXX domain knowledge: Sanity check: Port cannot have both Link and Host
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -07001129 // FIXME potentially local replica may not be up-to-date yet due to HZ delay.
1130 // may need to manage local truth and use them instead.
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001131 if (topology.getLinkEvent(linkEvent.getLinkTuple()) == null) {
1132 // Only check for existing Host when adding new Link.
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001133
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001134 // Remove all Hosts attached to the ports on both ends
1135
1136 Set<HostEvent> hostsToUpdate = new TreeSet<>(new Comparator<HostEvent>() {
1137 // comparison only using ID(=MAC)
1138 @Override
1139 public int compare(HostEvent o1, HostEvent o2) {
1140 return Long.compare(o1.getMac().toLong(), o2.getMac().toLong());
1141 }
1142 });
1143
1144 List<SwitchPort> portsToCheck = Arrays.asList(
1145 srcPort.getSwitchPort(),
1146 dstPort.getSwitchPort());
1147
1148 // Enumerate Host which needs to be updated by this Link add event
1149 for (SwitchPort port : portsToCheck) {
1150 for (Host host : topology.getHosts(port)) {
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -07001151 log.error("Host {} on Port {} should have been removed prior to adding Link {}",
1152 host, port, linkEvent);
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001153
1154 HostEvent hostEvent = topology.getHostEvent(host.getMacAddress());
1155 hostsToUpdate.add(hostEvent);
Ray Milkey269ffb92014-04-03 14:43:30 -07001156 }
1157 }
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001158 // remove attachment point from them.
1159 for (HostEvent hostEvent : hostsToUpdate) {
1160 // remove port from attachment point and update
1161 HostEvent newHostEvent = new HostEvent(hostEvent);
1162 newHostEvent.removeAttachmentPoint(srcPort.getSwitchPort());
1163 newHostEvent.removeAttachmentPoint(dstPort.getSwitchPort());
1164 newHostEvent.freeze();
1165
1166 // TODO should this event be fired inside #addHost?
1167 if (newHostEvent.getAttachmentPoints().isEmpty()) {
1168 // No more attachment point left -> remove Host
1169 removeHost(hostEvent);
1170 } else {
1171 // Update Host
1172 addHost(newHostEvent);
1173 }
Ray Milkeyb29e6262014-04-09 16:02:14 -07001174 }
Ray Milkey269ffb92014-04-03 14:43:30 -07001175 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -08001176
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001177 if (log.isDebugEnabled()) {
1178 LinkEvent link = topology.getLinkEvent(linkEvent.getLinkTuple());
1179 if (link != null) {
1180 log.debug("Update {}", linkEvent);
1181 } else {
1182 log.debug("Added {}", linkEvent);
1183 }
1184 }
1185 topology.putLink(linkEvent.freeze());
Ray Milkey269ffb92014-04-03 14:43:30 -07001186 apiAddedLinkEvents.add(linkEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001187 }
1188
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001189 /**
Yuta HIGUCHI7926ba32014-07-09 11:39:32 -07001190 * Removes a link from the topology replica.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001191 *
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -07001192 * @param linkEvent the LinkEvent with the link to remove.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001193 */
Yuta HIGUCHIbc67a052014-06-30 10:37:09 -07001194 @GuardedBy("topology.writeLock")
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001195 private void removeLink(LinkEvent linkEvent) {
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -07001196 Port srcPort = topology.getPort(linkEvent.getSrc().getDpid(),
Yuta HIGUCHIb1e2ab72014-06-30 11:01:31 -07001197 linkEvent.getSrc().getPortNumber());
Ray Milkey269ffb92014-04-03 14:43:30 -07001198 if (srcPort == null) {
1199 log.warn("Src Port for Link {} already removed, ignoring",
1200 linkEvent);
1201 return;
1202 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001203
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -07001204 Port dstPort = topology.getPort(linkEvent.getDst().getDpid(),
Yuta HIGUCHIb1e2ab72014-06-30 11:01:31 -07001205 linkEvent.getDst().getPortNumber());
Ray Milkey269ffb92014-04-03 14:43:30 -07001206 if (dstPort == null) {
1207 log.warn("Dst Port for Link {} already removed, ignoring",
1208 linkEvent);
1209 return;
1210 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001211
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001212 LinkEvent linkInTopo = topology.getLinkEvent(linkEvent.getLinkTuple(),
1213 linkEvent.getType());
1214 if (linkInTopo == null) {
1215 log.warn("Link {} already removed, ignoring", linkEvent);
1216 return;
Ray Milkey269ffb92014-04-03 14:43:30 -07001217 }
Jonathan Hart25bd53e2014-04-30 23:44:09 -07001218
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001219 if (log.isDebugEnabled()) {
1220 // only do sanity check on debug level
1221
1222 Link linkIn = dstPort.getIncomingLink(linkEvent.getType());
1223 if (linkIn == null) {
1224 log.warn("Link {} already removed on destination Port", linkEvent);
1225 }
1226 Link linkOut = srcPort.getOutgoingLink(linkEvent.getType());
1227 if (linkOut == null) {
1228 log.warn("Link {} already removed on src Port", linkEvent);
1229 }
Jonathan Hart25bd53e2014-04-30 23:44:09 -07001230 }
Pavlin Radoslavov74986ce2014-02-20 13:17:20 -08001231
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001232 log.debug("Removed {}", linkInTopo);
1233 topology.removeLink(linkEvent.getLinkTuple(), linkEvent.getType());
1234 apiRemovedLinkEvents.add(linkInTopo);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001235 }
1236
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001237 /**
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -07001238 * Adds a host to the topology replica.
Ray Milkey269ffb92014-04-03 14:43:30 -07001239 * <p/>
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -07001240 * TODO: Host-related work is incomplete.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001241 * TODO: Eventually, we might need to consider reordering
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001242 * or {@link #addLink(LinkEvent)} and {@link #addHost(HostEvent)} events on the same port.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001243 *
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -07001244 * @param hostEvent the HostEvent with the host to add.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001245 */
Yuta HIGUCHIbc67a052014-06-30 10:37:09 -07001246 @GuardedBy("topology.writeLock")
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -07001247 private void addHost(HostEvent hostEvent) {
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001248
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001249 // TODO Decide how to handle update scenario.
1250 // If the new HostEvent has less attachment point compared to
1251 // existing HostEvent, what should the event be?
1252 // - AddHostEvent with some attachment point removed? (current behavior)
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001253
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001254 // create unfrozen copy
1255 // for removing attachment points which already has a link
1256 HostEvent modifiedHostEvent = new HostEvent(hostEvent);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001257
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001258 // Verify each attachment point
Ray Milkey269ffb92014-04-03 14:43:30 -07001259 boolean attachmentFound = false;
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -07001260 for (SwitchPort swp : hostEvent.getAttachmentPoints()) {
1261 // XXX domain knowledge: Port must exist before Host
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -07001262 // but this knowledge cannot be pushed down to driver.
1263
Ray Milkey269ffb92014-04-03 14:43:30 -07001264 // Attached Ports must exist
Yuta HIGUCHIb1e2ab72014-06-30 11:01:31 -07001265 Port port = topology.getPort(swp.getDpid(), swp.getPortNumber());
Ray Milkey269ffb92014-04-03 14:43:30 -07001266 if (port == null) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001267 log.debug("{} reordered because port {} was not there", hostEvent, swp);
Ray Milkey269ffb92014-04-03 14:43:30 -07001268 // Reordered event: delay the event in local cache
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -07001269 ByteBuffer id = hostEvent.getIDasByteBuffer();
1270 reorderedAddedHostEvents.put(id, hostEvent);
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001271 return; // should not continue if re-applying later
Ray Milkey269ffb92014-04-03 14:43:30 -07001272 }
1273 // Attached Ports must not have Link
1274 if (port.getOutgoingLink() != null ||
1275 port.getIncomingLink() != null) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001276 log.warn("Link (Out:{},In:{}) exist on the attachment point. "
1277 + "Ignoring this attachmentpoint ({}) from {}.",
1278 port.getOutgoingLink(), port.getIncomingLink(),
1279 swp, modifiedHostEvent);
1280 // FIXME Should either reject, reorder this HostEvent,
1281 // or remove attachment point from given HostEvent
1282 // Removing attachment point from given HostEvent for now.
1283 modifiedHostEvent.removeAttachmentPoint(swp);
Ray Milkey269ffb92014-04-03 14:43:30 -07001284 continue;
1285 }
1286
Ray Milkey269ffb92014-04-03 14:43:30 -07001287 attachmentFound = true;
1288 }
1289
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -07001290 // Update the host in the topology
Ray Milkey269ffb92014-04-03 14:43:30 -07001291 if (attachmentFound) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001292 if (modifiedHostEvent.getAttachmentPoints().isEmpty()) {
1293 log.warn("No valid attachment point left. Ignoring."
1294 + "original: {}, modified: {}", hostEvent, modifiedHostEvent);
1295 // TODO Should we call #removeHost to trigger remove event?
1296 // only if this call is update.
1297 return;
1298 }
1299
1300 if (log.isDebugEnabled()) {
1301 HostEvent host = topology.getHostEvent(hostEvent.getMac());
1302 if (host != null) {
1303 log.debug("Update {}", modifiedHostEvent);
1304 } else {
1305 log.debug("Added {}", modifiedHostEvent);
1306 }
1307 }
1308 topology.putHost(modifiedHostEvent.freeze());
1309 apiAddedHostEvents.add(modifiedHostEvent);
Ray Milkey269ffb92014-04-03 14:43:30 -07001310 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001311 }
1312
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001313 /**
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -07001314 * Removes a host from the topology replica.
Ray Milkey269ffb92014-04-03 14:43:30 -07001315 * <p/>
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -07001316 * TODO: Host-related work is incomplete.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001317 *
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -07001318 * @param hostEvent the Host Event with the host to remove.
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001319 */
Yuta HIGUCHIbc67a052014-06-30 10:37:09 -07001320 @GuardedBy("topology.writeLock")
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -07001321 private void removeHost(HostEvent hostEvent) {
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001322
1323 final MACAddress mac = hostEvent.getMac();
1324 HostEvent hostInTopo = topology.getHostEvent(mac);
1325 if (hostInTopo == null) {
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -07001326 log.warn("Host {} already removed, ignoring", hostEvent);
Ray Milkey269ffb92014-04-03 14:43:30 -07001327 return;
1328 }
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001329
Yuta HIGUCHI8b389a72014-07-18 13:50:00 -07001330 log.debug("Removed {}", hostInTopo);
1331 topology.removeHost(mac);
1332 apiRemovedHostEvents.add(hostInTopo);
Pavlin Radoslavov3c9cc552014-02-20 09:58:38 -08001333 }
Jonathan Hart22eb9882014-02-11 15:52:59 -08001334
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001335 /**
Pavlin Radoslavov695f8952014-07-23 16:57:01 -07001336 * Processes added Switch Mastership event.
1337 *
1338 * @param mastershipEvent the MastershipEvent to process.
1339 */
1340 @GuardedBy("topology.writeLock")
1341 private void processAddedMastershipEvent(MastershipEvent mastershipEvent) {
1342 log.debug("Processing added Mastership event {}",
1343 mastershipEvent);
1344 // TODO: Not implemented/used yet.
1345 }
1346
1347 /**
1348 * Processes removed Switch Mastership event.
1349 *
1350 * @param mastershipEvent the MastershipEvent to process.
1351 */
1352 @GuardedBy("topology.writeLock")
1353 private void processRemovedMastershipEvent(MastershipEvent mastershipEvent) {
1354 log.debug("Processing removed Mastership event {}",
1355 mastershipEvent);
1356 // TODO: Not implemented/used yet.
1357 }
1358
1359 /**
Pavlin Radoslavov734ff5a2014-02-26 10:20:43 -08001360 * Read the whole topology from the database.
1361 *
1362 * @return a collection of EventEntry-encapsulated Topology Events for
1363 * the whole topology.
1364 */
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001365 private Collection<EventEntry<TopologyEvent>> readWholeTopologyFromDB() {
Ray Milkey269ffb92014-04-03 14:43:30 -07001366 Collection<EventEntry<TopologyEvent>> collection =
1367 new LinkedList<EventEntry<TopologyEvent>>();
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001368
Ray Milkey269ffb92014-04-03 14:43:30 -07001369 // XXX May need to clear whole topology first, depending on
1370 // how we initially subscribe to replication events
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001371
Ray Milkey269ffb92014-04-03 14:43:30 -07001372 // Add all active switches
1373 for (KVSwitch sw : KVSwitch.getAllSwitches()) {
1374 if (sw.getStatus() != KVSwitch.STATUS.ACTIVE) {
1375 continue;
1376 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001377
Pavlin Radoslavova5637c02014-07-30 15:55:11 -07001378 //
1379 // TODO: Using the local ONOS Instance ID below is incorrect.
1380 // Currently, this code is not used, and it might go away in the
1381 // future.
1382 //
Yuta HIGUCHIe2a4e172014-07-03 10:50:39 -07001383 SwitchEvent switchEvent = new SwitchEvent(new Dpid(sw.getDpid()));
Pavlin Radoslavova5637c02014-07-30 15:55:11 -07001384 TopologyEvent topologyEvent =
1385 new TopologyEvent(switchEvent,
1386 registryService.getOnosInstanceId());
Ray Milkey269ffb92014-04-03 14:43:30 -07001387 EventEntry<TopologyEvent> eventEntry =
1388 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
1389 topologyEvent);
1390 collection.add(eventEntry);
1391 }
Yuta HIGUCHIa536e762014-02-17 21:47:28 -08001392
Ray Milkey269ffb92014-04-03 14:43:30 -07001393 // Add all active ports
1394 for (KVPort p : KVPort.getAllPorts()) {
1395 if (p.getStatus() != KVPort.STATUS.ACTIVE) {
1396 continue;
1397 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001398
Pavlin Radoslavova5637c02014-07-30 15:55:11 -07001399 //
1400 // TODO: Using the local ONOS Instance ID below is incorrect.
1401 // Currently, this code is not used, and it might go away in the
1402 // future.
1403 //
1404 PortEvent portEvent =
1405 new PortEvent(new Dpid(p.getDpid()),
1406 new PortNumber(p.getNumber().shortValue()));
1407 TopologyEvent topologyEvent =
1408 new TopologyEvent(portEvent,
1409 registryService.getOnosInstanceId());
Ray Milkey269ffb92014-04-03 14:43:30 -07001410 EventEntry<TopologyEvent> eventEntry =
1411 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
1412 topologyEvent);
1413 collection.add(eventEntry);
1414 }
Yuta HIGUCHIa536e762014-02-17 21:47:28 -08001415
Pavlin Radoslavova5637c02014-07-30 15:55:11 -07001416 for (KVDevice d : KVDevice.getAllDevices()) {
1417 //
1418 // TODO: Using the local ONOS Instance ID below is incorrect.
1419 // Currently, this code is not used, and it might go away in the
1420 // future.
1421 //
1422 HostEvent devEvent = new HostEvent(MACAddress.valueOf(d.getMac()));
1423 for (byte[] portId : d.getAllPortIds()) {
1424 devEvent.addAttachmentPoint(
1425 new SwitchPort(KVPort.getDpidFromKey(portId),
1426 KVPort.getNumberFromKey(portId)));
1427 }
1428 }
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001429
Ray Milkey269ffb92014-04-03 14:43:30 -07001430 for (KVLink l : KVLink.getAllLinks()) {
Pavlin Radoslavova5637c02014-07-30 15:55:11 -07001431 //
1432 // TODO: Using the local ONOS Instance ID below is incorrect.
1433 // Currently, this code is not used, and it might go away in the
1434 // future.
1435 //
Yuta HIGUCHIe2a4e172014-07-03 10:50:39 -07001436 LinkEvent linkEvent = new LinkEvent(
Pavlin Radoslavova5637c02014-07-30 15:55:11 -07001437 new SwitchPort(l.getSrc().dpid, l.getSrc().number),
1438 new SwitchPort(l.getDst().dpid, l.getDst().number));
1439 TopologyEvent topologyEvent =
1440 new TopologyEvent(linkEvent,
1441 registryService.getOnosInstanceId());
Ray Milkey269ffb92014-04-03 14:43:30 -07001442 EventEntry<TopologyEvent> eventEntry =
1443 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
1444 topologyEvent);
1445 collection.add(eventEntry);
1446 }
Pavlin Radoslavov018d5332014-02-19 23:08:35 -08001447
Ray Milkey269ffb92014-04-03 14:43:30 -07001448 return collection;
Pavlin Radoslavovc1cfde52014-02-19 11:35:29 -08001449 }
Jonathan Hart062a2e82014-02-03 09:41:57 -08001450}