blob: feb0f57cd9912373ae157857c451e74da5dd21f1 [file] [log] [blame]
Jonathan Hart062a2e82014-02-03 09:41:57 -08001package net.onrc.onos.ofcontroller.networkgraph;
2
Yuta HIGUCHI1c700102014-02-12 16:30:52 -08003import java.net.InetAddress;
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -08004import java.util.ArrayList;
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -08005import java.util.Collection;
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -08006import java.util.HashSet;
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -08007import java.util.LinkedList;
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -08008import java.util.List;
9import java.util.Set;
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080010import java.util.concurrent.BlockingQueue;
11import java.util.concurrent.LinkedBlockingQueue;
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -080012
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080013import net.onrc.onos.datagrid.IDatagridService;
14import net.onrc.onos.datagrid.IEventChannel;
15import net.onrc.onos.datagrid.IEventChannelListener;
Yuta HIGUCHI765cd0d2014-02-06 12:46:41 -080016import net.onrc.onos.datastore.topology.RCLink;
Jonathan Hart062a2e82014-02-03 09:41:57 -080017import net.onrc.onos.datastore.topology.RCPort;
18import net.onrc.onos.datastore.topology.RCSwitch;
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -080019import net.onrc.onos.ofcontroller.networkgraph.PortEvent.SwitchPort;
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080020import net.onrc.onos.ofcontroller.util.EventEntry;
Yuta HIGUCHI765cd0d2014-02-06 12:46:41 -080021import net.onrc.onos.ofcontroller.util.Dpid;
Jonathan Hart062a2e82014-02-03 09:41:57 -080022
23import org.slf4j.Logger;
24import org.slf4j.LoggerFactory;
25
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -080026/**
27 * The "NB" read-only Network Map.
28 *
Yuta HIGUCHI4bfdd532014-02-07 13:47:36 -080029 * - Maintain Invariant/Relationships between Topology Objects.
30 *
Yuta HIGUCHI765cd0d2014-02-06 12:46:41 -080031 * TODO To be synchronized based on TopologyEvent Notification.
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -080032 *
Yuta HIGUCHIcb951982014-02-11 13:31:44 -080033 * TODO TBD: Caller is expected to maintain parent/child calling order. Parent
Yuta HIGUCHI1c700102014-02-12 16:30:52 -080034 * Object must exist before adding sub component(Add Switch -> Port).
Yuta HIGUCHIcb951982014-02-11 13:31:44 -080035 *
Yuta HIGUCHI4bfdd532014-02-07 13:47:36 -080036 * TODO TBD: This class may delay the requested change to handle event
37 * re-ordering. e.g.) Link Add came in, but Switch was not there.
Yuta HIGUCHIcb951982014-02-11 13:31:44 -080038 *
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -080039 */
Yuta HIGUCHI928fa682014-02-11 19:07:57 -080040public class NetworkGraphImpl extends AbstractNetworkGraph implements
41 NetworkGraphDiscoveryInterface, NetworkGraphReplicationInterface {
Jonathan Hart062a2e82014-02-03 09:41:57 -080042
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080043 private static final Logger log = LoggerFactory
44 .getLogger(NetworkGraphImpl.class);
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -080045
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080046 private IEventChannel<byte[], TopologyEvent> eventChannel;
47 private static final String EVENT_CHANNEL_NAME = "onos.topology";
48 private EventHandler eventHandler = new EventHandler();
49
Jonathan Hart22eb9882014-02-11 15:52:59 -080050 private final NetworkGraphDatastore datastore;
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -080051
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080052 public NetworkGraphImpl() {
53 super();
Jonathan Hart22eb9882014-02-11 15:52:59 -080054 datastore = new NetworkGraphDatastore(this);
Yuta HIGUCHI80829d12014-02-05 20:16:56 -080055 }
Yuta HIGUCHI181d34d2014-02-05 15:05:46 -080056
Yuta HIGUCHI4bfdd532014-02-07 13:47:36 -080057 /**
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -080058 * Event handler class.
59 */
60 private class EventHandler extends Thread implements
61 IEventChannelListener<byte[], TopologyEvent> {
62 private BlockingQueue<EventEntry<TopologyEvent>> topologyEvents =
63 new LinkedBlockingQueue<EventEntry<TopologyEvent>>();
64
65 /**
66 * Startup processing.
67 */
68 private void startup() {
69 //
70 // TODO: Read all state from the database
71 // For now, as a shortcut we read it from the datagrid
72 //
73 Collection<TopologyEvent> topologyEvents =
74 eventChannel.getAllEntries();
75 Collection<EventEntry<TopologyEvent>> collection =
76 new LinkedList<EventEntry<TopologyEvent>>();
77
78 for (TopologyEvent topologyEvent : topologyEvents) {
79 EventEntry<TopologyEvent> eventEntry =
80 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
81 topologyEvent);
82 collection.add(eventEntry);
83 }
84 processEvents(collection);
85 }
86
87 /**
88 * Run the thread.
89 */
90 public void run() {
91 Collection<EventEntry<TopologyEvent>> collection =
92 new LinkedList<EventEntry<TopologyEvent>>();
93
94 this.setName("NetworkGraphImpl.EventHandler " + this.getId());
95 startup();
96
97 //
98 // The main loop
99 //
100 try {
101 while (true) {
102 EventEntry<TopologyEvent> eventEntry = topologyEvents.take();
103 collection.add(eventEntry);
104 topologyEvents.drainTo(collection);
105
106 processEvents(collection);
107 collection.clear();
108 }
109 } catch (Exception exception) {
110 log.debug("Exception processing Topology Events: ", exception);
111 }
112 }
113
114 /**
115 * Process all topology events.
116 *
117 * @param events the events to process.
118 */
119 private void processEvents(Collection<EventEntry<TopologyEvent>> events) {
120 for (EventEntry<TopologyEvent> event : events) {
121 TopologyEvent topologyEvent = event.eventData();
122 switch (event.eventType()) {
123 case ENTRY_ADD:
124 log.debug("Topology event ENTRY_ADD: {}", topologyEvent);
125 if (topologyEvent.switchEvent != null)
126 putSwitchReplicationEvent(topologyEvent.switchEvent);
127 if (topologyEvent.portEvent != null)
128 putPortReplicationEvent(topologyEvent.portEvent);
129 if (topologyEvent.linkEvent != null)
130 putLinkReplicationEvent(topologyEvent.linkEvent);
131 if (topologyEvent.deviceEvent != null)
132 putDeviceReplicationEvent(topologyEvent.deviceEvent);
133 break;
134 case ENTRY_REMOVE:
135 log.debug("Topology event ENTRY_REMOVE: {}", topologyEvent);
136 if (topologyEvent.switchEvent != null)
137 removeSwitchReplicationEvent(topologyEvent.switchEvent);
138 if (topologyEvent.portEvent != null)
139 removePortReplicationEvent(topologyEvent.portEvent);
140 if (topologyEvent.linkEvent != null)
141 removeLinkReplicationEvent(topologyEvent.linkEvent);
142 if (topologyEvent.deviceEvent != null)
143 removeDeviceReplicationEvent(topologyEvent.deviceEvent);
144 break;
145 }
146 }
147 }
148
149 /**
150 * Receive a notification that an entry is added.
151 *
152 * @param value the value for the entry.
153 */
154 @Override
155 public void entryAdded(TopologyEvent value) {
156 EventEntry<TopologyEvent> eventEntry =
157 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
158 value);
159 topologyEvents.add(eventEntry);
160 }
161
162 /**
163 * Receive a notification that an entry is removed.
164 *
165 * @param value the value for the entry.
166 */
167 @Override
168 public void entryRemoved(TopologyEvent value) {
169 EventEntry<TopologyEvent> eventEntry =
170 new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_REMOVE,
171 value);
172 topologyEvents.add(eventEntry);
173 }
174
175 /**
176 * Receive a notification that an entry is updated.
177 *
178 * @param value the value for the entry.
179 */
180 @Override
181 public void entryUpdated(TopologyEvent value) {
182 // NOTE: The ADD and UPDATE events are processed in same way
183 entryAdded(value);
184 }
185 }
186
187 /**
188 * Startup processing.
189 *
190 * @param datagridService the datagrid service to use.
191 */
192 void startup(IDatagridService datagridService) {
193 eventChannel = datagridService.addListener(EVENT_CHANNEL_NAME,
194 eventHandler,
195 byte[].class,
196 TopologyEvent.class);
197 eventHandler.start();
198 }
199
200 /**
Yuta HIGUCHIcb951982014-02-11 13:31:44 -0800201 * Exception to be thrown when Modification to the Network Graph cannot be continued due to broken invariant.
202 *
203 * XXX Should this be checked exception or RuntimeException
204 */
205 public static class BrokenInvariantException extends RuntimeException {
206 private static final long serialVersionUID = 1L;
207
208 public BrokenInvariantException() {
209 super();
210 }
211
212 public BrokenInvariantException(String message) {
213 super(message);
214 }
215 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800216
217 /* ******************************
218 * NetworkGraphDiscoveryInterface methods
219 * ******************************/
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -0800220
Jonathan Hart22eb9882014-02-11 15:52:59 -0800221 @Override
222 public void putSwitchEvent(SwitchEvent switchEvent) {
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800223 if (prepareForAddSwitchEvent(switchEvent)) {
Jonathan Hart22eb9882014-02-11 15:52:59 -0800224 datastore.addSwitch(switchEvent);
225 putSwitch(switchEvent);
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800226 // Send out notification
227 TopologyEvent topologyEvent =
228 new TopologyEvent(switchEvent);
229 eventChannel.addEntry(topologyEvent.getID(),
230 topologyEvent);
Jonathan Hart22eb9882014-02-11 15:52:59 -0800231 }
232 // TODO handle invariant violation
233 }
234
235 @Override
236 public void removeSwitchEvent(SwitchEvent switchEvent) {
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800237 if (prepareForRemoveSwitchEvent(switchEvent)) {
Jonathan Hart22eb9882014-02-11 15:52:59 -0800238 datastore.deactivateSwitch(switchEvent);
239 removeSwitch(switchEvent);
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800240 // Send out notification
241 eventChannel.removeEntry(switchEvent.getID());
Jonathan Hart22eb9882014-02-11 15:52:59 -0800242 }
243 // TODO handle invariant violation
244 }
245
246 @Override
247 public void putPortEvent(PortEvent portEvent) {
Jonathan Hart4c263272014-02-13 17:41:05 -0800248 if (prepareForAddPortEvent(portEvent)) {
249 datastore.addPort(portEvent);
250 putPort(portEvent);
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800251 // Send out notification
252 TopologyEvent topologyEvent =
253 new TopologyEvent(portEvent);
254 eventChannel.addEntry(topologyEvent.getID(),
255 topologyEvent);
Jonathan Hart4c263272014-02-13 17:41:05 -0800256 }
Yuta HIGUCHI75c51ed2014-02-13 17:02:26 -0800257 // TODO handle invariant violation
Jonathan Hart22eb9882014-02-11 15:52:59 -0800258 }
259
260 @Override
261 public void removePortEvent(PortEvent portEvent) {
Jonathan Hart4c263272014-02-13 17:41:05 -0800262 if (prepareForRemovePortEvent(portEvent)) {
263 datastore.deactivatePort(portEvent);
264 removePort(portEvent);
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800265 // Send out notification
266 eventChannel.removeEntry(portEvent.getID());
Jonathan Hart4c263272014-02-13 17:41:05 -0800267 }
Yuta HIGUCHI75c51ed2014-02-13 17:02:26 -0800268 // TODO handle invariant violation
Jonathan Hart22eb9882014-02-11 15:52:59 -0800269 }
270
271 @Override
272 public void putLinkEvent(LinkEvent linkEvent) {
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800273 if (prepareForAddLinkEvent(linkEvent)) {
Jonathan Hart22eb9882014-02-11 15:52:59 -0800274 datastore.addLink(linkEvent);
275 putLink(linkEvent);
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800276 // Send out notification
277 TopologyEvent topologyEvent =
278 new TopologyEvent(linkEvent);
279 eventChannel.addEntry(topologyEvent.getID(),
280 topologyEvent);
Jonathan Hart22eb9882014-02-11 15:52:59 -0800281 }
282 // TODO handle invariant violation
283 }
284
285 @Override
286 public void removeLinkEvent(LinkEvent linkEvent) {
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800287 if (prepareForRemoveLinkEvent(linkEvent)) {
Jonathan Hart22eb9882014-02-11 15:52:59 -0800288 datastore.removeLink(linkEvent);
289 removeLink(linkEvent);
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800290 // Send out notification
291 eventChannel.removeEntry(linkEvent.getID());
Jonathan Hart22eb9882014-02-11 15:52:59 -0800292 }
293 // TODO handle invariant violation
294 }
295
296 @Override
Yuta HIGUCHI586d33e2014-02-13 17:05:08 -0800297 public void putDeviceEvent(DeviceEvent deviceEvent) {
298 if (prepareForAddDeviceEvent(deviceEvent)) {
299// datastore.addDevice(deviceEvent);
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800300 // Send out notification
301 TopologyEvent topologyEvent =
302 new TopologyEvent(deviceEvent);
303 eventChannel.addEntry(topologyEvent.getID(),
304 topologyEvent);
Yuta HIGUCHI586d33e2014-02-13 17:05:08 -0800305 }
306 // TODO handle invariant violation
307 // XXX if prepareFor~ method returned false, event should be dropped
Jonathan Hart22eb9882014-02-11 15:52:59 -0800308 }
309
310 @Override
311 public void removeDeviceEvent(DeviceEvent deviceEvent) {
Yuta HIGUCHI586d33e2014-02-13 17:05:08 -0800312 if (prepareForRemoveDeviceEvent(deviceEvent)) {
313// datastore.removeDevice(deviceEvent);
Pavlin Radoslavov721a2e02014-02-14 23:40:14 -0800314 // Send out notification
315 eventChannel.removeEntry(deviceEvent.getID());
Yuta HIGUCHI586d33e2014-02-13 17:05:08 -0800316 }
317 // TODO handle invariant violation
318 // XXX if prepareFor~ method returned false, event should be dropped
Jonathan Hart22eb9882014-02-11 15:52:59 -0800319 }
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -0800320
Jonathan Hart22eb9882014-02-11 15:52:59 -0800321 /* *****************
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800322 * Internal methods to maintain invariants of the network graph
Jonathan Hart22eb9882014-02-11 15:52:59 -0800323 * *****************/
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -0800324
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800325 /**
326 *
327 * @param swEvt
328 * @return true if ready to accept event.
329 */
330 private boolean prepareForAddSwitchEvent(SwitchEvent swEvt) {
Yuta HIGUCHI76df2472014-02-12 22:36:51 -0800331 // No show stopping precondition
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800332 // Prep: remove(deactivate) Ports on Switch, which is not on event
333 removePortsNotOnEvent(swEvt);
334 return true;
Jonathan Hart22eb9882014-02-11 15:52:59 -0800335 }
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -0800336
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800337 private boolean prepareForRemoveSwitchEvent(SwitchEvent swEvt) {
Yuta HIGUCHI76df2472014-02-12 22:36:51 -0800338 // No show stopping precondition
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800339 // Prep: remove(deactivate) Ports on Switch, which is not on event
340 // XXX may be remove switch should imply wipe all ports
341 removePortsNotOnEvent(swEvt);
342 return true;
343 }
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800344
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800345 private void removePortsNotOnEvent(SwitchEvent swEvt) {
346 Switch sw = switches.get( swEvt.getDpid() );
347 if ( sw != null ) {
348 Set<Long> port_noOnEvent = new HashSet<>();
349 for( PortEvent portEvent : swEvt.getPorts()) {
350 port_noOnEvent.add(portEvent.getNumber());
351 }
352 // Existing ports not on event should be removed.
353 // TODO Should batch eventually for performance?
Jonathan Hart480c5572014-02-14 18:28:16 -0800354 List<Port> portsToRemove = new ArrayList<Port>();
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800355 for( Port p : sw.getPorts() ) {
356 if ( !port_noOnEvent.contains(p.getNumber()) ) {
Jonathan Hart480c5572014-02-14 18:28:16 -0800357 //PortEvent rmEvent = new PortEvent(p.getSwitch().getDpid(), p.getNumber());
358 // calling Discovery removePort() API to wipe from DB, etc.
359 //removePortEvent(rmEvent);
360
361 // We can't remove ports here because this will trigger a remove
362 // from the switch's port list, which we are currently iterating
363 // over.
364 portsToRemove.add(p);
365 }
366 }
367 for (Port p : portsToRemove) {
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800368 PortEvent rmEvent = new PortEvent(p.getSwitch().getDpid(), p.getNumber());
369 // calling Discovery removePort() API to wipe from DB, etc.
370 removePortEvent(rmEvent);
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800371 }
372 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800373 }
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -0800374
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800375 private boolean prepareForAddPortEvent(PortEvent portEvt) {
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800376 // Parent Switch must exist
377 if ( getSwitch(portEvt.getDpid()) == null) {
378 return false;
379 }
380 // Prep: None
Jonathan Hart22eb9882014-02-11 15:52:59 -0800381 return true;
382 }
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -0800383
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800384 private boolean prepareForRemovePortEvent(PortEvent portEvt) {
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800385 // Parent Switch must exist
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800386 Switch sw = getSwitch(portEvt.getDpid());
387 if ( sw == null ) {
Yuta HIGUCHI88be0f22014-02-14 17:20:43 -0800388 log.debug("Switch already removed? {}", portEvt);
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800389 return false;
390 }
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800391 Port port = sw.getPort(portEvt.getNumber());
392 if ( port == null ) {
393 log.debug("Port already removed? {}", portEvt);
394 // let it pass
395 return true;
396 }
397
398 // Prep: Remove Link and Device Attachment
399 for (Device device : port.getDevices()) {
Yuta HIGUCHI88be0f22014-02-14 17:20:43 -0800400 log.debug("Removing Device {} on Port {}", device, portEvt);
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800401 DeviceEvent devEvt = new DeviceEvent(device.getMacAddress());
402 devEvt.addAttachmentPoint(new SwitchPort(port.getSwitch().getDpid(), port.getNumber()));
403 // calling Discovery API to wipe from DB, etc.
404 removeDeviceEvent(devEvt);
405 }
406 Set<Link> links = new HashSet<>();
407 links.add(port.getOutgoingLink());
408 links.add(port.getIncomingLink());
409 for ( Link link : links) {
410 if (link == null ) {
411 continue;
412 }
Yuta HIGUCHI88be0f22014-02-14 17:20:43 -0800413 log.debug("Removing Link {} on Port {}", link, portEvt);
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800414 LinkEvent linkEvent = new LinkEvent(link.getSourceSwitchDpid(), link.getSourcePortNumber(), link.getDestinationSwitchDpid(), link.getDestinationPortNumber());
415 // calling Discovery API to wipe from DB, etc.
416 removeLinkEvent(linkEvent);
417 }
Jonathan Hart22eb9882014-02-11 15:52:59 -0800418 return true;
419 }
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -0800420
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800421 private boolean prepareForAddLinkEvent(LinkEvent linkEvt) {
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800422 // Src/Dst Switch must exist
423 Switch srcSw = getSwitch(linkEvt.getSrc().dpid);
424 Switch dstSw = getSwitch(linkEvt.getDst().dpid);
425 if ( srcSw == null || dstSw == null ) {
426 return false;
427 }
428 // Src/Dst Port must exist
429 Port srcPort = srcSw.getPort(linkEvt.getSrc().number);
Jonathan Hart4c263272014-02-13 17:41:05 -0800430 Port dstPort = dstSw.getPort(linkEvt.getDst().number);
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800431 if ( srcPort == null || dstPort == null ) {
432 return false;
433 }
434
435 // Prep: remove Device attachment on both Ports
436 for (Device device : srcPort.getDevices()) {
437 DeviceEvent devEvt = new DeviceEvent(device.getMacAddress());
438 devEvt.addAttachmentPoint(new SwitchPort(srcPort.getSwitch().getDpid(), srcPort.getNumber()));
439 // calling Discovery API to wipe from DB, etc.
440 removeDeviceEvent(devEvt);
441 }
442 for (Device device : dstPort.getDevices()) {
443 DeviceEvent devEvt = new DeviceEvent(device.getMacAddress());
444 devEvt.addAttachmentPoint(new SwitchPort(dstPort.getSwitch().getDpid(), dstPort.getNumber()));
445 // calling Discovery API to wipe from DB, etc.
446 removeDeviceEvent(devEvt);
447 }
448
449 return true;
Jonathan Hart22eb9882014-02-11 15:52:59 -0800450 }
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -0800451
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800452 private boolean prepareForRemoveLinkEvent(LinkEvent linkEvt) {
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800453 // Src/Dst Switch must exist
454 Switch srcSw = getSwitch(linkEvt.getSrc().dpid);
455 Switch dstSw = getSwitch(linkEvt.getDst().dpid);
456 if ( srcSw == null || dstSw == null ) {
Yuta HIGUCHI125c7df2014-02-14 12:28:10 -0800457 log.warn("Rejecting removeLink {} because switch doesn't exist", linkEvt);
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800458 return false;
459 }
460 // Src/Dst Port must exist
461 Port srcPort = srcSw.getPort(linkEvt.getSrc().number);
Yuta HIGUCHI125c7df2014-02-14 12:28:10 -0800462 Port dstPort = dstSw.getPort(linkEvt.getDst().number);
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800463 if ( srcPort == null || dstPort == null ) {
Yuta HIGUCHI125c7df2014-02-14 12:28:10 -0800464 log.warn("Rejecting removeLink {} because port doesn't exist", linkEvt);
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800465 return false;
466 }
467
Yuta HIGUCHI125c7df2014-02-14 12:28:10 -0800468 Link link = srcPort.getOutgoingLink();
469
470 // Link is already gone, or different Link exist in memory
471 // XXX Check if we should reject or just accept these cases.
472 // it should be harmless to remove the Link on event from DB anyways
473 if (link == null ||
474 !link.getDestinationPortNumber().equals(linkEvt.getDst().number)
475 || !link.getDestinationSwitchDpid().equals(linkEvt.getDst().dpid)) {
476 log.warn("Rejecting removeLink {} because link doesn't exist", linkEvt);
477 return false;
478 }
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800479 // Prep: None
480 return true;
Jonathan Hart22eb9882014-02-11 15:52:59 -0800481 }
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -0800482
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800483 /**
484 *
485 * @param deviceEvt Event will be modified to remove inapplicable attachemntPoints/ipAddress
486 * @return false if this event should be dropped.
487 */
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800488 private boolean prepareForAddDeviceEvent(DeviceEvent deviceEvt) {
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800489 boolean preconditionBroken = false;
490 ArrayList<PortEvent.SwitchPort> failedSwitchPort = new ArrayList<>();
491 for ( PortEvent.SwitchPort swp : deviceEvt.getAttachmentPoints() ) {
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800492 // Attached Ports' Parent Switch must exist
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800493 Switch sw = getSwitch(swp.dpid);
494 if ( sw == null ) {
495 preconditionBroken = true;
496 failedSwitchPort.add(swp);
497 continue;
498 }
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800499 // Attached Ports must exist
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800500 Port port = sw.getPort(swp.number);
501 if ( port == null ) {
502 preconditionBroken = true;
503 failedSwitchPort.add(swp);
504 continue;
505 }
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800506 // Attached Ports must not have Link
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800507 if ( port.getOutgoingLink() != null || port.getIncomingLink() != null ) {
508 preconditionBroken = true;
509 failedSwitchPort.add(swp);
510 continue;
511 }
512 }
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800513
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800514 // Rewriting event to exclude failed attachmentPoint
515 // XXX Assumption behind this is that inapplicable device event should
516 // be dropped, not deferred. If we decide to defer Device event,
517 // rewriting can become a problem
518 List<SwitchPort> attachmentPoints = deviceEvt.getAttachmentPoints();
519 attachmentPoints.removeAll(failedSwitchPort);
520 deviceEvt.setAttachmentPoints(attachmentPoints);
521
522 if ( deviceEvt.getAttachmentPoints().isEmpty() && deviceEvt.getIpAddresses().isEmpty() ) {
Yuta HIGUCHI125c7df2014-02-14 12:28:10 -0800523 // return false to represent: Nothing left to do for this event. Caller should drop event
Yuta HIGUCHI8d762e92014-02-12 14:10:25 -0800524 return false;
525 }
526
527 // Should we return false to tell caller that the event was trimmed?
528 // if ( preconditionBroken ) {
529 // return false;
530 // }
531
532 return true;
Jonathan Hart22eb9882014-02-11 15:52:59 -0800533 }
Yuta HIGUCHIcd922f42014-02-11 18:59:11 -0800534
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800535 private boolean prepareForRemoveDeviceEvent(DeviceEvent deviceEvt) {
Yuta HIGUCHId02e9282014-02-12 09:24:41 -0800536 // No show stopping precondition?
537 // Prep: none
Jonathan Hart22eb9882014-02-11 15:52:59 -0800538 return true;
539 }
Yuta HIGUCHI928fa682014-02-11 19:07:57 -0800540
Yuta HIGUCHI76df2472014-02-12 22:36:51 -0800541 /* ******************************
542 * NetworkGraphReplicationInterface methods
543 * ******************************/
544
Yuta HIGUCHI928fa682014-02-11 19:07:57 -0800545 @Override
546 public void putSwitchReplicationEvent(SwitchEvent switchEvent) {
Yuta HIGUCHI9fc10ac2014-02-12 17:18:57 -0800547 if (prepareForAddSwitchEvent(switchEvent)) {
548 putSwitch(switchEvent);
549 }
550 // TODO handle invariant violation
Yuta HIGUCHI928fa682014-02-11 19:07:57 -0800551 }
552
553 @Override
554 public void removeSwitchReplicationEvent(SwitchEvent switchEvent) {
Yuta HIGUCHI9fc10ac2014-02-12 17:18:57 -0800555 if (prepareForRemoveSwitchEvent(switchEvent)) {
556 removeSwitch(switchEvent);
557 }
Yuta HIGUCHI125c7df2014-02-14 12:28:10 -0800558 // TODO handle invariant violation
Yuta HIGUCHI928fa682014-02-11 19:07:57 -0800559 }
560
561 @Override
562 public void putPortReplicationEvent(PortEvent portEvent) {
Yuta HIGUCHI9fc10ac2014-02-12 17:18:57 -0800563 if (prepareForAddPortEvent(portEvent)) {
564 putPort(portEvent);
565 }
Yuta HIGUCHI125c7df2014-02-14 12:28:10 -0800566 // TODO handle invariant violation
Yuta HIGUCHI928fa682014-02-11 19:07:57 -0800567 }
568
569 @Override
570 public void removePortReplicationEvent(PortEvent portEvent) {
Yuta HIGUCHI9fc10ac2014-02-12 17:18:57 -0800571 if (prepareForRemovePortEvent(portEvent)) {
572 removePort(portEvent);
573 }
Yuta HIGUCHI125c7df2014-02-14 12:28:10 -0800574 // TODO handle invariant violation
Yuta HIGUCHI928fa682014-02-11 19:07:57 -0800575 }
576
577 @Override
578 public void putLinkReplicationEvent(LinkEvent linkEvent) {
Yuta HIGUCHI9fc10ac2014-02-12 17:18:57 -0800579 if (prepareForAddLinkEvent(linkEvent)) {
580 putLink(linkEvent);
581 }
Yuta HIGUCHI125c7df2014-02-14 12:28:10 -0800582 // TODO handle invariant violation
Yuta HIGUCHI928fa682014-02-11 19:07:57 -0800583 }
584
585 @Override
586 public void removeLinkReplicationEvent(LinkEvent linkEvent) {
Yuta HIGUCHI9fc10ac2014-02-12 17:18:57 -0800587 if (prepareForRemoveLinkEvent(linkEvent)) {
588 removeLink(linkEvent);
589 }
Yuta HIGUCHI125c7df2014-02-14 12:28:10 -0800590 // TODO handle invariant violation
Yuta HIGUCHI928fa682014-02-11 19:07:57 -0800591 }
592
593 @Override
594 public void putDeviceReplicationEvent(DeviceEvent deviceEvent) {
Yuta HIGUCHI9fc10ac2014-02-12 17:18:57 -0800595 if (prepareForAddDeviceEvent(deviceEvent)) {
596 putDevice(deviceEvent);
597 }
Yuta HIGUCHI125c7df2014-02-14 12:28:10 -0800598 // TODO handle invariant violation
Yuta HIGUCHI928fa682014-02-11 19:07:57 -0800599 }
600
601 @Override
602 public void removeDeviceReplicationEvent(DeviceEvent deviceEvent) {
Yuta HIGUCHI9fc10ac2014-02-12 17:18:57 -0800603 if (prepareForRemoveDeviceEvent(deviceEvent)) {
604 removeDevice(deviceEvent);
605 }
Yuta HIGUCHI125c7df2014-02-14 12:28:10 -0800606 // TODO handle invariant violation
Yuta HIGUCHI928fa682014-02-11 19:07:57 -0800607 }
Yuta HIGUCHI76df2472014-02-12 22:36:51 -0800608
609 /* ************************************************
610 * Internal In-memory object mutation methods.
611 * ************************************************/
612
613 void putSwitch(SwitchEvent swEvt) {
614 if (swEvt == null) {
615 throw new IllegalArgumentException("Switch cannot be null");
616 }
617
618 Switch sw = switches.get(swEvt.getDpid());
619
620 if (sw == null) {
621 sw = new SwitchImpl(this, swEvt.getDpid());
622 Switch existing = switches.putIfAbsent(swEvt.getDpid(), sw);
623 if (existing != null) {
624 log.warn(
625 "Concurrent putSwitch not expected. Continuing updating {}",
626 existing);
627 sw = existing;
628 }
629 }
630
631 // Update when more attributes are added to Event object
632 // no attribute to update for now
633
634 // TODO handle child Port event properly for performance
635 for (PortEvent portEvt : swEvt.getPorts() ) {
636 putPort(portEvt);
637 }
638
639 }
640
641 void removeSwitch(SwitchEvent swEvt) {
642 if (swEvt == null) {
643 throw new IllegalArgumentException("Switch cannot be null");
644 }
645
646 // TODO handle child Port event properly for performance
647 for (PortEvent portEvt : swEvt.getPorts() ) {
648 removePort(portEvt);
649 }
650
651 Switch sw = switches.get(swEvt.getDpid());
652
653 if (sw == null) {
654 log.warn("Switch {} already removed, ignoring", swEvt);
655 return;
656 }
657
658 // Sanity check
659 if (!sw.getPorts().isEmpty()) {
660 log.warn(
661 "Ports on Switch {} should be removed prior to removing Switch. Removing Switch anyways",
662 swEvt);
663 // XXX Should we remove Port?
664 }
665 if (!sw.getDevices().isEmpty()) {
666 log.warn(
667 "Devices on Switch {} should be removed prior to removing Switch. Removing Switch anyways",
668 swEvt);
669 // XXX Should we remove Device to Switch relation?
670 }
671 if (!sw.getIncomingLinks().iterator().hasNext()) {
672 log.warn(
673 "IncomingLinks on Switch {} should be removed prior to removing Switch. Removing Switch anyways",
674 swEvt);
675 // XXX Should we remove Link?
676 }
677 if (!sw.getOutgoingLinks().iterator().hasNext()) {
678 log.warn(
679 "OutgoingLinks on Switch {} should be removed prior to removing Switch. Removing Switch anyways",
680 swEvt);
681 // XXX Should we remove Link?
682 }
683
684 boolean removed = switches.remove(swEvt.getDpid(), sw);
685 if (removed) {
686 log.warn(
687 "Switch instance was replaced concurrently while removing {}. Something is not right.",
688 sw);
689 }
690 }
691
692 void putPort(PortEvent portEvt) {
693 if (portEvt == null) {
694 throw new IllegalArgumentException("Port cannot be null");
695 }
696 Switch sw = switches.get(portEvt.getDpid());
697 if (sw == null) {
698 throw new BrokenInvariantException(String.format(
699 "Switch with dpid %s did not exist.",
700 new Dpid(portEvt.getDpid())));
701 }
702 Port p = sw.getPort(portEvt.getNumber());
703 PortImpl port = null;
704 if (p != null) {
705 port = getPortImpl(p);
706 }
707
708 if (port == null) {
709 port = new PortImpl(this, sw, portEvt.getNumber());
710 }
711
712 // TODO update attributes
713
714 SwitchImpl s = getSwitchImpl(sw);
715 s.addPort(port);
716 }
717
718 void removePort(PortEvent portEvt) {
719 if (portEvt == null) {
720 throw new IllegalArgumentException("Port cannot be null");
721 }
722
723 Switch sw = switches.get(portEvt.getDpid());
724 if (sw == null) {
725 log.warn("Parent Switch for Port {} already removed, ignoring", portEvt);
726 return;
727 }
728
729 Port p = sw.getPort(portEvt.getNumber());
730 if (p == null) {
731 log.warn("Port {} already removed, ignoring", portEvt);
732 return;
733 }
734
735 // check if there is something referring to this Port
736
737 if (!p.getDevices().iterator().hasNext()) {
738 log.warn(
739 "Devices on Port {} should be removed prior to removing Port. Removing Port anyways",
740 portEvt);
741 // XXX Should we remove Device to Port relation?
742 }
743 if (p.getIncomingLink() != null) {
744 log.warn(
745 "IncomingLinks on Port {} should be removed prior to removing Port. Removing Port anyways",
746 portEvt);
747 // XXX Should we remove Link?
748 }
749 if (p.getOutgoingLink() != null) {
750 log.warn(
751 "OutgoingLinks on Port {} should be removed prior to removing Port. Removing Port anyways",
752 portEvt);
753 // XXX Should we remove Link?
754 }
755
756 // remove Port from Switch
757 SwitchImpl s = getSwitchImpl(sw);
758 s.removePort(p);
759 }
760
761 void putLink(LinkEvent linkEvt) {
762 if (linkEvt == null) {
763 throw new IllegalArgumentException("Link cannot be null");
764 }
765
766 Switch srcSw = switches.get(linkEvt.getSrc().dpid);
767 if (srcSw == null) {
768 throw new BrokenInvariantException(
769 String.format(
770 "Switch with dpid %s did not exist.",
771 new Dpid(linkEvt.getSrc().dpid)));
772 }
773
774 Switch dstSw = switches.get(linkEvt.getDst().dpid);
775 if (dstSw == null) {
776 throw new BrokenInvariantException(
777 String.format(
778 "Switch with dpid %s did not exist.",
779 new Dpid(linkEvt.getDst().dpid)));
780 }
781
782 Port srcPort = srcSw.getPort(linkEvt.getSrc().number);
783 if (srcPort == null) {
784 throw new BrokenInvariantException(
785 String.format(
786 "Src Port %s of a Link did not exist.",
787 linkEvt.getSrc() ));
788 }
789
790 Port dstPort = dstSw.getPort(linkEvt.getDst().number);
791 if (dstPort == null) {
792 throw new BrokenInvariantException(
793 String.format(
794 "Dst Port %s of a Link did not exist.",
795 linkEvt.getDst() ));
796 }
797
798 // getting Link instance from destination port incoming Link
799 Link l = dstPort.getIncomingLink();
800 LinkImpl link = null;
801 assert( l == srcPort.getOutgoingLink() );
802 if (l != null) {
803 link = getLinkImpl(l);
804 }
805
806 if (link == null) {
807 link = new LinkImpl(this, srcPort, dstPort);
808 }
809
810
811 PortImpl dstPortMem = getPortImpl(dstPort);
812 PortImpl srcPortMem = getPortImpl(srcPort);
813
814 // Add Link first to avoid further Device addition
815
816 // add Link to Port
817 dstPortMem.setIncomingLink(link);
818 srcPortMem.setOutgoingLink(link);
819
820 // remove Device Pointing to Port if any
821 for(Device d : dstPortMem.getDevices() ) {
822 log.error("Device {} on Port {} should have been removed prior to adding Link {}", d, dstPort, linkEvt);
823 DeviceImpl dev = getDeviceImpl(d);
824 dev.removeAttachmentPoint(dstPort);
Yuta HIGUCHI407261a2014-02-13 16:34:06 -0800825 // This implies that change is made to Device Object.
826 // sending Device attachment point removed event
827 DeviceEvent rmEvent = new DeviceEvent(d.getMacAddress());
828 rmEvent.addAttachmentPoint(new SwitchPort(dstPort.getDpid(), dstPort.getNumber()));
829 removeDeviceEvent(rmEvent);
Yuta HIGUCHI76df2472014-02-12 22:36:51 -0800830 }
831 dstPortMem.removeAllDevice();
832 for(Device d : srcPortMem.getDevices() ) {
833 log.error("Device {} on Port {} should have been removed prior to adding Link {}", d, srcPort, linkEvt);
834 DeviceImpl dev = getDeviceImpl(d);
835 dev.removeAttachmentPoint(srcPort);
Yuta HIGUCHI407261a2014-02-13 16:34:06 -0800836 // This implies that change is made to Device Object.
837 // sending Device attachment point removed event
838 DeviceEvent rmEvent = new DeviceEvent(d.getMacAddress());
839 rmEvent.addAttachmentPoint(new SwitchPort(dstPort.getDpid(), dstPort.getNumber()));
840 removeDeviceEvent(rmEvent);
Yuta HIGUCHI76df2472014-02-12 22:36:51 -0800841 }
842 srcPortMem.removeAllDevice();
843
844 }
845
846 void removeLink(LinkEvent linkEvt) {
847 if (linkEvt == null) {
848 throw new IllegalArgumentException("Link cannot be null");
849 }
850
851 Switch srcSw = switches.get(linkEvt.getSrc().dpid);
852 if (srcSw == null) {
853 log.warn("Src Switch for Link {} already removed, ignoring", linkEvt);
854 return;
855 }
856
857 Switch dstSw = switches.get(linkEvt.getDst().dpid);
858 if (dstSw == null) {
859 log.warn("Dst Switch for Link {} already removed, ignoring", linkEvt);
860 return;
861 }
862
863 Port srcPort = srcSw.getPort(linkEvt.getSrc().number);
864 if (srcPort == null) {
865 log.warn("Src Port for Link {} already removed, ignoring", linkEvt);
866 return;
867 }
868
869 Port dstPort = dstSw.getPort(linkEvt.getDst().number);
870 if (dstPort == null) {
871 log.warn("Dst Port for Link {} already removed, ignoring", linkEvt);
872 return;
873 }
874
875 Link l = dstPort.getIncomingLink();
876 if ( l == null ) {
877 log.warn("Link {} already removed on destination Port", linkEvt);
878 }
879 l = srcPort.getOutgoingLink();
880 if ( l == null ) {
881 log.warn("Link {} already removed on src Port", linkEvt);
882 }
883
884 getPortImpl(dstPort).setIncomingLink(null);
885 getPortImpl(srcPort).setOutgoingLink(null);
886 }
887
888 // XXX Need to rework Device related
889 void putDevice(DeviceEvent deviceEvt) {
890 if (deviceEvt == null) {
891 throw new IllegalArgumentException("Device cannot be null");
892 }
893
894 Device device = getDeviceByMac(deviceEvt.getMac());
895 if ( device == null ) {
896 device = new DeviceImpl(this, deviceEvt.getMac());
897 Device existing = mac2Device.putIfAbsent(deviceEvt.getMac(), device);
898 if (existing != null) {
899 log.warn(
900 "Concurrent putDevice seems to be in action. Continuing updating {}",
901 existing);
902 device = existing;
903 }
904 }
905 DeviceImpl memDevice = getDeviceImpl(device);
906
907 // for each attachment point
908 for (SwitchPort swp : deviceEvt.getAttachmentPoints() ) {
909 // Attached Ports' Parent Switch must exist
910 Switch sw = getSwitch(swp.dpid);
911 if ( sw == null ) {
Yuta HIGUCHI25719052014-02-13 14:42:06 -0800912 log.warn("Switch for the attachment point {} did not exist. skipping mutation", swp);
Yuta HIGUCHI76df2472014-02-12 22:36:51 -0800913 continue;
914 }
915 // Attached Ports must exist
916 Port port = sw.getPort(swp.number);
917 if ( port == null ) {
Yuta HIGUCHI25719052014-02-13 14:42:06 -0800918 log.warn("Port for the attachment point {} did not exist. skipping mutation", swp);
Yuta HIGUCHI76df2472014-02-12 22:36:51 -0800919 continue;
920 }
921 // Attached Ports must not have Link
922 if ( port.getOutgoingLink() != null || port.getIncomingLink() != null ) {
923 log.warn("Link (Out:{},In:{}) exist on the attachment point, skipping mutation.", port.getOutgoingLink(), port.getIncomingLink());
924 continue;
925 }
926
927 // finally add Device <-> Port on In-memory structure
928 PortImpl memPort = getPortImpl(port);
929 memPort.addDevice(device);
930 memDevice.addAttachmentPoint(port);
931 }
932
933 // for each IP address
934 for( InetAddress ipAddr : deviceEvt.getIpAddresses() ) {
935 // Add Device -> IP
936 memDevice.addIpAddress(ipAddr);
937
938 // Add IP -> Set<Device>
939 boolean updated = false;
940 do {
941 Set<Device> devices = this.addr2Device.get(ipAddr);
942 if ( devices == null ) {
943 devices = new HashSet<>();
944 Set<Device> existing = this.addr2Device.putIfAbsent(ipAddr, devices);
945 if ( existing == null ) {
946 // success
947 updated = true;
948 }
949 } else {
950 Set<Device> updateDevices = new HashSet<>(devices);
951 updateDevices.add(device);
952 updated = this.addr2Device.replace(ipAddr, devices, updateDevices);
953 }
954 if (!updated) {
955 log.debug("Collision detected, updating IP to Device mapping retrying.");
956 }
957 } while( !updated );
958 }
959 }
960
961 void removeDevice(DeviceEvent deviceEvt) {
962 if (deviceEvt == null) {
963 throw new IllegalArgumentException("Device cannot be null");
964 }
965
966 Device device = getDeviceByMac(deviceEvt.getMac());
967 if ( device == null ) {
968 log.warn("Device {} already removed, ignoring", deviceEvt);
969 return;
970 }
971 DeviceImpl memDevice = getDeviceImpl(device);
972
973 // for each attachment point
974 for (SwitchPort swp : deviceEvt.getAttachmentPoints() ) {
975 // Attached Ports' Parent Switch must exist
976 Switch sw = getSwitch(swp.dpid);
977 if ( sw == null ) {
Yuta HIGUCHI25719052014-02-13 14:42:06 -0800978 log.warn("Switch for the attachment point {} did not exist. skipping attachment point mutation", swp);
Yuta HIGUCHI76df2472014-02-12 22:36:51 -0800979 continue;
980 }
981 // Attached Ports must exist
982 Port port = sw.getPort(swp.number);
983 if ( port == null ) {
Yuta HIGUCHI25719052014-02-13 14:42:06 -0800984 log.warn("Port for the attachment point {} did not exist. skipping attachment point mutation", swp);
Yuta HIGUCHI76df2472014-02-12 22:36:51 -0800985 continue;
986 }
987
988 // finally remove Device <-> Port on In-memory structure
989 PortImpl memPort = getPortImpl(port);
990 memPort.removeDevice(device);
991 memDevice.removeAttachmentPoint(port);
992 }
993
994 // for each IP address
995 for( InetAddress ipAddr : deviceEvt.getIpAddresses() ) {
996 // Remove Device -> IP
997 memDevice.removeIpAddress(ipAddr);
998
999 // Remove IP -> Set<Device>
1000 boolean updated = false;
1001 do {
1002 Set<Device> devices = this.addr2Device.get(ipAddr);
1003 if ( devices == null ) {
1004 // already empty set, nothing to do
1005 updated = true;
1006 } else {
1007 Set<Device> updateDevices = new HashSet<>(devices);
1008 updateDevices.remove(device);
1009 updated = this.addr2Device.replace(ipAddr, devices, updateDevices);
1010 }
1011 if (!updated) {
1012 log.debug("Collision detected, updating IP to Device mapping retrying.");
1013 }
1014 } while( !updated );
1015 }
1016 }
1017
1018 private SwitchImpl getSwitchImpl(Switch sw) {
1019 if (sw instanceof SwitchImpl) {
1020 return (SwitchImpl) sw;
1021 }
1022 throw new ClassCastException("SwitchImpl expected, but found: " + sw);
1023 }
1024
1025 private PortImpl getPortImpl(Port p) {
1026 if (p instanceof PortImpl) {
1027 return (PortImpl) p;
1028 }
1029 throw new ClassCastException("PortImpl expected, but found: " + p);
1030 }
1031
1032 private LinkImpl getLinkImpl(Link l) {
1033 if (l instanceof LinkImpl) {
1034 return (LinkImpl) l;
1035 }
1036 throw new ClassCastException("LinkImpl expected, but found: " + l);
1037 }
1038
1039 private DeviceImpl getDeviceImpl(Device d) {
1040 if (d instanceof DeviceImpl) {
1041 return (DeviceImpl) d;
1042 }
1043 throw new ClassCastException("DeviceImpl expected, but found: " + d);
1044 }
1045
1046 @Deprecated
1047 public void loadWholeTopologyFromDB() {
1048 // XXX clear everything first?
1049
1050 for (RCSwitch sw : RCSwitch.getAllSwitches()) {
1051 if ( sw.getStatus() != RCSwitch.STATUS.ACTIVE ) {
1052 continue;
1053 }
1054 putSwitchReplicationEvent(new SwitchEvent(sw.getDpid()));
1055 }
1056
1057 for (RCPort p : RCPort.getAllPorts()) {
1058 if (p.getStatus() != RCPort.STATUS.ACTIVE) {
1059 continue;
1060 }
1061 putPortReplicationEvent(new PortEvent(p.getDpid(), p.getNumber() ));
1062 }
1063
1064 // TODO Is Device going to be in DB? If so, read from DB.
1065 // for (RCDevice d : RCDevice.getAllDevices()) {
1066 // DeviceEvent devEvent = new DeviceEvent( MACAddress.valueOf(d.getMac()) );
1067 // for (byte[] portId : d.getAllPortIds() ) {
1068 // devEvent.addAttachmentPoint( new SwitchPort( RCPort.getDpidFromKey(portId), RCPort.getNumberFromKey(portId) ));
1069 // }
1070 // }
1071
1072 for (RCLink l : RCLink.getAllLinks()) {
1073 putLinkReplicationEvent( new LinkEvent(l.getSrc().dpid, l.getSrc().number, l.getDst().dpid, l.getDst().number));
1074 }
1075 }
Jonathan Hart062a2e82014-02-03 09:41:57 -08001076}