blob: ed450f2e1f9724a70d46459530a03055a4d69d5e [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) {
Praseed Balakrishnane82adc62014-08-04 10:59:24 -0700102 // FIXME How to handle case where Switch has never been
103 // registered to ZK
104 if (sw.getConfigState() == ConfigState.CONFIGURED) {
105 continue;
106 }
Jonathan Hart88770672014-04-02 18:08:30 -0700107 try {
108 String controller =
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -0700109 registryService.getControllerForSwitch(sw.getDpid().value());
Jonathan Hart88770672014-04-02 18:08:30 -0700110 if (controller == null) {
111 log.debug("Requesting control to set switch {} INACTIVE",
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -0700112 sw.getDpid());
113 registryService.requestControl(sw.getDpid().value(), this);
Jonathan Hart88770672014-04-02 18:08:30 -0700114 }
115 } catch (RegistryException e) {
116 log.error("Caught RegistryException in cleanup thread", e);
117 }
118 }
Jonathan Hart369875b2014-02-13 10:00:31 -0800119 }
120
Jonathan Hart88770672014-04-02 18:08:30 -0700121 /**
122 * Second half of the switch cleanup operation. If the registry grants
123 * control of a switch, we can be sure no other instance is writing
Jonathan Harte37e4e22014-05-13 19:12:02 -0700124 * this switch to the topology, so we can remove it now.
Ray Milkey269ffb92014-04-03 14:43:30 -0700125 *
126 * @param dpid the dpid of the switch we requested control for
Jonathan Hart88770672014-04-02 18:08:30 -0700127 * @param hasControl whether we got control or not
128 */
129 @Override
130 public void controlChanged(long dpid, boolean hasControl) {
131 if (hasControl) {
132 log.debug("Got control to set switch {} INACTIVE",
133 HexString.toHexString(dpid));
Jonathan Harte02cf542014-04-02 16:24:44 -0700134
Yuta HIGUCHIe2a4e172014-07-03 10:50:39 -0700135 SwitchEvent switchEvent = new SwitchEvent(new Dpid(dpid));
Jonathan Harte37e4e22014-05-13 19:12:02 -0700136 topologyDiscoveryInterface.
Jonathan Hart88770672014-04-02 18:08:30 -0700137 removeSwitchDiscoveryEvent(switchEvent);
138 registryService.releaseControl(dpid);
139 }
140 }
Jonathan Hart369875b2014-02-13 10:00:31 -0800141 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800142
Jonathan Hart88770672014-04-02 18:08:30 -0700143 @Override
Jonathan Hart284e70f2014-07-05 12:32:51 -0700144 public void linkAdded(Link link) {
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700145 LinkEvent linkEvent = new LinkEvent(
Jonathan Hart284e70f2014-07-05 12:32:51 -0700146 new SwitchPort(link.getSrc(), link.getSrcPort()),
147 new SwitchPort(link.getDst(), link.getDstPort()));
148
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700149 // FIXME should be merging, with existing attrs, etc..
150 // TODO define attr name as constant somewhere.
151 // TODO populate appropriate attributes.
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -0700152 linkEvent.createStringAttribute(TopologyElement.TYPE,
Yuta HIGUCHIdbc33122014-07-10 13:32:32 -0700153 TopologyElement.TYPE_PACKET_LAYER);
Praseed Balakrishnan2aa6c0b2014-07-17 11:42:05 -0700154 linkEvent.createStringAttribute(TopologyElement.ELEMENT_CONFIG_STATE,
155 ConfigState.NOT_CONFIGURED.toString());
156 linkEvent.createStringAttribute(TopologyElement.ELEMENT_ADMIN_STATUS,
157 AdminStatus.ACTIVE.toString());
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700158 linkEvent.freeze();
Jonathan Hartb3e1b052014-04-02 16:01:12 -0700159
Jonathan Hart284e70f2014-07-05 12:32:51 -0700160 if (!registryService.hasControl(link.getDst())) {
161 // Don't process or send a link event if we're not master for the
162 // destination switch
163 log.debug("Not the master for dst switch {}. Suppressed link add event {}.",
164 link.getDst(), linkEvent);
165 return;
Jonathan Hart88770672014-04-02 18:08:30 -0700166 }
Jonathan Hart284e70f2014-07-05 12:32:51 -0700167 topologyDiscoveryInterface.putLinkDiscoveryEvent(linkEvent);
168 }
169
170 @Override
171 public void linkRemoved(Link link) {
172 LinkEvent linkEvent = new LinkEvent(
173 new SwitchPort(link.getSrc(), link.getSrcPort()),
174 new SwitchPort(link.getDst(), link.getDstPort()));
175
176 // FIXME should be merging, with existing attrs, etc..
177 // TODO define attr name as constant somewhere.
178 // TODO populate appropriate attributes.
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -0700179 linkEvent.createStringAttribute(TopologyElement.TYPE,
Yuta HIGUCHIdbc33122014-07-10 13:32:32 -0700180 TopologyElement.TYPE_PACKET_LAYER);
Jonathan Hart284e70f2014-07-05 12:32:51 -0700181 linkEvent.freeze();
182
183 if (!registryService.hasControl(link.getDst())) {
184 // Don't process or send a link event if we're not master for the
185 // destination switch
186 log.debug("Not the master for dst switch {}. Suppressed link remove event {}.",
187 link.getDst(), linkEvent);
188 return;
189 }
190 topologyDiscoveryInterface.removeLinkDiscoveryEvent(linkEvent);
Jonathan Hart88770672014-04-02 18:08:30 -0700191 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800192
Jonathan Hart88770672014-04-02 18:08:30 -0700193 @Override
194 public void switchPortAdded(Long switchId, OFPhysicalPort port) {
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700195 final Dpid dpid = new Dpid(switchId);
196 PortEvent portEvent = new PortEvent(dpid, new PortNumber(port.getPortNumber()));
197 // FIXME should be merging, with existing attrs, etc..
198 // TODO define attr name as constant somewhere.
199 // TODO populate appropriate attributes.
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -0700200 portEvent.createStringAttribute(TopologyElement.TYPE,
Yuta HIGUCHIdbc33122014-07-10 13:32:32 -0700201 TopologyElement.TYPE_PACKET_LAYER);
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700202 portEvent.createStringAttribute("name", port.getName());
Yuta HIGUCHI5bbbaca2014-06-09 16:39:08 -0700203
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700204 portEvent.freeze();
205
Jonathan Hart67b6cba2014-05-30 22:36:37 -0700206 if (registryService.hasControl(switchId)) {
Jonathan Hart67b6cba2014-05-30 22:36:37 -0700207 topologyDiscoveryInterface.putPortDiscoveryEvent(portEvent);
Jonathan Hart284e70f2014-07-05 12:32:51 -0700208 linkDiscovery.enableDiscoveryOnPort(switchId, port.getPortNumber());
Yuta HIGUCHI5bbbaca2014-06-09 16:39:08 -0700209 } else {
210 log.debug("Not the master for switch {}. Suppressed port add event {}.",
211 new Dpid(switchId), portEvent);
Jonathan Hart67b6cba2014-05-30 22:36:37 -0700212 }
Jonathan Hart88770672014-04-02 18:08:30 -0700213 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800214
Jonathan Hart88770672014-04-02 18:08:30 -0700215 @Override
216 public void switchPortRemoved(Long switchId, OFPhysicalPort port) {
Yuta HIGUCHIe2a4e172014-07-03 10:50:39 -0700217 final Dpid dpid = new Dpid(switchId);
Yuta HIGUCHI5bbbaca2014-06-09 16:39:08 -0700218
Yuta HIGUCHIe2a4e172014-07-03 10:50:39 -0700219 PortEvent portEvent = new PortEvent(dpid, new PortNumber(port.getPortNumber()));
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -0700220 // FIXME should be merging, with existing attrs, etc..
221 // TODO define attr name as constant somewhere.
222 // TODO populate appropriate attributes.
223 portEvent.createStringAttribute(TopologyElement.TYPE,
Yuta HIGUCHIdbc33122014-07-10 13:32:32 -0700224 TopologyElement.TYPE_PACKET_LAYER);
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -0700225 portEvent.createStringAttribute("name", port.getName());
226
227 portEvent.freeze();
228
Jonathan Hart67b6cba2014-05-30 22:36:37 -0700229 if (registryService.hasControl(switchId)) {
Jonathan Hart67b6cba2014-05-30 22:36:37 -0700230 topologyDiscoveryInterface.removePortDiscoveryEvent(portEvent);
Yuta HIGUCHI5bbbaca2014-06-09 16:39:08 -0700231 } else {
232 log.debug("Not the master for switch {}. Suppressed port del event {}.",
Yuta HIGUCHIe2a4e172014-07-03 10:50:39 -0700233 dpid, portEvent);
Jonathan Hart67b6cba2014-05-30 22:36:37 -0700234 }
Jonathan Hart88770672014-04-02 18:08:30 -0700235 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800236
Jonathan Hart88770672014-04-02 18:08:30 -0700237 @Override
238 public void addedSwitch(IOFSwitch sw) {
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700239 final Dpid dpid = new Dpid(sw.getId());
240 SwitchEvent switchEvent = new SwitchEvent(dpid);
241 // FIXME should be merging, with existing attrs, etc..
242 // TODO define attr name as constant somewhere.
243 // TODO populate appropriate attributes.
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -0700244 switchEvent.createStringAttribute(TopologyElement.TYPE,
Yuta HIGUCHIdbc33122014-07-10 13:32:32 -0700245 TopologyElement.TYPE_PACKET_LAYER);
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700246 switchEvent.createStringAttribute("ConnectedSince",
247 sw.getConnectedSince().toString());
Praseed Balakrishnan2aa6c0b2014-07-17 11:42:05 -0700248 switchEvent.createStringAttribute(TopologyElement.ELEMENT_CONFIG_STATE,
249 ConfigState.NOT_CONFIGURED.toString());
250 switchEvent.createStringAttribute(TopologyElement.ELEMENT_ADMIN_STATUS,
251 AdminStatus.ACTIVE.toString());
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700252 switchEvent.freeze();
Jonathan Hartb3e1b052014-04-02 16:01:12 -0700253
Yuta HIGUCHI5bbbaca2014-06-09 16:39:08 -0700254 // TODO Not very robust
255 if (!registryService.hasControl(sw.getId())) {
256 log.debug("Not the master for switch {}. Suppressed switch add event {}.",
Yuta HIGUCHIe2a4e172014-07-03 10:50:39 -0700257 dpid, switchEvent);
Yuta HIGUCHI5bbbaca2014-06-09 16:39:08 -0700258 return;
259 }
260
Jonathan Hart88770672014-04-02 18:08:30 -0700261 List<PortEvent> portEvents = new ArrayList<PortEvent>();
262 for (OFPhysicalPort port : sw.getPorts()) {
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700263 PortEvent portEvent = new PortEvent(dpid, new PortNumber(port.getPortNumber()));
264 // FIXME should be merging, with existing attrs, etc..
265 // TODO define attr name as constant somewhere.
266 // TODO populate appropriate attributes.
267 portEvent.createStringAttribute("name", port.getName());
Yuta HIGUCHI1222ac52014-07-09 16:50:28 -0700268 portEvent.createStringAttribute(TopologyElement.TYPE,
Yuta HIGUCHIdbc33122014-07-10 13:32:32 -0700269 TopologyElement.TYPE_PACKET_LAYER);
Praseed Balakrishnan2aa6c0b2014-07-17 11:42:05 -0700270 portEvent.createStringAttribute(TopologyElement.ELEMENT_CONFIG_STATE,
271 ConfigState.NOT_CONFIGURED.toString());
272 portEvent.createStringAttribute(TopologyElement.ELEMENT_ADMIN_STATUS,
273 AdminStatus.ACTIVE.toString());
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700274
275 portEvent.freeze();
276 portEvents.add(portEvent);
Jonathan Hart88770672014-04-02 18:08:30 -0700277 }
Jonathan Harte37e4e22014-05-13 19:12:02 -0700278 topologyDiscoveryInterface
Ray Milkey269ffb92014-04-03 14:43:30 -0700279 .putSwitchDiscoveryEvent(switchEvent, portEvents);
Toshio Koide2f570c12014-02-06 16:55:32 -0800280
Jonathan Hart88770672014-04-02 18:08:30 -0700281 for (OFPhysicalPort port : sw.getPorts()) {
282 // Allow links to be discovered on this port now that it's
283 // in the database
Jonathan Hart284e70f2014-07-05 12:32:51 -0700284 linkDiscovery.enableDiscoveryOnPort(sw.getId(), port.getPortNumber());
Jonathan Hart88770672014-04-02 18:08:30 -0700285 }
286 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800287
Jonathan Hart88770672014-04-02 18:08:30 -0700288 @Override
289 public void removedSwitch(IOFSwitch sw) {
290 // We don't use this event - switch remove is done by cleanup thread
291 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800292
Jonathan Hart88770672014-04-02 18:08:30 -0700293 @Override
294 public void switchPortChanged(Long switchId) {
295 // We don't use this event
296 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800297
Jonathan Hart88770672014-04-02 18:08:30 -0700298 @Override
299 public String getName() {
300 // TODO Auto-generated method stub
301 return null;
302 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800303
Jonathan Hart88770672014-04-02 18:08:30 -0700304 /* *****************
305 * IFloodlightModule
306 * *****************/
Toshio Koide2f570c12014-02-06 16:55:32 -0800307
Jonathan Hart88770672014-04-02 18:08:30 -0700308 @Override
309 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
310 return null;
311 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800312
Jonathan Hart88770672014-04-02 18:08:30 -0700313 @Override
314 public Map<Class<? extends IFloodlightService>, IFloodlightService>
315 getServiceImpls() {
316 return null;
317 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800318
Jonathan Hart88770672014-04-02 18:08:30 -0700319 @Override
320 public Collection<Class<? extends IFloodlightService>>
Ray Milkey269ffb92014-04-03 14:43:30 -0700321 getModuleDependencies() {
Jonathan Hart88770672014-04-02 18:08:30 -0700322 Collection<Class<? extends IFloodlightService>> l =
323 new ArrayList<Class<? extends IFloodlightService>>();
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800324 l.add(IFloodlightProviderService.class);
325 l.add(ILinkDiscoveryService.class);
Jonathan Hart369875b2014-02-13 10:00:31 -0800326 l.add(IThreadPoolService.class);
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800327 l.add(IControllerRegistryService.class);
Jonathan Harte37e4e22014-05-13 19:12:02 -0700328 l.add(ITopologyService.class);
Jonathan Hart03102132014-07-01 23:22:04 -0700329 l.add(IHostService.class);
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800330 return l;
Jonathan Hart88770672014-04-02 18:08:30 -0700331 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800332
Jonathan Hart88770672014-04-02 18:08:30 -0700333 @Override
334 public void init(FloodlightModuleContext context)
335 throws FloodlightModuleException {
336 floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
337 linkDiscovery = context.getServiceImpl(ILinkDiscoveryService.class);
338 registryService = context.getServiceImpl(IControllerRegistryService.class);
Jonathan Hart03102132014-07-01 23:22:04 -0700339 hostService = context.getServiceImpl(IHostService.class);
Toshio Koide2f570c12014-02-06 16:55:32 -0800340
Jonathan Harte37e4e22014-05-13 19:12:02 -0700341 topologyService = context.getServiceImpl(ITopologyService.class);
Pavlin Radoslavov695f8952014-07-23 16:57:01 -0700342
343 floodlightProvider.addLocalSwitchMastershipListener(this);
Jonathan Hart88770672014-04-02 18:08:30 -0700344 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800345
Jonathan Hart88770672014-04-02 18:08:30 -0700346 @Override
347 public void startUp(FloodlightModuleContext context) {
348 floodlightProvider.addOFSwitchListener(this);
349 linkDiscovery.addListener(this);
Jonathan Hart03102132014-07-01 23:22:04 -0700350 hostService.addHostListener(this);
Toshio Koide2f570c12014-02-06 16:55:32 -0800351
Jonathan Harte37e4e22014-05-13 19:12:02 -0700352 topology = topologyService.getTopology();
353 topologyDiscoveryInterface =
354 topologyService.getTopologyDiscoveryInterface();
Jonathan Hartb3e1b052014-04-02 16:01:12 -0700355
Jonathan Hart88770672014-04-02 18:08:30 -0700356 // Run the cleanup thread
357 String enableCleanup =
358 context.getConfigParams(this).get(ENABLE_CLEANUP_PROPERTY);
359 if (enableCleanup != null
360 && enableCleanup.equalsIgnoreCase("false")) {
361 cleanupEnabled = false;
362 }
Jonathan Hartb3e1b052014-04-02 16:01:12 -0700363
Jonathan Hart88770672014-04-02 18:08:30 -0700364 log.debug("Cleanup thread is {}enabled", (cleanupEnabled) ? "" : "not ");
Jonathan Hartb3e1b052014-04-02 16:01:12 -0700365
Jonathan Hart88770672014-04-02 18:08:30 -0700366 if (cleanupEnabled) {
367 IThreadPoolService threadPool =
368 context.getServiceImpl(IThreadPoolService.class);
369 cleanupTask = new SingletonTask(threadPool.getScheduledExecutor(),
370 new SwitchCleanup());
371 // Run the cleanup task immediately on startup
372 cleanupTask.reschedule(0, TimeUnit.SECONDS);
373 }
374 }
Jonathan Hartb3e1b052014-04-02 16:01:12 -0700375
Jonathan Hart88770672014-04-02 18:08:30 -0700376 @Override
Jonathan Hart03102132014-07-01 23:22:04 -0700377 public void hostAdded(Host host) {
378 log.debug("Called onosDeviceAdded mac {}", host.getMacAddress());
TeruUd1c5b652014-03-24 13:58:46 -0700379
Jonathan Hart03102132014-07-01 23:22:04 -0700380 SwitchPort sp = new SwitchPort(host.getSwitchDPID(), host.getSwitchPort());
Jonathan Hart88770672014-04-02 18:08:30 -0700381 List<SwitchPort> spLists = new ArrayList<SwitchPort>();
382 spLists.add(sp);
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700383 HostEvent event = new HostEvent(host.getMacAddress());
Jonathan Hart88770672014-04-02 18:08:30 -0700384 event.setAttachmentPoints(spLists);
Jonathan Hart03102132014-07-01 23:22:04 -0700385 event.setLastSeenTime(host.getLastSeenTimestamp().getTime());
Jonathan Hart88770672014-04-02 18:08:30 -0700386 // Does not use vlan info now.
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700387 event.freeze();
Jonathan Hartb3e1b052014-04-02 16:01:12 -0700388
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700389 topologyDiscoveryInterface.putHostDiscoveryEvent(event);
Jonathan Hart88770672014-04-02 18:08:30 -0700390 }
TeruUd1c5b652014-03-24 13:58:46 -0700391
Jonathan Hart88770672014-04-02 18:08:30 -0700392 @Override
Jonathan Hart03102132014-07-01 23:22:04 -0700393 public void hostRemoved(Host host) {
Jonathan Hart88770672014-04-02 18:08:30 -0700394 log.debug("Called onosDeviceRemoved");
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700395 HostEvent event = new HostEvent(host.getMacAddress());
Jonathan Hart03102132014-07-01 23:22:04 -0700396 //XXX shouldn't we be setting attachment points?
Yuta HIGUCHIbf0a8712014-06-30 18:59:46 -0700397 event.freeze();
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700398 topologyDiscoveryInterface.removeHostDiscoveryEvent(event);
Jonathan Hart88770672014-04-02 18:08:30 -0700399 }
Pavlin Radoslavov695f8952014-07-23 16:57:01 -0700400
401 @Override
402 public void controllerRoleChanged(Dpid dpid, Role role) {
403 log.debug("Local switch controller mastership role changed: dpid = {} role = {}", dpid, role);
404 MastershipEvent mastershipEvent =
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -0700405 new MastershipEvent(dpid, registryService.getOnosInstanceId(),
406 role);
Pavlin Radoslavov695f8952014-07-23 16:57:01 -0700407 // FIXME should be merging, with existing attrs, etc..
408 // TODO define attr name as constant somewhere.
409 // TODO populate appropriate attributes.
410 mastershipEvent.createStringAttribute(TopologyElement.TYPE,
411 TopologyElement.TYPE_ALL_LAYERS);
412 mastershipEvent.freeze();
413 topologyDiscoveryInterface.putSwitchMastershipEvent(mastershipEvent);
414 }
415
416 @Override
417 public void switchDisconnected(Dpid dpid) {
418 log.debug("Local switch disconnected: dpid = {} role = {}", dpid);
419
420 Role role = Role.SLAVE; // TODO: Should be Role.UNKNOWN
421
422 MastershipEvent mastershipEvent =
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -0700423 new MastershipEvent(dpid, registryService.getOnosInstanceId(),
424 role);
Pavlin Radoslavov695f8952014-07-23 16:57:01 -0700425 // FIXME should be merging, with existing attrs, etc..
426 // TODO define attr name as constant somewhere.
427 // TODO populate appropriate attributes.
428 mastershipEvent.createStringAttribute(TopologyElement.TYPE,
429 TopologyElement.TYPE_ALL_LAYERS);
430 mastershipEvent.freeze();
431 topologyDiscoveryInterface.removeSwitchMastershipEvent(mastershipEvent);
432 }
Jonathan Hart4b5bbb52014-02-06 10:09:31 -0800433}