blob: 3b6a5e9856756b866754d10f812a58f8ae5c90c6 [file] [log] [blame]
Jonathan Hart472062d2014-04-03 10:56:48 -07001package net.onrc.onos.core.topology;
Jonathan Hart4b5bbb52014-02-06 10:09:31 -08002
3import java.util.ArrayList;
4import java.util.Collection;
Jonathan Hart369875b2014-02-13 10:00:31 -08005import java.util.List;
Jonathan Hart4b5bbb52014-02-06 10:09:31 -08006import java.util.Map;
Jonathan Hart369875b2014-02-13 10:00:31 -08007import java.util.concurrent.TimeUnit;
Jonathan Hart4b5bbb52014-02-06 10:09:31 -08008
9import net.floodlightcontroller.core.IFloodlightProviderService;
Pavlin Radoslavov695f8952014-07-23 16:57:01 -070010import net.floodlightcontroller.core.IFloodlightProviderService.Role;
Jonathan Hart4b5bbb52014-02-06 10:09:31 -080011import net.floodlightcontroller.core.IOFSwitch;
12import net.floodlightcontroller.core.module.FloodlightModuleContext;
13import net.floodlightcontroller.core.module.FloodlightModuleException;
14import net.floodlightcontroller.core.module.IFloodlightModule;
15import net.floodlightcontroller.core.module.IFloodlightService;
Jonathan Hart369875b2014-02-13 10:00:31 -080016import net.floodlightcontroller.core.util.SingletonTask;
17import net.floodlightcontroller.threadpool.IThreadPoolService;
Pavlin Radoslavov695f8952014-07-23 16:57:01 -070018import net.onrc.onos.api.registry.ILocalSwitchMastershipListener;
Jonathan Hart03102132014-07-01 23:22:04 -070019import net.onrc.onos.core.hostmanager.Host;
20import net.onrc.onos.core.hostmanager.IHostListener;
21import net.onrc.onos.core.hostmanager.IHostService;
Jonathan Hart23701d12014-04-03 10:45:48 -070022import net.onrc.onos.core.linkdiscovery.ILinkDiscoveryListener;
23import net.onrc.onos.core.linkdiscovery.ILinkDiscoveryService;
Jonathan Hart284e70f2014-07-05 12:32:51 -070024import net.onrc.onos.core.linkdiscovery.Link;
Jonathan Hart51f6f5b2014-04-03 10:32:10 -070025import net.onrc.onos.core.main.IOFSwitchPortListener;
Jonathan Hartdeda0ba2014-04-03 11:14:12 -070026import net.onrc.onos.core.registry.IControllerRegistryService;
Jonathan Hartdeda0ba2014-04-03 11:14:12 -070027import net.onrc.onos.core.registry.IControllerRegistryService.ControlChangeCallback;
Jonathan Harta99ec672014-04-03 11:30:34 -070028import net.onrc.onos.core.registry.RegistryException;
Yuta HIGUCHI5bbbaca2014-06-09 16:39:08 -070029import net.onrc.onos.core.util.Dpid;
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -070030import net.onrc.onos.core.util.PortNumber;
Yuta HIGUCHI5c8cbeb2014-06-27 11:13:48 -070031import net.onrc.onos.core.util.SwitchPort;
Jonathan Hart4b5bbb52014-02-06 10:09:31 -080032
33import org.openflow.protocol.OFPhysicalPort;
Jonathan Hart369875b2014-02-13 10:00:31 -080034import org.openflow.util.HexString;
Toshio Koide2f570c12014-02-06 16:55:32 -080035import org.slf4j.Logger;
36import org.slf4j.LoggerFactory;
Jonathan Hart4b5bbb52014-02-06 10:09:31 -080037
Jonathan Hart88770672014-04-02 18:08:30 -070038/**
Jonathan Harte37e4e22014-05-13 19:12:02 -070039 * The TopologyPublisher subscribes to topology network events from the
40 * discovery modules. These events are reformatted and relayed to the in-memory
41 * topology instance.
Jonathan Hart88770672014-04-02 18:08:30 -070042 */
Jonathan Harte37e4e22014-05-13 19:12:02 -070043public class TopologyPublisher implements /*IOFSwitchListener,*/
Ray Milkey269ffb92014-04-03 14:43:30 -070044 IOFSwitchPortListener,
45 ILinkDiscoveryListener,
46 IFloodlightModule,
Pavlin Radoslavov695f8952014-07-23 16:57:01 -070047 IHostListener,
48 ILocalSwitchMastershipListener {
Jonathan Hart88770672014-04-02 18:08:30 -070049 private static final Logger log =
Jonathan Harte37e4e22014-05-13 19:12:02 -070050 LoggerFactory.getLogger(TopologyPublisher.class);
Yuta HIGUCHIcb951982014-02-11 13:31:44 -080051
Jonathan Hart88770672014-04-02 18:08:30 -070052 private IFloodlightProviderService floodlightProvider;
53 private ILinkDiscoveryService linkDiscovery;
54 private IControllerRegistryService registryService;
Jonathan Harte37e4e22014-05-13 19:12:02 -070055 private ITopologyService topologyService;
Toshio Koide2f570c12014-02-06 16:55:32 -080056
Jonathan Hart03102132014-07-01 23:22:04 -070057 private IHostService hostService;
Jonathan Hartb3e1b052014-04-02 16:01:12 -070058
Jonathan Harte37e4e22014-05-13 19:12:02 -070059 private Topology topology;
60 private TopologyDiscoveryInterface topologyDiscoveryInterface;
Jonathan Hartb3e1b052014-04-02 16:01:12 -070061
Jonathan Hart88770672014-04-02 18:08:30 -070062 private static final String ENABLE_CLEANUP_PROPERTY = "EnableCleanup";
63 private boolean cleanupEnabled = true;
64 private static final int CLEANUP_TASK_INTERVAL = 60; // in seconds
65 private SingletonTask cleanupTask;
Toshio Koide2f570c12014-02-06 16:55:32 -080066
Jonathan Hart369875b2014-02-13 10:00:31 -080067 /**
Jonathan Harte37e4e22014-05-13 19:12:02 -070068 * Cleanup old switches from the topology. Old switches are those
Jonathan Hart88770672014-04-02 18:08:30 -070069 * which have no controller in the registry.
Jonathan Hart369875b2014-02-13 10:00:31 -080070 */
71 private class SwitchCleanup implements ControlChangeCallback, Runnable {
72 @Override
73 public void run() {
74 String old = Thread.currentThread().getName();
75 Thread.currentThread().setName("SwitchCleanup@" + old);
Jonathan Hartb3e1b052014-04-02 16:01:12 -070076
Jonathan Hart369875b2014-02-13 10:00:31 -080077 try {
Jonathan Hart88770672014-04-02 18:08:30 -070078 if (log.isTraceEnabled()) {
79 log.trace("Running cleanup thread");
80 }
Jonathan Hart369875b2014-02-13 10:00:31 -080081 switchCleanup();
Jonathan Hart369875b2014-02-13 10:00:31 -080082 } finally {
83 cleanupTask.reschedule(CLEANUP_TASK_INTERVAL,
Jonathan Hart88770672014-04-02 18:08:30 -070084 TimeUnit.SECONDS);
Jonathan Hart369875b2014-02-13 10:00:31 -080085 Thread.currentThread().setName(old);
86 }
87 }
Jonathan Hartb3e1b052014-04-02 16:01:12 -070088
Jonathan Hart88770672014-04-02 18:08:30 -070089 /**
90 * First half of the switch cleanup operation. This method will attempt
91 * to get control of any switch it sees without a controller via the
92 * registry.
93 */
Jonathan Hart369875b2014-02-13 10:00:31 -080094 private void switchCleanup() {
Jonathan Harte37e4e22014-05-13 19:12:02 -070095 Iterable<Switch> switches = topology.getSwitches();
Jonathan Hart369875b2014-02-13 10:00:31 -080096
Jonathan Hart88770672014-04-02 18:08:30 -070097 if (log.isTraceEnabled()) {
98 log.trace("Checking for inactive switches");
99 }
100 // For each switch check if a controller exists in controller registry
Ray Milkey269ffb92014-04-03 14:43:30 -0700101 for (Switch sw : switches) {
Jonathan Hart88770672014-04-02 18:08:30 -0700102 try {
103 String controller =
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -0700104 registryService.getControllerForSwitch(sw.getDpid().value());
Jonathan Hart88770672014-04-02 18:08:30 -0700105 if (controller == null) {
106 log.debug("Requesting control to set switch {} INACTIVE",
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -0700107 sw.getDpid());
108 registryService.requestControl(sw.getDpid().value(), this);
Jonathan Hart88770672014-04-02 18:08:30 -0700109 }
110 } catch (RegistryException e) {
111 log.error("Caught RegistryException in cleanup thread", e);
112 }
113 }
Jonathan Hart369875b2014-02-13 10:00:31 -0800114 }
115
Jonathan Hart88770672014-04-02 18:08:30 -0700116 /**
117 * Second half of the switch cleanup operation. If the registry grants
118 * control of a switch, we can be sure no other instance is writing
Jonathan Harte37e4e22014-05-13 19:12:02 -0700119 * this switch to the topology, so we can remove it now.
Ray Milkey269ffb92014-04-03 14:43:30 -0700120 *
121 * @param dpid the dpid of the switch we requested control for
Jonathan Hart88770672014-04-02 18:08:30 -0700122 * @param hasControl whether we got control or not
123 */
124 @Override
125 public void controlChanged(long dpid, boolean hasControl) {
126 if (hasControl) {
127 log.debug("Got control to set switch {} INACTIVE",
128 HexString.toHexString(dpid));
Jonathan Harte02cf542014-04-02 16:24:44 -0700129
Yuta HIGUCHIe2a4e172014-07-03 10:50:39 -0700130 SwitchEvent switchEvent = new SwitchEvent(new Dpid(dpid));
Jonathan Harte37e4e22014-05-13 19:12:02 -0700131 topologyDiscoveryInterface.
Jonathan Hart88770672014-04-02 18:08:30 -0700132 removeSwitchDiscoveryEvent(switchEvent);
133 registryService.releaseControl(dpid);
134 }
135 }
Jonathan Hart369875b2014-02-13 10:00:31 -0800136 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800137
Jonathan Hart88770672014-04-02 18:08:30 -0700138 @Override
Jonathan Hart284e70f2014-07-05 12:32:51 -0700139 public void linkAdded(Link link) {
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700140 LinkEvent linkEvent = new LinkEvent(
Jonathan Hart284e70f2014-07-05 12:32:51 -0700141 new SwitchPort(link.getSrc(), link.getSrcPort()),
142 new SwitchPort(link.getDst(), link.getDstPort()));
143
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700144 // FIXME should be merging, with existing attrs, etc..
145 // TODO define attr name as constant somewhere.
146 // TODO populate appropriate attributes.
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -0700147 linkEvent.createStringAttribute(TopologyElement.TYPE,
Yuta HIGUCHIdbc33122014-07-10 13:32:32 -0700148 TopologyElement.TYPE_PACKET_LAYER);
Praseed Balakrishnan2aa6c0b2014-07-17 11:42:05 -0700149 linkEvent.createStringAttribute(TopologyElement.ELEMENT_CONFIG_STATE,
150 ConfigState.NOT_CONFIGURED.toString());
151 linkEvent.createStringAttribute(TopologyElement.ELEMENT_ADMIN_STATUS,
152 AdminStatus.ACTIVE.toString());
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700153 linkEvent.freeze();
Jonathan Hartb3e1b052014-04-02 16:01:12 -0700154
Jonathan Hart284e70f2014-07-05 12:32:51 -0700155 if (!registryService.hasControl(link.getDst())) {
156 // Don't process or send a link event if we're not master for the
157 // destination switch
158 log.debug("Not the master for dst switch {}. Suppressed link add event {}.",
159 link.getDst(), linkEvent);
160 return;
Jonathan Hart88770672014-04-02 18:08:30 -0700161 }
Jonathan Hart284e70f2014-07-05 12:32:51 -0700162 topologyDiscoveryInterface.putLinkDiscoveryEvent(linkEvent);
163 }
164
165 @Override
166 public void linkRemoved(Link link) {
167 LinkEvent linkEvent = new LinkEvent(
168 new SwitchPort(link.getSrc(), link.getSrcPort()),
169 new SwitchPort(link.getDst(), link.getDstPort()));
170
171 // FIXME should be merging, with existing attrs, etc..
172 // TODO define attr name as constant somewhere.
173 // TODO populate appropriate attributes.
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -0700174 linkEvent.createStringAttribute(TopologyElement.TYPE,
Yuta HIGUCHIdbc33122014-07-10 13:32:32 -0700175 TopologyElement.TYPE_PACKET_LAYER);
Jonathan Hart284e70f2014-07-05 12:32:51 -0700176 linkEvent.freeze();
177
178 if (!registryService.hasControl(link.getDst())) {
179 // Don't process or send a link event if we're not master for the
180 // destination switch
181 log.debug("Not the master for dst switch {}. Suppressed link remove event {}.",
182 link.getDst(), linkEvent);
183 return;
184 }
185 topologyDiscoveryInterface.removeLinkDiscoveryEvent(linkEvent);
Jonathan Hart88770672014-04-02 18:08:30 -0700186 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800187
Jonathan Hart88770672014-04-02 18:08:30 -0700188 @Override
189 public void switchPortAdded(Long switchId, OFPhysicalPort port) {
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700190 final Dpid dpid = new Dpid(switchId);
191 PortEvent portEvent = new PortEvent(dpid, new PortNumber(port.getPortNumber()));
192 // FIXME should be merging, with existing attrs, etc..
193 // TODO define attr name as constant somewhere.
194 // TODO populate appropriate attributes.
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -0700195 portEvent.createStringAttribute(TopologyElement.TYPE,
Yuta HIGUCHIdbc33122014-07-10 13:32:32 -0700196 TopologyElement.TYPE_PACKET_LAYER);
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700197 portEvent.createStringAttribute("name", port.getName());
Yuta HIGUCHI5bbbaca2014-06-09 16:39:08 -0700198
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700199 portEvent.freeze();
200
Jonathan Hart67b6cba2014-05-30 22:36:37 -0700201 if (registryService.hasControl(switchId)) {
Jonathan Hart67b6cba2014-05-30 22:36:37 -0700202 topologyDiscoveryInterface.putPortDiscoveryEvent(portEvent);
Jonathan Hart284e70f2014-07-05 12:32:51 -0700203 linkDiscovery.enableDiscoveryOnPort(switchId, port.getPortNumber());
Yuta HIGUCHI5bbbaca2014-06-09 16:39:08 -0700204 } else {
205 log.debug("Not the master for switch {}. Suppressed port add event {}.",
206 new Dpid(switchId), portEvent);
Jonathan Hart67b6cba2014-05-30 22:36:37 -0700207 }
Jonathan Hart88770672014-04-02 18:08:30 -0700208 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800209
Jonathan Hart88770672014-04-02 18:08:30 -0700210 @Override
211 public void switchPortRemoved(Long switchId, OFPhysicalPort port) {
Yuta HIGUCHIe2a4e172014-07-03 10:50:39 -0700212 final Dpid dpid = new Dpid(switchId);
Yuta HIGUCHI5bbbaca2014-06-09 16:39:08 -0700213
Yuta HIGUCHIe2a4e172014-07-03 10:50:39 -0700214 PortEvent portEvent = new PortEvent(dpid, new PortNumber(port.getPortNumber()));
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -0700215 // FIXME should be merging, with existing attrs, etc..
216 // TODO define attr name as constant somewhere.
217 // TODO populate appropriate attributes.
218 portEvent.createStringAttribute(TopologyElement.TYPE,
Yuta HIGUCHIdbc33122014-07-10 13:32:32 -0700219 TopologyElement.TYPE_PACKET_LAYER);
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -0700220 portEvent.createStringAttribute("name", port.getName());
221
222 portEvent.freeze();
223
Jonathan Hart67b6cba2014-05-30 22:36:37 -0700224 if (registryService.hasControl(switchId)) {
Jonathan Hart67b6cba2014-05-30 22:36:37 -0700225 topologyDiscoveryInterface.removePortDiscoveryEvent(portEvent);
Yuta HIGUCHI5bbbaca2014-06-09 16:39:08 -0700226 } else {
227 log.debug("Not the master for switch {}. Suppressed port del event {}.",
Yuta HIGUCHIe2a4e172014-07-03 10:50:39 -0700228 dpid, portEvent);
Jonathan Hart67b6cba2014-05-30 22:36:37 -0700229 }
Jonathan Hart88770672014-04-02 18:08:30 -0700230 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800231
Jonathan Hart88770672014-04-02 18:08:30 -0700232 @Override
233 public void addedSwitch(IOFSwitch sw) {
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700234 final Dpid dpid = new Dpid(sw.getId());
235 SwitchEvent switchEvent = new SwitchEvent(dpid);
236 // FIXME should be merging, with existing attrs, etc..
237 // TODO define attr name as constant somewhere.
238 // TODO populate appropriate attributes.
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -0700239 switchEvent.createStringAttribute(TopologyElement.TYPE,
Yuta HIGUCHIdbc33122014-07-10 13:32:32 -0700240 TopologyElement.TYPE_PACKET_LAYER);
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700241 switchEvent.createStringAttribute("ConnectedSince",
242 sw.getConnectedSince().toString());
Praseed Balakrishnan2aa6c0b2014-07-17 11:42:05 -0700243 switchEvent.createStringAttribute(TopologyElement.ELEMENT_CONFIG_STATE,
244 ConfigState.NOT_CONFIGURED.toString());
245 switchEvent.createStringAttribute(TopologyElement.ELEMENT_ADMIN_STATUS,
246 AdminStatus.ACTIVE.toString());
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700247 switchEvent.freeze();
Jonathan Hartb3e1b052014-04-02 16:01:12 -0700248
Yuta HIGUCHI5bbbaca2014-06-09 16:39:08 -0700249 // TODO Not very robust
250 if (!registryService.hasControl(sw.getId())) {
251 log.debug("Not the master for switch {}. Suppressed switch add event {}.",
Yuta HIGUCHIe2a4e172014-07-03 10:50:39 -0700252 dpid, switchEvent);
Yuta HIGUCHI5bbbaca2014-06-09 16:39:08 -0700253 return;
254 }
255
Jonathan Hart88770672014-04-02 18:08:30 -0700256 List<PortEvent> portEvents = new ArrayList<PortEvent>();
257 for (OFPhysicalPort port : sw.getPorts()) {
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700258 PortEvent portEvent = new PortEvent(dpid, new PortNumber(port.getPortNumber()));
259 // FIXME should be merging, with existing attrs, etc..
260 // TODO define attr name as constant somewhere.
261 // TODO populate appropriate attributes.
262 portEvent.createStringAttribute("name", port.getName());
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -0700263 portEvent.createStringAttribute(TopologyElement.TYPE,
Yuta HIGUCHIdbc33122014-07-10 13:32:32 -0700264 TopologyElement.TYPE_PACKET_LAYER);
Praseed Balakrishnan2aa6c0b2014-07-17 11:42:05 -0700265 portEvent.createStringAttribute(TopologyElement.ELEMENT_CONFIG_STATE,
266 ConfigState.NOT_CONFIGURED.toString());
267 portEvent.createStringAttribute(TopologyElement.ELEMENT_ADMIN_STATUS,
268 AdminStatus.ACTIVE.toString());
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700269
270 portEvent.freeze();
271 portEvents.add(portEvent);
Jonathan Hart88770672014-04-02 18:08:30 -0700272 }
Jonathan Harte37e4e22014-05-13 19:12:02 -0700273 topologyDiscoveryInterface
Ray Milkey269ffb92014-04-03 14:43:30 -0700274 .putSwitchDiscoveryEvent(switchEvent, portEvents);
Toshio Koide2f570c12014-02-06 16:55:32 -0800275
Jonathan Hart88770672014-04-02 18:08:30 -0700276 for (OFPhysicalPort port : sw.getPorts()) {
277 // Allow links to be discovered on this port now that it's
278 // in the database
Jonathan Hart284e70f2014-07-05 12:32:51 -0700279 linkDiscovery.enableDiscoveryOnPort(sw.getId(), port.getPortNumber());
Jonathan Hart88770672014-04-02 18:08:30 -0700280 }
281 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800282
Jonathan Hart88770672014-04-02 18:08:30 -0700283 @Override
284 public void removedSwitch(IOFSwitch sw) {
285 // We don't use this event - switch remove is done by cleanup thread
286 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800287
Jonathan Hart88770672014-04-02 18:08:30 -0700288 @Override
289 public void switchPortChanged(Long switchId) {
290 // We don't use this event
291 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800292
Jonathan Hart88770672014-04-02 18:08:30 -0700293 @Override
294 public String getName() {
295 // TODO Auto-generated method stub
296 return null;
297 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800298
Jonathan Hart88770672014-04-02 18:08:30 -0700299 /* *****************
300 * IFloodlightModule
301 * *****************/
Toshio Koide2f570c12014-02-06 16:55:32 -0800302
Jonathan Hart88770672014-04-02 18:08:30 -0700303 @Override
304 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
305 return null;
306 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800307
Jonathan Hart88770672014-04-02 18:08:30 -0700308 @Override
309 public Map<Class<? extends IFloodlightService>, IFloodlightService>
310 getServiceImpls() {
311 return null;
312 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800313
Jonathan Hart88770672014-04-02 18:08:30 -0700314 @Override
315 public Collection<Class<? extends IFloodlightService>>
Ray Milkey269ffb92014-04-03 14:43:30 -0700316 getModuleDependencies() {
Jonathan Hart88770672014-04-02 18:08:30 -0700317 Collection<Class<? extends IFloodlightService>> l =
318 new ArrayList<Class<? extends IFloodlightService>>();
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800319 l.add(IFloodlightProviderService.class);
320 l.add(ILinkDiscoveryService.class);
Jonathan Hart369875b2014-02-13 10:00:31 -0800321 l.add(IThreadPoolService.class);
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800322 l.add(IControllerRegistryService.class);
Jonathan Harte37e4e22014-05-13 19:12:02 -0700323 l.add(ITopologyService.class);
Jonathan Hart03102132014-07-01 23:22:04 -0700324 l.add(IHostService.class);
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800325 return l;
Jonathan Hart88770672014-04-02 18:08:30 -0700326 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800327
Jonathan Hart88770672014-04-02 18:08:30 -0700328 @Override
329 public void init(FloodlightModuleContext context)
330 throws FloodlightModuleException {
331 floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
332 linkDiscovery = context.getServiceImpl(ILinkDiscoveryService.class);
333 registryService = context.getServiceImpl(IControllerRegistryService.class);
Jonathan Hart03102132014-07-01 23:22:04 -0700334 hostService = context.getServiceImpl(IHostService.class);
Toshio Koide2f570c12014-02-06 16:55:32 -0800335
Jonathan Harte37e4e22014-05-13 19:12:02 -0700336 topologyService = context.getServiceImpl(ITopologyService.class);
Pavlin Radoslavov695f8952014-07-23 16:57:01 -0700337
338 floodlightProvider.addLocalSwitchMastershipListener(this);
Jonathan Hart88770672014-04-02 18:08:30 -0700339 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800340
Jonathan Hart88770672014-04-02 18:08:30 -0700341 @Override
342 public void startUp(FloodlightModuleContext context) {
343 floodlightProvider.addOFSwitchListener(this);
344 linkDiscovery.addListener(this);
Jonathan Hart03102132014-07-01 23:22:04 -0700345 hostService.addHostListener(this);
Toshio Koide2f570c12014-02-06 16:55:32 -0800346
Jonathan Harte37e4e22014-05-13 19:12:02 -0700347 topology = topologyService.getTopology();
348 topologyDiscoveryInterface =
349 topologyService.getTopologyDiscoveryInterface();
Jonathan Hartb3e1b052014-04-02 16:01:12 -0700350
Jonathan Hart88770672014-04-02 18:08:30 -0700351 // Run the cleanup thread
352 String enableCleanup =
353 context.getConfigParams(this).get(ENABLE_CLEANUP_PROPERTY);
354 if (enableCleanup != null
355 && enableCleanup.equalsIgnoreCase("false")) {
356 cleanupEnabled = false;
357 }
Jonathan Hartb3e1b052014-04-02 16:01:12 -0700358
Jonathan Hart88770672014-04-02 18:08:30 -0700359 log.debug("Cleanup thread is {}enabled", (cleanupEnabled) ? "" : "not ");
Jonathan Hartb3e1b052014-04-02 16:01:12 -0700360
Jonathan Hart88770672014-04-02 18:08:30 -0700361 if (cleanupEnabled) {
362 IThreadPoolService threadPool =
363 context.getServiceImpl(IThreadPoolService.class);
364 cleanupTask = new SingletonTask(threadPool.getScheduledExecutor(),
365 new SwitchCleanup());
366 // Run the cleanup task immediately on startup
367 cleanupTask.reschedule(0, TimeUnit.SECONDS);
368 }
369 }
Jonathan Hartb3e1b052014-04-02 16:01:12 -0700370
Jonathan Hart88770672014-04-02 18:08:30 -0700371 @Override
Jonathan Hart03102132014-07-01 23:22:04 -0700372 public void hostAdded(Host host) {
373 log.debug("Called onosDeviceAdded mac {}", host.getMacAddress());
TeruUd1c5b652014-03-24 13:58:46 -0700374
Jonathan Hart03102132014-07-01 23:22:04 -0700375 SwitchPort sp = new SwitchPort(host.getSwitchDPID(), host.getSwitchPort());
Jonathan Hart88770672014-04-02 18:08:30 -0700376 List<SwitchPort> spLists = new ArrayList<SwitchPort>();
377 spLists.add(sp);
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700378 HostEvent event = new HostEvent(host.getMacAddress());
Jonathan Hart88770672014-04-02 18:08:30 -0700379 event.setAttachmentPoints(spLists);
Jonathan Hart03102132014-07-01 23:22:04 -0700380 event.setLastSeenTime(host.getLastSeenTimestamp().getTime());
Jonathan Hart88770672014-04-02 18:08:30 -0700381 // Does not use vlan info now.
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700382 event.freeze();
Jonathan Hartb3e1b052014-04-02 16:01:12 -0700383
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700384 topologyDiscoveryInterface.putHostDiscoveryEvent(event);
Jonathan Hart88770672014-04-02 18:08:30 -0700385 }
TeruUd1c5b652014-03-24 13:58:46 -0700386
Jonathan Hart88770672014-04-02 18:08:30 -0700387 @Override
Jonathan Hart03102132014-07-01 23:22:04 -0700388 public void hostRemoved(Host host) {
Jonathan Hart88770672014-04-02 18:08:30 -0700389 log.debug("Called onosDeviceRemoved");
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700390 HostEvent event = new HostEvent(host.getMacAddress());
Jonathan Hart03102132014-07-01 23:22:04 -0700391 //XXX shouldn't we be setting attachment points?
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700392 event.freeze();
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700393 topologyDiscoveryInterface.removeHostDiscoveryEvent(event);
Jonathan Hart88770672014-04-02 18:08:30 -0700394 }
Pavlin Radoslavov695f8952014-07-23 16:57:01 -0700395
396 @Override
397 public void controllerRoleChanged(Dpid dpid, Role role) {
398 log.debug("Local switch controller mastership role changed: dpid = {} role = {}", dpid, role);
399 MastershipEvent mastershipEvent =
400 new MastershipEvent(dpid, registryService.getControllerId(), role);
401 // FIXME should be merging, with existing attrs, etc..
402 // TODO define attr name as constant somewhere.
403 // TODO populate appropriate attributes.
404 mastershipEvent.createStringAttribute(TopologyElement.TYPE,
405 TopologyElement.TYPE_ALL_LAYERS);
406 mastershipEvent.freeze();
407 topologyDiscoveryInterface.putSwitchMastershipEvent(mastershipEvent);
408 }
409
410 @Override
411 public void switchDisconnected(Dpid dpid) {
412 log.debug("Local switch disconnected: dpid = {} role = {}", dpid);
413
414 Role role = Role.SLAVE; // TODO: Should be Role.UNKNOWN
415
416 MastershipEvent mastershipEvent =
417 new MastershipEvent(dpid, registryService.getControllerId(), role);
418 // FIXME should be merging, with existing attrs, etc..
419 // TODO define attr name as constant somewhere.
420 // TODO populate appropriate attributes.
421 mastershipEvent.createStringAttribute(TopologyElement.TYPE,
422 TopologyElement.TYPE_ALL_LAYERS);
423 mastershipEvent.freeze();
424 topologyDiscoveryInterface.removeSwitchMastershipEvent(mastershipEvent);
425 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800426}