Merge branch 'master' of https://github.com/OPENNETWORKINGLAB/ONOS
diff --git a/src/main/java/net/floodlightcontroller/core/internal/SwitchStorageImpl.java b/src/main/java/net/floodlightcontroller/core/internal/SwitchStorageImpl.java
index 6be26cb..7e049b6 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/SwitchStorageImpl.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/SwitchStorageImpl.java
@@ -16,6 +16,7 @@
 import com.thinkaurelius.titan.core.TitanFactory;
 import com.thinkaurelius.titan.core.TitanGraph;
 import com.tinkerpop.blueprints.Direction;
+import com.tinkerpop.blueprints.TransactionalGraph;
 import com.tinkerpop.blueprints.TransactionalGraph.Conclusion;
 import com.tinkerpop.blueprints.Edge;
 import com.tinkerpop.blueprints.Vertex;
@@ -244,9 +245,6 @@
 		FramedGraph<TitanGraph> fg = new FramedGraph<TitanGraph>(graph);
 		Iterable<ISwitchObject> switches =  fg.getVertices("type","switch",ISwitchObject.class);
 
-		for (ISwitchObject sw: switches) {
-			log.debug("switch: {}", sw.getDPID());
-		}
 
 		return switches;
 	}
diff --git a/src/main/java/net/floodlightcontroller/onoslistener/OnosPublisher.java b/src/main/java/net/floodlightcontroller/onoslistener/OnosPublisher.java
index 2a66527..a6931e6 100644
--- a/src/main/java/net/floodlightcontroller/onoslistener/OnosPublisher.java
+++ b/src/main/java/net/floodlightcontroller/onoslistener/OnosPublisher.java
@@ -3,34 +3,110 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Map;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
 
+import org.openflow.util.HexString;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.INetMapStorage.DM_OPERATION;
+import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.floodlightcontroller.core.ISwitchStorage.SwitchState;
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.IOFSwitchListener;
 import net.floodlightcontroller.core.ISwitchStorage;
 import net.floodlightcontroller.core.internal.SwitchStorageImpl;
+import net.floodlightcontroller.core.internal.TopoSwitchServiceImpl;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.module.FloodlightModuleException;
 import net.floodlightcontroller.core.module.IFloodlightModule;
 import net.floodlightcontroller.core.module.IFloodlightService;
+import net.floodlightcontroller.core.util.SingletonTask;
 import net.floodlightcontroller.devicemanager.IDevice;
 import net.floodlightcontroller.devicemanager.IDeviceListener;
 import net.floodlightcontroller.devicemanager.IDeviceService;
 import net.floodlightcontroller.devicemanager.IDeviceStorage;
 import net.floodlightcontroller.devicemanager.internal.DeviceStorageImpl;
 import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryListener;
