blob: 58b8bc71ffe0365227eebf0a5084329eace83296 [file] [log] [blame]
Jonathan Hartd82f20d2013-02-21 18:04:24 -08001package net.onrc.onos.registry.controller;
Umesh Krishnaswamyb56bb292013-02-12 20:28:27 -08002
Jonathan Hartbd181b62013-02-17 16:05:38 -08003import java.io.IOException;
Jonathan Hartedd6a442013-02-20 15:22:06 -08004import java.io.UnsupportedEncodingException;
Umesh Krishnaswamyb56bb292013-02-12 20:28:27 -08005import java.util.ArrayList;
6import java.util.Collection;
Jonathan Hart3d7730a2013-02-22 11:51:17 -08007import java.util.Collections;
Umesh Krishnaswamyb56bb292013-02-12 20:28:27 -08008import java.util.HashMap;
Jonathan Hartedd6a442013-02-20 15:22:06 -08009import java.util.List;
Umesh Krishnaswamyb56bb292013-02-12 20:28:27 -080010import java.util.Map;
11
Umesh Krishnaswamyb56bb292013-02-12 20:28:27 -080012import net.floodlightcontroller.core.module.FloodlightModuleContext;
13import net.floodlightcontroller.core.module.FloodlightModuleException;
14import net.floodlightcontroller.core.module.IFloodlightModule;
15import net.floodlightcontroller.core.module.IFloodlightService;
Jonathan Hart3d7730a2013-02-22 11:51:17 -080016import net.floodlightcontroller.restserver.IRestApiService;
Umesh Krishnaswamyb56bb292013-02-12 20:28:27 -080017
Jonathan Hartedd6a442013-02-20 15:22:06 -080018import org.apache.zookeeper.CreateMode;
Jonathan Hartbd181b62013-02-17 16:05:38 -080019import org.apache.zookeeper.WatchedEvent;
Jonathan Hartc6eee9e2013-02-18 14:58:27 -080020import org.apache.zookeeper.Watcher.Event.KeeperState;
Jonathan Hartbd181b62013-02-17 16:05:38 -080021import org.openflow.util.HexString;
22import org.slf4j.Logger;
23import org.slf4j.LoggerFactory;
Umesh Krishnaswamyb56bb292013-02-12 20:28:27 -080024
Jonathan Hartbd181b62013-02-17 16:05:38 -080025import com.netflix.curator.RetryPolicy;
26import com.netflix.curator.framework.CuratorFramework;
27import com.netflix.curator.framework.CuratorFrameworkFactory;
28import com.netflix.curator.framework.api.CuratorWatcher;
Jonathan Hartedd6a442013-02-20 15:22:06 -080029import com.netflix.curator.framework.recipes.cache.ChildData;
30import com.netflix.curator.framework.recipes.cache.PathChildrenCache;
31import com.netflix.curator.framework.recipes.cache.PathChildrenCache.StartMode;
Jonathan Hart3d7730a2013-02-22 11:51:17 -080032import com.netflix.curator.framework.recipes.cache.PathChildrenCacheEvent;
33import com.netflix.curator.framework.recipes.cache.PathChildrenCacheListener;
Jonathan Hartbd181b62013-02-17 16:05:38 -080034import com.netflix.curator.framework.recipes.leader.LeaderLatch;
35import com.netflix.curator.framework.recipes.leader.Participant;
Jonathan Hart3d7730a2013-02-22 11:51:17 -080036import com.netflix.curator.retry.ExponentialBackoffRetry;
Jonathan Hartbd181b62013-02-17 16:05:38 -080037
Jonathan Hartbd766972013-02-22 15:13:03 -080038public class ZookeeperRegistry implements IFloodlightModule, IControllerRegistryService {
Jonathan Hartc6eee9e2013-02-18 14:58:27 -080039
Jonathan Hartbd766972013-02-22 15:13:03 -080040 protected static Logger log = LoggerFactory.getLogger(ZookeeperRegistry.class);
41 protected String controllerId = null;
Umesh Krishnaswamyb56bb292013-02-12 20:28:27 -080042
Jonathan Hart3d7730a2013-02-22 11:51:17 -080043 protected IRestApiService restApi;
44
Jonathan Hartbd181b62013-02-17 16:05:38 -080045 //TODO read this from configuration
46 protected String connectionString = "localhost:2181";
Jonathan Hart3d7730a2013-02-22 11:51:17 -080047
48
Jonathan Hartbd181b62013-02-17 16:05:38 -080049 private final String namespace = "onos";
Jonathan Hartedd6a442013-02-20 15:22:06 -080050 private final String switchLatchesPath = "/switches";
Jonathan Hart3d7730a2013-02-22 11:51:17 -080051 private final String controllerPath = "/controllers";
Jonathan Hartbd181b62013-02-17 16:05:38 -080052
53 protected CuratorFramework client;
Jonathan Hartedd6a442013-02-20 15:22:06 -080054
Jonathan Hartedd6a442013-02-20 15:22:06 -080055 protected PathChildrenCache controllerCache;
Jonathan Hart3d7730a2013-02-22 11:51:17 -080056 protected PathChildrenCache switchCache;
Jonathan Hartbd181b62013-02-17 16:05:38 -080057
58 protected Map<String, LeaderLatch> switchLatches;
Jonathan Hartd82f20d2013-02-21 18:04:24 -080059 protected Map<String, ControlChangeCallback> switchCallbacks;
Jonathan Hart3d7730a2013-02-22 11:51:17 -080060 protected Map<String, PathChildrenCache> switchPathCaches;
Jonathan Hartbd181b62013-02-17 16:05:38 -080061
Jonathan Hartbd766972013-02-22 15:13:03 -080062 //protected boolean zookeeperEnabled = false;
Jonathan Hart57080fb2013-02-21 10:55:46 -080063
Jonathan Hartbd181b62013-02-17 16:05:38 -080064 protected class ParamaterizedCuratorWatcher implements CuratorWatcher {
65 private String dpid;
Jonathan Hartc6eee9e2013-02-18 14:58:27 -080066 private boolean isLeader = false;
Jonathan Hartbd181b62013-02-17 16:05:38 -080067 private String latchPath;
68
69 public ParamaterizedCuratorWatcher(String dpid, String latchPath){
70 this.dpid = dpid;
71 this.latchPath = latchPath;
72 }
73
74 @Override
Jonathan Hartedd6a442013-02-20 15:22:06 -080075 public synchronized void process(WatchedEvent event) throws Exception {
Jonathan Hartbd181b62013-02-17 16:05:38 -080076 log.debug("Watch Event: {}", event);
77
78 LeaderLatch latch = switchLatches.get(dpid);
79
Jonathan Hartc6eee9e2013-02-18 14:58:27 -080080 if (event.getState() == KeeperState.Disconnected){
81 if (isLeader) {
82 log.debug("Disconnected while leader - lost leadership for {}", dpid);
83
84 isLeader = false;
Jonathan Hart3d7730a2013-02-22 11:51:17 -080085 ControlChangeCallback cb = switchCallbacks.get(dpid);
86 if (cb != null) {
87 //Allow callback to be null if the requester doesn't want a callback
88 cb.controlChanged(HexString.toLong(dpid), false);
89 }
Jonathan Hartc6eee9e2013-02-18 14:58:27 -080090 }
91 return;
92 }
Jonathan Hartbd181b62013-02-17 16:05:38 -080093
Jonathan Hartc6eee9e2013-02-18 14:58:27 -080094 try {
Jonathan Hartedd6a442013-02-20 15:22:06 -080095
Jonathan Hartc6eee9e2013-02-18 14:58:27 -080096 Participant leader = latch.getLeader();
97
Jonathan Hartbd766972013-02-22 15:13:03 -080098 if (leader.getId().equals(controllerId) && !isLeader){
Jonathan Hartc6eee9e2013-02-18 14:58:27 -080099 log.debug("Became leader for {}", dpid);
100
101 isLeader = true;
Jonathan Hartd82f20d2013-02-21 18:04:24 -0800102 switchCallbacks.get(dpid).controlChanged(HexString.toLong(dpid), true);
Jonathan Hartc6eee9e2013-02-18 14:58:27 -0800103 }
Jonathan Hartbd766972013-02-22 15:13:03 -0800104 else if (!leader.getId().equals(controllerId) && isLeader){
Jonathan Hartc6eee9e2013-02-18 14:58:27 -0800105 log.debug("Lost leadership for {}", dpid);
106
107 isLeader = false;
Jonathan Hartd82f20d2013-02-21 18:04:24 -0800108 switchCallbacks.get(dpid).controlChanged(HexString.toLong(dpid), false);
Jonathan Hartc6eee9e2013-02-18 14:58:27 -0800109 }
110 } catch (Exception e){
111 if (isLeader){
112 log.debug("Exception checking leadership status. Assume leadship lost for {}",
113 dpid);
114
115 isLeader = false;
Jonathan Hartd82f20d2013-02-21 18:04:24 -0800116 switchCallbacks.get(dpid).controlChanged(HexString.toLong(dpid), false);
Jonathan Hartc6eee9e2013-02-18 14:58:27 -0800117 }
Jonathan Hartbd181b62013-02-17 16:05:38 -0800118 }
119
120 client.getChildren().usingWatcher(this).inBackground().forPath(latchPath);
121 //client.getChildren().usingWatcher(this).forPath(latchPath);
122 }
Jonathan Hartc6eee9e2013-02-18 14:58:27 -0800123 }
Jonathan Hart3d7730a2013-02-22 11:51:17 -0800124
125
126 /*
127 * Listens for changes to the switch znodes in Zookeeper. This maintains the second level of
128 * PathChildrenCaches that hold the controllers contending for each switch - there's one for
129 * each switch.
130 */
131 PathChildrenCacheListener switchPathCacheListener = new PathChildrenCacheListener() {
132 @Override
133 public void childEvent(CuratorFramework client,
134 PathChildrenCacheEvent event) throws Exception {
135 // TODO Auto-generated method stub
136 log.debug("Root switch path cache got {} event", event.getType());
137
138 String strSwitch = null;
139 if (event.getData() != null){
140 log.debug("Event path {}", event.getData().getPath());
141 String[] splitted = event.getData().getPath().split("/");
142 strSwitch = splitted[splitted.length - 1];
143 log.debug("Switch name is {}", strSwitch);
144 }
145
146 switch (event.getType()){
147 case CHILD_ADDED:
148 case CHILD_UPDATED:
149 //Check we have a PathChildrenCache for this child, add one if not
150 if (switchPathCaches.get(strSwitch) == null){
151 PathChildrenCache pc = new PathChildrenCache(client,
152 event.getData().getPath(), true);
153 pc.start(StartMode.NORMAL);
154 switchPathCaches.put(strSwitch, pc);
155 }
156 break;
157 case CHILD_REMOVED:
158 //Remove our PathChildrenCache for this child
159 PathChildrenCache pc = switchPathCaches.remove(strSwitch);
160 pc.close();
161 break;
162 default:
163 //All other events are connection status events. We need to do anything
164 //as the path cache handles these on its own.
165 break;
166 }
167
168 }
169 };
Jonathan Hartedd6a442013-02-20 15:22:06 -0800170
Jonathan Hartbd181b62013-02-17 16:05:38 -0800171
172 @Override
Jonathan Hart3d7730a2013-02-22 11:51:17 -0800173 public void requestControl(long dpid, ControlChangeCallback cb) throws RegistryException {
Jonathan Hartbd766972013-02-22 15:13:03 -0800174 /*
175 if (!zookeeperEnabled) {
176 //If zookeeper connection is disabled all control requests succeed immediately
177 if (cb != null){
178 cb.controlChanged(dpid, true);
179 }
180 return;
181 }*/
Jonathan Hartc6eee9e2013-02-18 14:58:27 -0800182
Jonathan Hartbd766972013-02-22 15:13:03 -0800183 if (controllerId == null){
184 throw new RuntimeException("Must register a controller before calling requestControl");
Jonathan Hartbd181b62013-02-17 16:05:38 -0800185 }
186
187 String dpidStr = HexString.toHexString(dpid);
188 String latchPath = switchLatchesPath + "/" + dpidStr;
189
Jonathan Hartc6eee9e2013-02-18 14:58:27 -0800190 if (switchLatches.get(dpidStr) != null){
191 throw new RuntimeException("Leader election for switch " + dpidStr +
192 "is already running");
193 }
194
Jonathan Hartbd766972013-02-22 15:13:03 -0800195 LeaderLatch latch = new LeaderLatch(client, latchPath, controllerId);
Jonathan Hartbd181b62013-02-17 16:05:38 -0800196 switchLatches.put(dpidStr, latch);
Jonathan Hartbd181b62013-02-17 16:05:38 -0800197 switchCallbacks.put(dpidStr, cb);
198
199 try {
200 //client.getChildren().usingWatcher(watcher).inBackground().forPath(singleLatchPath);
201 client.getChildren().usingWatcher(
202 new ParamaterizedCuratorWatcher(dpidStr, latchPath))
203 .inBackground().forPath(latchPath);
204 latch.start();
205 } catch (Exception e) {
Jonathan Hartc6eee9e2013-02-18 14:58:27 -0800206 log.warn("Error starting leader latch: {}", e.getMessage());
Jonathan Hart3d7730a2013-02-22 11:51:17 -0800207 throw new RegistryException("Error starting leader latch for " + dpidStr, e);
Jonathan Hartbd181b62013-02-17 16:05:38 -0800208 }
209
210 }
211
212 @Override
Jonathan Hartd82f20d2013-02-21 18:04:24 -0800213 public void releaseControl(long dpid) {
Jonathan Hartbd766972013-02-22 15:13:03 -0800214 //if (!zookeeperEnabled) return;
Jonathan Hart57080fb2013-02-21 10:55:46 -0800215
Jonathan Hartc6eee9e2013-02-18 14:58:27 -0800216 String dpidStr = HexString.toHexString(dpid);
217
218 LeaderLatch latch = switchLatches.get(dpidStr);
Jonathan Hartbd181b62013-02-17 16:05:38 -0800219 if (latch == null) {
Jonathan Hartc6eee9e2013-02-18 14:58:27 -0800220 log.debug("Trying to release mastership for switch we are not contesting");
Jonathan Hartbd181b62013-02-17 16:05:38 -0800221 return;
222 }
223
224 try {
225 latch.close();
226 } catch (IOException e) {
Jonathan Hart1be46262013-02-20 16:43:51 -0800227 //I think it's OK not to do anything here. Either the node got deleted correctly,
228 //or the connection went down and the node got deleted.
229 } finally {
230 switchLatches.remove(dpidStr);
231 switchCallbacks.remove(dpidStr);
Jonathan Hartbd181b62013-02-17 16:05:38 -0800232 }
233 }
234
235 @Override
Jonathan Hartd82f20d2013-02-21 18:04:24 -0800236 public boolean hasControl(long dpid) {
Jonathan Hartbd766972013-02-22 15:13:03 -0800237 //if (!zookeeperEnabled) return false;
Jonathan Hart57080fb2013-02-21 10:55:46 -0800238
Jonathan Hartbd181b62013-02-17 16:05:38 -0800239 LeaderLatch latch = switchLatches.get(HexString.toHexString(dpid));
240
241 if (latch == null) {
242 log.warn("No leader latch for dpid {}", HexString.toHexString(dpid));
243 return false;
244 }
245
Jonathan Hartbd181b62013-02-17 16:05:38 -0800246 try {
Jonathan Hartbd766972013-02-22 15:13:03 -0800247 return latch.getLeader().getId().equals(controllerId);
Jonathan Hartbd181b62013-02-17 16:05:38 -0800248 } catch (Exception e) {
249 //TODO swallow exception?
250 return false;
251 }
252 }
253
254 @Override
255 public void setMastershipId(String id) {
Jonathan Hartbd766972013-02-22 15:13:03 -0800256 //TODO remove this method if not needed
257 //controllerId = id;
Jonathan Hartbd181b62013-02-17 16:05:38 -0800258 }
259
260 @Override
261 public String getMastershipId() {
Jonathan Hartbd766972013-02-22 15:13:03 -0800262 return controllerId;
Jonathan Hartbd181b62013-02-17 16:05:38 -0800263 }
264
Jonathan Hartedd6a442013-02-20 15:22:06 -0800265 @Override
Jonathan Hart57080fb2013-02-21 10:55:46 -0800266 public Collection<String> getAllControllers() throws RegistryException {
Jonathan Hartbd766972013-02-22 15:13:03 -0800267 //if (!zookeeperEnabled) return null;
Jonathan Hart57080fb2013-02-21 10:55:46 -0800268
Jonathan Hartedd6a442013-02-20 15:22:06 -0800269 log.debug("Getting all controllers");
Jonathan Hart1be46262013-02-20 16:43:51 -0800270
Jonathan Hartedd6a442013-02-20 15:22:06 -0800271 List<String> controllers = new ArrayList<String>();
272 for (ChildData data : controllerCache.getCurrentData()){
273
274 String d = null;
275 try {
276 d = new String(data.getData(), "UTF-8");
277 } catch (UnsupportedEncodingException e) {
Jonathan Hart57080fb2013-02-21 10:55:46 -0800278 throw new RegistryException("Error encoding string", e);
Jonathan Hartedd6a442013-02-20 15:22:06 -0800279 }
280
281 controllers.add(d);
282 }
283 return controllers;
284 }
285
286 @Override
Jonathan Hart57080fb2013-02-21 10:55:46 -0800287 public void registerController(String id) throws RegistryException {
Jonathan Hartbd766972013-02-22 15:13:03 -0800288 //if (!zookeeperEnabled) return;
289
290 controllerId = id;
Jonathan Hart57080fb2013-02-21 10:55:46 -0800291
Jonathan Hartedd6a442013-02-20 15:22:06 -0800292 byte bytes[] = null;
293 try {
294 bytes = id.getBytes("UTF-8");
295 } catch (UnsupportedEncodingException e1) {
Jonathan Hart57080fb2013-02-21 10:55:46 -0800296 throw new RegistryException("Error encoding string", e1);
Jonathan Hartedd6a442013-02-20 15:22:06 -0800297 }
298
299 String path = controllerPath + "/" + id;
300
301 log.info("Registering controller with id {}", id);
302
Jonathan Hart57080fb2013-02-21 10:55:46 -0800303 //Create ephemeral node in controller registry
Jonathan Hartedd6a442013-02-20 15:22:06 -0800304 try {
305 client.create().withProtection().withMode(CreateMode.EPHEMERAL)
306 .forPath(path, bytes);
307 } catch (Exception e) {
Jonathan Hart57080fb2013-02-21 10:55:46 -0800308 throw new RegistryException("Error contacting the Zookeeper service", e);
Jonathan Hartedd6a442013-02-20 15:22:06 -0800309 }
310 }
311
312 @Override
Jonathan Hart57080fb2013-02-21 10:55:46 -0800313 public String getControllerForSwitch(long dpid) throws RegistryException {
Jonathan Hartbd766972013-02-22 15:13:03 -0800314 //if (!zookeeperEnabled) return null;
Jonathan Hartedd6a442013-02-20 15:22:06 -0800315 // TODO Work out how we should store this controller/switch data.
316 // The leader latch might be a index to the /controllers collections
317 // which holds more info on the controller (how to talk to it for example).
318
319
320 String strDpid = HexString.toHexString(dpid);
321 LeaderLatch latch = switchLatches.get(strDpid);
322
323 if (latch == null){
324 log.warn("Tried to get controller for non-existent switch");
325 return null;
326 }
327
328 Participant leader = null;
329 try {
330 leader = latch.getLeader();
331 } catch (Exception e) {
Jonathan Hart57080fb2013-02-21 10:55:46 -0800332 throw new RegistryException("Error contacting the Zookeeper service", e);
Jonathan Hartedd6a442013-02-20 15:22:06 -0800333 }
334
335 return leader.getId();
336 }
337
338 @Override
339 public Collection<Long> getSwitchesControlledByController(String controllerId) {
Jonathan Hart3d7730a2013-02-22 11:51:17 -0800340 //TODO remove this if not needed
Jonathan Hartbd766972013-02-22 15:13:03 -0800341 throw new RuntimeException("Not yet implemented");
Jonathan Hartedd6a442013-02-20 15:22:06 -0800342 }
Jonathan Hartbd181b62013-02-17 16:05:38 -0800343
Jonathan Hartd82f20d2013-02-21 18:04:24 -0800344
345 @Override
Jonathan Hart3d7730a2013-02-22 11:51:17 -0800346 public Map<String, List<ControllerRegistryEntry>> getAllSwitches() {
347 Map<String, List<ControllerRegistryEntry>> data =
348 new HashMap<String, List<ControllerRegistryEntry>>();
349
350 for (Map.Entry<String, PathChildrenCache> entry : switchPathCaches.entrySet()){
351 List<ControllerRegistryEntry> contendingControllers =
352 new ArrayList<ControllerRegistryEntry>();
353
354 if (entry.getValue().getCurrentData().size() < 1){
355 log.info("Switch entry with no leader elections: {}", entry.getKey());
356 continue;
357 }
358
359 for (ChildData d : entry.getValue().getCurrentData()) {
360 /*
361 if (d.getPath().length() < 1){
362 log.info("Switch entry with no leader elections: {}", d.getPath());
363 continue;
364 }
365 */
366
367 String controllerId = null;
368 try {
369 controllerId = new String(d.getData(), "UTF-8");
370 } catch (UnsupportedEncodingException e) {
371 log.warn("Encoding exception: {}", e.getMessage());
372 }
373
374 String[] splitted = d.getPath().split("-");
375 int sequenceNumber = Integer.parseInt(splitted[splitted.length - 1]);
376
377 contendingControllers.add(new ControllerRegistryEntry(controllerId, sequenceNumber));
378 }
379
380 Collections.sort(contendingControllers);
381 data.put(entry.getKey(), contendingControllers);
382 }
383 return data;
Jonathan Hartd82f20d2013-02-21 18:04:24 -0800384 }
385
Jonathan Hartbd181b62013-02-17 16:05:38 -0800386 /*
387 * IFloodlightModule
388 */
389
Umesh Krishnaswamyb56bb292013-02-12 20:28:27 -0800390 @Override
391 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
Jonathan Hartedd6a442013-02-20 15:22:06 -0800392 Collection<Class<? extends IFloodlightService>> l =
393 new ArrayList<Class<? extends IFloodlightService>>();
Jonathan Hartd82f20d2013-02-21 18:04:24 -0800394 l.add(IControllerRegistryService.class);
Umesh Krishnaswamyb56bb292013-02-12 20:28:27 -0800395 return l;
396 }
397
398 @Override
399 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
400 Map<Class<? extends IFloodlightService>, IFloodlightService> m =
401 new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
Jonathan Hartd82f20d2013-02-21 18:04:24 -0800402 m.put(IControllerRegistryService.class, this);
Umesh Krishnaswamyb56bb292013-02-12 20:28:27 -0800403 return m;
404 }
405
406 @Override
407 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
Jonathan Hart3d7730a2013-02-22 11:51:17 -0800408 Collection<Class<? extends IFloodlightService>> l =
409 new ArrayList<Class<? extends IFloodlightService>>();
410 l.add(IRestApiService.class);
411 return l;
Umesh Krishnaswamyb56bb292013-02-12 20:28:27 -0800412 }
413
414 @Override
415 public void init (FloodlightModuleContext context) throws FloodlightModuleException {
Jonathan Hart57080fb2013-02-21 10:55:46 -0800416
Jonathan Hartbd766972013-02-22 15:13:03 -0800417 log.info("Initialising the Zookeeper Registry - Zookeeper connection required");
418
Jonathan Hart3d7730a2013-02-22 11:51:17 -0800419 restApi = context.getServiceImpl(IRestApiService.class);
420
Jonathan Hartbd766972013-02-22 15:13:03 -0800421 //We have a config option that determines whether we try and connect to
422 //zookeeper or not. By default zookeeper connection is disabled. When we don't
423 //have a zookeeper connection we act as though we are the only server in the
424 //cluster, i.e. all control requests will succeed.
425 /*Map<String, String> configOptions = context.getConfigParams(this);
Jonathan Hart57080fb2013-02-21 10:55:46 -0800426 String enableZookeeper = configOptions.get("enableZookeeper");
427 if (enableZookeeper != null) {
Jonathan Hartbd766972013-02-22 15:13:03 -0800428 log.info("Enabling Zookeeper connection");
429 zookeeperEnabled = true;
Jonathan Hart57080fb2013-02-21 10:55:46 -0800430 }
431 else {
Jonathan Hartbd766972013-02-22 15:13:03 -0800432 log.info("Zookeeper connectivity is disabled - running in standalone mode");
Jonathan Hart57080fb2013-02-21 10:55:46 -0800433 return;
Jonathan Hartbd766972013-02-22 15:13:03 -0800434 }*/
Jonathan Hart57080fb2013-02-21 10:55:46 -0800435
Jonathan Hartbd766972013-02-22 15:13:03 -0800436 /*
Jonathan Hartbd181b62013-02-17 16:05:38 -0800437 try {
438 String localHostname = java.net.InetAddress.getLocalHost().getHostName();
Jonathan Hartbd766972013-02-22 15:13:03 -0800439 controllerId = localHostname;
440 log.debug("Setting controller id to {}", controllerId);
Jonathan Hartbd181b62013-02-17 16:05:38 -0800441 } catch (UnknownHostException e) {
442 // TODO Handle this exception
443 e.printStackTrace();
Jonathan Hartbd766972013-02-22 15:13:03 -0800444 }*/
Jonathan Hartbd181b62013-02-17 16:05:38 -0800445
446 switchLatches = new HashMap<String, LeaderLatch>();
Jonathan Hartd82f20d2013-02-21 18:04:24 -0800447 switchCallbacks = new HashMap<String, ControlChangeCallback>();
Jonathan Hart3d7730a2013-02-22 11:51:17 -0800448 switchPathCaches = new HashMap<String, PathChildrenCache>();
Jonathan Hartbd181b62013-02-17 16:05:38 -0800449
Jonathan Hart3d7730a2013-02-22 11:51:17 -0800450 RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
Jonathan Hartbd181b62013-02-17 16:05:38 -0800451 client = CuratorFrameworkFactory.newClient(connectionString, retryPolicy);
452
453 client.start();
454
455 client = client.usingNamespace(namespace);
456
Jonathan Hart3d7730a2013-02-22 11:51:17 -0800457 //Put some data in for testing
Jonathan Hartbd766972013-02-22 15:13:03 -0800458 /*
Jonathan Hart3d7730a2013-02-22 11:51:17 -0800459 try {
Jonathan Hartbd766972013-02-22 15:13:03 -0800460 registerController("zookeeperController");
Jonathan Hart3d7730a2013-02-22 11:51:17 -0800461 requestControl(2L, null);
462 } catch (RegistryException e1) {
463 // TODO Auto-generated catch block
464 e1.printStackTrace();
Jonathan Hartbd766972013-02-22 15:13:03 -0800465 }*/
Jonathan Hart3d7730a2013-02-22 11:51:17 -0800466
Jonathan Hartedd6a442013-02-20 15:22:06 -0800467 controllerCache = new PathChildrenCache(client, controllerPath, true);
Jonathan Hart3d7730a2013-02-22 11:51:17 -0800468 switchCache = new PathChildrenCache(client, switchLatchesPath, true);
469 switchCache.getListenable().addListener(switchPathCacheListener);
Jonathan Hartedd6a442013-02-20 15:22:06 -0800470
471 try {
472 controllerCache.start(StartMode.BUILD_INITIAL_CACHE);
Jonathan Hart3d7730a2013-02-22 11:51:17 -0800473
474 //Don't prime the cache, we want a notification for each child node in the path
475 switchCache.start(StartMode.NORMAL);
Jonathan Hartedd6a442013-02-20 15:22:06 -0800476 } catch (Exception e) {
477 // TODO Auto-generated catch block
478 e.printStackTrace();
479 }
Umesh Krishnaswamyb56bb292013-02-12 20:28:27 -0800480 }
481
482 @Override
483 public void startUp (FloodlightModuleContext context) {
Jonathan Hart3d7730a2013-02-22 11:51:17 -0800484 restApi.addRestletRoutable(new RegistryWebRoutable());
Umesh Krishnaswamyb56bb292013-02-12 20:28:27 -0800485 }
Jonathan Hartd82f20d2013-02-21 18:04:24 -0800486
Umesh Krishnaswamyb56bb292013-02-12 20:28:27 -0800487}