Implemented Cleanup thread to periodically detect inactive switches
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