+import net.floodlightcontroller.threadpool.IThreadPoolService;
+import net.onrc.onos.registry.controller.IControllerRegistryService;
+import net.onrc.onos.registry.controller.IControllerRegistryService.ControlChangeCallback;
+import net.onrc.onos.registry.controller.RegistryException;
 
 public class OnosPublisher implements IDeviceListener, IOFSwitchListener,
 		ILinkDiscoveryListener, IFloodlightModule {
 	
 	protected IDeviceStorage devStore;
+	protected ISwitchStorage swStore;
 	protected static Logger log;
 	protected IDeviceService deviceService;
+	protected IControllerRegistryService registryService;
 	
 	protected static final String DBConfigFile = "dbconf";
+	protected IThreadPoolService threadPool;
+	
+	protected final int CLEANUP_TASK_INTERVAL = 999; // 999 ms
+	protected SingletonTask cleanupTask;
+	
+	/**
+     *  Cleanup and synch switch state from registry
+     */
+    protected class SwitchCleanup implements ControlChangeCallback, Runnable {
+        @Override
+        public void run() {
+            try {
+            	log.debug("Running cleanup thread");
+                switchCleanup();
+            }
+            catch (Exception e) {
+                log.error("Error in cleanup thread", e);
+            } finally {
+                    cleanupTask.reschedule(CLEANUP_TASK_INTERVAL,
+                                              TimeUnit.MILLISECONDS);
+            }
+        }
+
+		@Override
+		public void controlChanged(long dpid, boolean hasControl) {
+			// TODO Auto-generated method stub
+			
+			if (hasControl) {
+				log.debug("got control to set inactive sw {}", dpid);
+				swStore.update(HexString.toHexString(dpid),SwitchState.INACTIVE, DM_OPERATION.UPDATE);
+			    registryService.releaseControl(dpid);	
+			}						
+		}
+    }
+    
+
+    
+    protected void switchCleanup() {
+    	
+    	TopoSwitchServiceImpl impl = new TopoSwitchServiceImpl();
+    	Iterable<ISwitchObject> switches = impl.getActiveSwitches();
+    	// For each switch check if a controller exists in controller registry
+    	for (ISwitchObject sw: switches) {
+			log.debug("checking if switch is inactive: {}", sw.getDPID());
+			try {
+				long dpid = HexString.toLong(sw.getDPID());
+				String controller = registryService.getControllerForSwitch(dpid);
+				if (controller == null) {
+					log.debug("request Control to set inactive sw {}", dpid);
+					registryService.requestControl(dpid, new SwitchCleanup());
+				} else {
+					log.debug("sw {} is controlled by controller: {}",dpid,controller);
+				}
+			} catch (NumberFormatException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} catch (RegistryException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}			
+		}
+    }
 
 	@Override
 	public void linkDiscoveryUpdate(LDUpdate update) {
@@ -112,6 +188,7 @@
 	            new ArrayList<Class<? extends IFloodlightService>>();
 	        l.add(IFloodlightProviderService.class);
 	        l.add(IDeviceService.class);
+	        l.add(IThreadPoolService.class);
 	        return l;
 	}
 
@@ -124,10 +201,15 @@
 		
 		log = LoggerFactory.getLogger(OnosPublisher.class);
 		deviceService = context.getServiceImpl(IDeviceService.class);
+		threadPool = context.getServiceImpl(IThreadPoolService.class);
+		registryService = context.getServiceImpl(IControllerRegistryService.class);
 		
 		devStore = new DeviceStorageImpl();
 		devStore.init(conf);
 		
+		swStore = new SwitchStorageImpl();
+		swStore.init(conf);
+				
 		log.debug("Initializing OnosPublisher module with {}", conf);
 		
 	}
@@ -135,7 +217,11 @@
 	@Override
 	public void startUp(FloodlightModuleContext context) {
 		// TODO Auto-generated method stub
-		deviceService.addListener(this);		
+		ScheduledExecutorService ses = threadPool.getScheduledExecutor();
+		deviceService.addListener(this);
+	       // Setup the Cleanup task. 
+        cleanupTask = new SingletonTask(ses, new SwitchCleanup());
+        cleanupTask.reschedule(CLEANUP_TASK_INTERVAL, TimeUnit.MILLISECONDS);
 	}
 
 }
diff --git a/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java b/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java
index 7345084..2c220fd 100644
--- a/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java
+++ b/src/main/java/net/onrc/onos/registry/controller/StandaloneRegistry.java
@@ -91,7 +91,7 @@
 
 	@Override
 	public String getControllerForSwitch(long dpid) throws RegistryException {
-		return controllerId;
+		return (switchCallbacks.get(HexString.toHexString(dpid)) != null)? controllerId: null;
 	}
 
 	@Override
diff --git a/src/main/resources/floodlightdefault.properties b/src/main/resources/floodlightdefault.properties
index 9ea7a92..498fce5 100644
--- a/src/main/resources/floodlightdefault.properties
+++ b/src/main/resources/floodlightdefault.properties
@@ -10,7 +10,7 @@
 net.floodlightcontroller.perfmon.PktInProcessingTime,\
 net.floodlightcontroller.ui.web.StaticWebRoutable,\
 net.floodlightcontroller.onoslistener.OnosPublisher, \
-net.onrc.onos.registry.controller.StandaloneRegistry
+net.onrc.onos.registry.controller.ZookeeperRegistry
 net.floodlightcontroller.restserver.RestApiServer.port = 8080
 net.floodlightcontroller.core.FloodlightProvider.openflowport = 6633
 net.floodlightcontroller.jython.JythonDebugInterface.port = 6655