blob: 9eefba35a6959c372cbb0c58478b41ac7f2f3af3 [file] [log] [blame]
HIGUCHI Yuta155cfc52013-06-14 15:54:16 -07001package net.onrc.onos.ofcontroller.floodlightlistener;
Pankaj Berdeda809572013-02-22 15:31:20 -08002
3import java.util.ArrayList;
4import java.util.Collection;
Pavlin Radoslavov28069402013-10-18 18:43:11 -07005import java.util.HashMap;
Pankaj Berdeda809572013-02-22 15:31:20 -08006import java.util.Map;
Pankaj Berdef08d5ff2013-03-14 17:03:07 -07007import java.util.concurrent.ScheduledExecutorService;
8import java.util.concurrent.TimeUnit;
Pankaj Berdeda809572013-02-22 15:31:20 -08009
Pankaj Berde465ac7c2013-05-23 13:47:49 -070010import org.openflow.protocol.OFPhysicalPort;
Pankaj Berdef08d5ff2013-03-14 17:03:07 -070011import org.openflow.util.HexString;
Pankaj Berdeda809572013-02-22 15:31:20 -080012import org.slf4j.Logger;
13import org.slf4j.LoggerFactory;
14
15import net.floodlightcontroller.core.IFloodlightProviderService;
16import net.floodlightcontroller.core.IOFSwitch;
17import net.floodlightcontroller.core.IOFSwitchListener;
Pankaj Berdeda809572013-02-22 15:31:20 -080018import net.floodlightcontroller.core.module.FloodlightModuleContext;
19import net.floodlightcontroller.core.module.FloodlightModuleException;
20import net.floodlightcontroller.core.module.IFloodlightModule;
21import net.floodlightcontroller.core.module.IFloodlightService;
Pankaj Berdef08d5ff2013-03-14 17:03:07 -070022import net.floodlightcontroller.core.util.SingletonTask;
Pankaj Berdeda809572013-02-22 15:31:20 -080023import net.floodlightcontroller.devicemanager.IDevice;
24import net.floodlightcontroller.devicemanager.IDeviceListener;
25import net.floodlightcontroller.devicemanager.IDeviceService;
Pankaj Berde00e90882013-06-10 21:25:05 -070026import net.floodlightcontroller.routing.Link;
Pankaj Berdef08d5ff2013-03-14 17:03:07 -070027import net.floodlightcontroller.threadpool.IThreadPoolService;
Pankaj Berde38646d62013-06-21 11:34:04 -070028import net.onrc.onos.graph.GraphDBConnection;
29import net.onrc.onos.graph.GraphDBOperation;
30import net.onrc.onos.graph.IDBConnection;
31import net.onrc.onos.graph.LocalTopologyEventListener;
HIGUCHI Yuta2d011582013-06-15 01:47:11 -070032import net.onrc.onos.ofcontroller.core.IDeviceStorage;
33import net.onrc.onos.ofcontroller.core.ILinkStorage;
HIGUCHI Yuta36cf0762013-06-14 14:25:38 -070034import net.onrc.onos.ofcontroller.core.IOFSwitchPortListener;
HIGUCHI Yuta20514902013-06-12 11:24:16 -070035import net.onrc.onos.ofcontroller.core.ISwitchStorage;
36import net.onrc.onos.ofcontroller.core.INetMapStorage.DM_OPERATION;
HIGUCHI Yuta20514902013-06-12 11:24:16 -070037import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
38import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
HIGUCHI Yuta2d011582013-06-15 01:47:11 -070039import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
40import net.onrc.onos.ofcontroller.core.internal.LinkStorageImpl;
HIGUCHI Yutaed49ef72013-06-12 11:34:10 -070041import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
HIGUCHI Yutaa56fbde2013-06-17 14:26:05 -070042import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryListener;
43import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
Naoki Shiotab2d17e82013-10-18 18:08:16 -070044import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
Pankaj Berdef08d5ff2013-03-14 17:03:07 -070045import net.onrc.onos.registry.controller.IControllerRegistryService;
46import net.onrc.onos.registry.controller.IControllerRegistryService.ControlChangeCallback;
47import net.onrc.onos.registry.controller.RegistryException;
Pankaj Berdeda809572013-02-22 15:31:20 -080048
Pavlin Radoslavov28069402013-10-18 18:43:11 -070049public class NetworkGraphPublisher implements IDeviceListener,
50 IOFSwitchListener,
51 IOFSwitchPortListener,
52 ILinkDiscoveryListener,
53 IFloodlightModule,
54 INetworkGraphService {
Pankaj Berdeda809572013-02-22 15:31:20 -080055
56 protected IDeviceStorage devStore;
Pankaj Berdef08d5ff2013-03-14 17:03:07 -070057 protected ISwitchStorage swStore;
Pankaj Berde00e90882013-06-10 21:25:05 -070058 protected ILinkStorage linkStore;
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070059 protected final static Logger log = LoggerFactory.getLogger(NetworkGraphPublisher.class);
Pankaj Berdeda809572013-02-22 15:31:20 -080060 protected IDeviceService deviceService;
Pankaj Berdef08d5ff2013-03-14 17:03:07 -070061 protected IControllerRegistryService registryService;
Toshio Koide70ba38b2013-06-13 14:05:05 -070062 protected GraphDBOperation op;
Pankaj Berdeda809572013-02-22 15:31:20 -080063
64 protected static final String DBConfigFile = "dbconf";
Pankaj Berde1e3e5ba2013-03-15 13:17:53 -070065 protected static final String CleanupEnabled = "EnableCleanup";
Pankaj Berdef08d5ff2013-03-14 17:03:07 -070066 protected IThreadPoolService threadPool;
Pankaj Berde465ac7c2013-05-23 13:47:49 -070067 protected IFloodlightProviderService floodlightProvider;
Pankaj Berdef08d5ff2013-03-14 17:03:07 -070068
Pankaj Berde62016142013-04-09 15:35:50 -070069 protected final int CLEANUP_TASK_INTERVAL = 60; // 1 min
Pankaj Berdef08d5ff2013-03-14 17:03:07 -070070 protected SingletonTask cleanupTask;
Pankaj Berde00e90882013-06-10 21:25:05 -070071 protected ILinkDiscoveryService linkDiscovery;
Pankaj Berdef08d5ff2013-03-14 17:03:07 -070072
73 /**
74 * Cleanup and synch switch state from registry
75 */
76 protected class SwitchCleanup implements ControlChangeCallback, Runnable {
77 @Override
78 public void run() {
79 try {
80 log.debug("Running cleanup thread");
81 switchCleanup();
82 }
83 catch (Exception e) {
84 log.error("Error in cleanup thread", e);
85 } finally {
Toshio Koide70ba38b2013-06-13 14:05:05 -070086 op.close();
Pankaj Berdef08d5ff2013-03-14 17:03:07 -070087 cleanupTask.reschedule(CLEANUP_TASK_INTERVAL,
Pankaj Berde99fcee12013-03-18 09:41:53 -070088 TimeUnit.SECONDS);
Pankaj Berdef08d5ff2013-03-14 17:03:07 -070089 }
90 }
91
92 @Override
93 public void controlChanged(long dpid, boolean hasControl) {
Pankaj Berdef08d5ff2013-03-14 17:03:07 -070094 if (hasControl) {
Pankaj Berde99fcee12013-03-18 09:41:53 -070095 log.debug("got control to set inactive sw {}", HexString.toHexString(dpid));
Naoki Shiota987a5722013-10-23 11:59:36 -070096 try {
97 if (swStore.updateSwitch(HexString.toHexString(dpid), SwitchState.INACTIVE, DM_OPERATION.UPDATE)) {
98 registryService.releaseControl(dpid);
99
100 // TODO publish UPDATE_SWITCH event here
101 }
102 } catch (Exception e) {
103 log.error("Error in SwitchCleanup:controlChanged ", e);
104 }
Pankaj Berdef08d5ff2013-03-14 17:03:07 -0700105 }
106 }
107 }
Pankaj Berdef08d5ff2013-03-14 17:03:07 -0700108
Pankaj Berdef08d5ff2013-03-14 17:03:07 -0700109 protected void switchCleanup() {
Toshio Koide70ba38b2013-06-13 14:05:05 -0700110 op.close();
111 Iterable<ISwitchObject> switches = op.getActiveSwitches();
Jonathan Hartf02a0932013-03-18 18:30:48 -0700112
113 log.debug("Checking for inactive switches");
Pankaj Berdef08d5ff2013-03-14 17:03:07 -0700114 // For each switch check if a controller exists in controller registry
115 for (ISwitchObject sw: switches) {
Jonathan Hartf02a0932013-03-18 18:30:48 -0700116 //log.debug("checking if switch is inactive: {}", sw.getDPID());
Pankaj Berdef08d5ff2013-03-14 17:03:07 -0700117 try {
118 long dpid = HexString.toLong(sw.getDPID());
119 String controller = registryService.getControllerForSwitch(dpid);
120 if (controller == null) {
Pankaj Berde99fcee12013-03-18 09:41:53 -0700121 log.debug("request Control to set inactive sw {}", HexString.toHexString(dpid));
Pankaj Berdef08d5ff2013-03-14 17:03:07 -0700122 registryService.requestControl(dpid, new SwitchCleanup());
Umesh Krishnaswamy255b9882013-04-02 19:55:43 -0700123 //} else {
124 // log.debug("sw {} is controlled by controller: {}",HexString.toHexString(dpid),controller);
Pankaj Berdef08d5ff2013-03-14 17:03:07 -0700125 }
126 } catch (NumberFormatException e) {
Naoki Shiota987a5722013-10-23 11:59:36 -0700127 log.debug("Caught NumberFormatException trying to requestControl in cleanup thread");
Pankaj Berdef08d5ff2013-03-14 17:03:07 -0700128 e.printStackTrace();
129 } catch (RegistryException e) {
Jonathan Hart4baf3be2013-03-21 18:26:13 -0700130 log.debug("Caught RegistryException trying to requestControl in cleanup thread");
Pankaj Berdef08d5ff2013-03-14 17:03:07 -0700131 e.printStackTrace();
Naoki Shiota987a5722013-10-23 11:59:36 -0700132 }
Pankaj Berdef08d5ff2013-03-14 17:03:07 -0700133 }
Toshio Koide70ba38b2013-06-13 14:05:05 -0700134 op.close();
Pankaj Berdef08d5ff2013-03-14 17:03:07 -0700135 }
Pankaj Berdeda809572013-02-22 15:31:20 -0800136
137 @Override
138 public void linkDiscoveryUpdate(LDUpdate update) {
139 // TODO Auto-generated method stub
Pankaj Berde00e90882013-06-10 21:25:05 -0700140 Link lt = new Link(update.getSrc(),update.getSrcPort(),update.getDst(),update.getDstPort());
Jonathan Harte7c2d2f2013-07-27 18:08:34 +1200141 //log.debug("{}:LinkDicoveryUpdate(): Updating Link {}",this.getClass(), lt);
Pankaj Berde465ac7c2013-05-23 13:47:49 -0700142
Jonathan Harte7c2d2f2013-07-27 18:08:34 +1200143 switch (update.getOperation()) {
Pankaj Berde465ac7c2013-05-23 13:47:49 -0700144 case LINK_REMOVED:
Jonathan Harte7c2d2f2013-07-27 18:08:34 +1200145 log.debug("LinkDiscoveryUpdate(): Removing link {}", lt);
Naoki Shiota987a5722013-10-23 11:59:36 -0700146
147 if (linkStore.deleteLink(lt)) {
148 // TODO publish DELETE_LINK event here
149 }
Pankaj Berde465ac7c2013-05-23 13:47:49 -0700150 break;
Pankaj Berde00e90882013-06-10 21:25:05 -0700151 case LINK_UPDATED:
Jonathan Harte7c2d2f2013-07-27 18:08:34 +1200152 log.debug("LinkDiscoveryUpdate(): Updating link {}", lt);
Naoki Shiota987a5722013-10-23 11:59:36 -0700153
Naoki Shiotab2d17e82013-10-18 18:08:16 -0700154 LinkInfo linfo = linkStore.getLinkInfo(lt);
155 // TODO update "linfo" using portState derived using "update"
Naoki Shiota987a5722013-10-23 11:59:36 -0700156 if (linkStore.update(lt, linfo, DM_OPERATION.UPDATE)) {
157 // TODO publish UPDATE_LINK event here
158 }
Pankaj Berde00e90882013-06-10 21:25:05 -0700159 break;
160 case LINK_ADDED:
Jonathan Harte7c2d2f2013-07-27 18:08:34 +1200161 log.debug("LinkDiscoveryUpdate(): Adding link {}", lt);
Naoki Shiota987a5722013-10-23 11:59:36 -0700162
163 if (linkStore.addLink(lt)) {
164 // TODO publish ADD_LINK event here
165 }
Pankaj Berde00e90882013-06-10 21:25:05 -0700166 break;
Pankaj Berde465ac7c2013-05-23 13:47:49 -0700167 default:
168 break;
169 }
Pankaj Berdeda809572013-02-22 15:31:20 -0800170
171 }
172
173 @Override
174 public void addedSwitch(IOFSwitch sw) {
Pankaj Berde465ac7c2013-05-23 13:47:49 -0700175 if (registryService.hasControl(sw.getId())) {
Naoki Shiota987a5722013-10-23 11:59:36 -0700176 if (swStore.addSwitch(sw)) {
177 // TODO publish ADD_SWITCH event here
178 }
Pankaj Berde465ac7c2013-05-23 13:47:49 -0700179 }
Pankaj Berdeda809572013-02-22 15:31:20 -0800180 }
181
182 @Override
183 public void removedSwitch(IOFSwitch sw) {
Naoki Shiota987a5722013-10-23 11:59:36 -0700184 if (registryService.hasControl(sw.getId())) {
185 if (swStore.deleteSwitch(sw.getStringId())) {
186 // TODO publish DELETE_SWITCH event here
187 }
188 }
Pankaj Berdeda809572013-02-22 15:31:20 -0800189 }
190
191 @Override
192 public void switchPortChanged(Long switchId) {
193 // TODO Auto-generated method stub
Naoki Shiota987a5722013-10-23 11:59:36 -0700194 // NOTE: Event not needed here. This callback always coincide with add/remove callback.
Pankaj Berdeda809572013-02-22 15:31:20 -0800195 }
196
Pankaj Berde465ac7c2013-05-23 13:47:49 -0700197
198 @Override
199 public void switchPortAdded(Long switchId, OFPhysicalPort port) {
Naoki Shiota987a5722013-10-23 11:59:36 -0700200 if (swStore.addPort(HexString.toHexString(switchId), port)) {
201 // TODO publish ADD_PORT event here
202 }
Pankaj Berde465ac7c2013-05-23 13:47:49 -0700203 }
204
205 @Override
206 public void switchPortRemoved(Long switchId, OFPhysicalPort port) {
Naoki Shiota987a5722013-10-23 11:59:36 -0700207 if (swStore.deletePort(HexString.toHexString(switchId), port.getPortNumber())) {
208 // TODO publish DELETE_PORT event here
209 }
Pankaj Berde465ac7c2013-05-23 13:47:49 -0700210 }
211
Pankaj Berdeda809572013-02-22 15:31:20 -0800212 @Override
213 public String getName() {
HIGUCHI Yuta155cfc52013-06-14 15:54:16 -0700214 return "NetworkGraphPublisher";
Pankaj Berdeda809572013-02-22 15:31:20 -0800215 }
216
217 @Override
218 public void deviceAdded(IDevice device) {
Pankaj Berdeda809572013-02-22 15:31:20 -0800219 log.debug("{}:deviceAdded(): Adding device {}",this.getClass(),device.getMACAddressString());
220 devStore.addDevice(device);
221 }
222
223 @Override
224 public void deviceRemoved(IDevice device) {
225 // TODO Auto-generated method stub
226
227 }
228
229 @Override
230 public void deviceMoved(IDevice device) {
Pankaj Berdeda809572013-02-22 15:31:20 -0800231 devStore.changeDeviceAttachments(device);
Pankaj Berdeda809572013-02-22 15:31:20 -0800232 }
233
234 @Override
235 public void deviceIPV4AddrChanged(IDevice device) {
Pankaj Berdeda809572013-02-22 15:31:20 -0800236 devStore.changeDeviceIPv4Address(device);
Pankaj Berdeda809572013-02-22 15:31:20 -0800237 }
238
239 @Override
240 public void deviceVlanChanged(IDevice device) {
241 // TODO Auto-generated method stub
242 }
243
244
245 @Override
246 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
Pavlin Radoslavov28069402013-10-18 18:43:11 -0700247 Collection<Class<? extends IFloodlightService>> l =
248 new ArrayList<Class<? extends IFloodlightService>>();
249 l.add(INetworkGraphService.class);
250 return l;
Pankaj Berdeda809572013-02-22 15:31:20 -0800251 }
252
253 @Override
254 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
Pavlin Radoslavov28069402013-10-18 18:43:11 -0700255 Map<Class<? extends IFloodlightService>,
256 IFloodlightService> m =
257 new HashMap<Class<? extends IFloodlightService>,
258 IFloodlightService>();
259 m.put(INetworkGraphService.class, this);
260 return m;
Pankaj Berdeda809572013-02-22 15:31:20 -0800261 }
262
263 @Override
264 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
265 Collection<Class<? extends IFloodlightService>> l =
266 new ArrayList<Class<? extends IFloodlightService>>();
267 l.add(IFloodlightProviderService.class);
268 l.add(IDeviceService.class);
Pankaj Berdef08d5ff2013-03-14 17:03:07 -0700269 l.add(IThreadPoolService.class);
Pankaj Berdeda809572013-02-22 15:31:20 -0800270 return l;
271 }
272
273 @Override
274 public void init(FloodlightModuleContext context)
275 throws FloodlightModuleException {
Pankaj Berdeda809572013-02-22 15:31:20 -0800276 Map<String, String> configMap = context.getConfigParams(this);
277 String conf = configMap.get(DBConfigFile);
Toshio Koidebfe9b922013-06-18 10:56:05 -0700278 op = new GraphDBOperation(conf);
Pankaj Berdeda809572013-02-22 15:31:20 -0800279
Pankaj Berde465ac7c2013-05-23 13:47:49 -0700280 floodlightProvider =
281 context.getServiceImpl(IFloodlightProviderService.class);
Pankaj Berdeda809572013-02-22 15:31:20 -0800282 deviceService = context.getServiceImpl(IDeviceService.class);
Pankaj Berde00e90882013-06-10 21:25:05 -0700283 linkDiscovery = context.getServiceImpl(ILinkDiscoveryService.class);
Pankaj Berdef08d5ff2013-03-14 17:03:07 -0700284 threadPool = context.getServiceImpl(IThreadPoolService.class);
285 registryService = context.getServiceImpl(IControllerRegistryService.class);
Pankaj Berdeda809572013-02-22 15:31:20 -0800286
Pankaj Berdeda809572013-02-22 15:31:20 -0800287 devStore = new DeviceStorageImpl();
288 devStore.init(conf);
289
Pankaj Berdef08d5ff2013-03-14 17:03:07 -0700290 swStore = new SwitchStorageImpl();
291 swStore.init(conf);
Pankaj Berde00e90882013-06-10 21:25:05 -0700292
293 linkStore = new LinkStorageImpl();
294 linkStore.init(conf);
Pankaj Berdef08d5ff2013-03-14 17:03:07 -0700295
HIGUCHI Yuta155cfc52013-06-14 15:54:16 -0700296 log.debug("Initializing NetworkGraphPublisher module with {}", conf);
Pankaj Berdeda809572013-02-22 15:31:20 -0800297
298 }
299
300 @Override
301 public void startUp(FloodlightModuleContext context) {
Pankaj Berde1e3e5ba2013-03-15 13:17:53 -0700302 Map<String, String> configMap = context.getConfigParams(this);
303 String cleanupNeeded = configMap.get(CleanupEnabled);
304
Pankaj Berdef08d5ff2013-03-14 17:03:07 -0700305 deviceService.addListener(this);
Pankaj Berde465ac7c2013-05-23 13:47:49 -0700306 floodlightProvider.addOFSwitchListener(this);
Pankaj Berde00e90882013-06-10 21:25:05 -0700307 linkDiscovery.addListener(this);
Pankaj Berde9d6b5072013-04-03 11:51:23 -0700308
309 log.debug("Adding EventListener");
Toshio Koide70ba38b2013-06-13 14:05:05 -0700310 IDBConnection conn = op.getDBConnection();
311 conn.addEventListener(new LocalTopologyEventListener((GraphDBConnection) conn));
Pankaj Berdef08d5ff2013-03-14 17:03:07 -0700312 // Setup the Cleanup task.
Pankaj Berde99fcee12013-03-18 09:41:53 -0700313 if (cleanupNeeded == null || !cleanupNeeded.equals("False")) {
Pankaj Berde1e3e5ba2013-03-15 13:17:53 -0700314 ScheduledExecutorService ses = threadPool.getScheduledExecutor();
315 cleanupTask = new SingletonTask(ses, new SwitchCleanup());
Pankaj Berde99fcee12013-03-18 09:41:53 -0700316 cleanupTask.reschedule(CLEANUP_TASK_INTERVAL, TimeUnit.SECONDS);
Pankaj Berde1e3e5ba2013-03-15 13:17:53 -0700317 }
Pankaj Berdeda809572013-02-22 15:31:20 -0800318 }
319
320}