Merge remote-tracking branch 'upstream/master' into syncdev

Conflicts:
	src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowProgrammer.java
	src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowProgrammer.java b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowProgrammer.java
index b567a87..45f59b3 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowProgrammer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowProgrammer.java
@@ -5,22 +5,32 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import org.openflow.protocol.OFFlowRemoved;
+import org.openflow.protocol.OFMessage;
+import org.openflow.protocol.OFType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import net.floodlightcontroller.core.FloodlightContext;
 import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.IOFMessageListener;
+import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.IOFSwitchListener;
 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.onrc.onos.registry.controller.IControllerRegistryService;
 
-public class FlowProgrammer implements IFloodlightModule {
+public class FlowProgrammer implements IFloodlightModule, 
+				       IOFMessageListener,
+				       IOFSwitchListener {
     @SuppressWarnings("unused")
-	private final static Logger log = LoggerFactory.getLogger(FlowProgrammer.class);
-
-	private static final boolean enableFlowSync = false;
-	
+    private static final boolean enableFlowSync = false;
+    protected static Logger log = LoggerFactory.getLogger(FlowProgrammer.class);
     protected volatile IFloodlightProviderService floodlightProvider;
+    protected volatile IControllerRegistryService registryService;
+
 
     protected FlowPusher pusher;
     private static final int NUM_PUSHER_THREAD = 1;
@@ -30,7 +40,7 @@
     public FlowProgrammer() {
 	pusher = new FlowPusher(NUM_PUSHER_THREAD);
 	if (enableFlowSync) {
-	synchronizer = new FlowSynchronizer();
+	    synchronizer = new FlowSynchronizer();
 	}
     }
     
@@ -38,18 +48,18 @@
     public void init(FloodlightModuleContext context)
 	    throws FloodlightModuleException {
 	floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
+	registryService = context.getServiceImpl(IControllerRegistryService.class);
 	pusher.init(null, context, floodlightProvider.getOFMessageFactory(), null);
 	if (enableFlowSync) {
-	synchronizer.init(context);
+	    synchronizer.init(pusher);
 	}
     }
 
     @Override
     public void startUp(FloodlightModuleContext context) {
 	pusher.start();
-	if (enableFlowSync) {
-	synchronizer.startUp(context);
-	}
+	floodlightProvider.addOFMessageListener(OFType.FLOW_REMOVED, this);
+	floodlightProvider.addOFSwitchListener(this);
     }
 
     @Override
@@ -58,7 +68,7 @@
 		new ArrayList<Class<? extends IFloodlightService>>();
 	l.add(IFlowPusherService.class);
 	if (enableFlowSync) {
-	l.add(IFlowSyncService.class);
+	    l.add(IFlowSyncService.class);
 	}
 	return l;
     }
@@ -71,7 +81,7 @@
 	    IFloodlightService>();
 	m.put(IFlowPusherService.class, pusher);
 	if (enableFlowSync) {
-	m.put(IFlowSyncService.class, synchronizer);
+	    m.put(IFlowSyncService.class, synchronizer);
 	}
 	return m;
     }
@@ -83,5 +93,60 @@
 	l.add(IFloodlightProviderService.class);
 	return l;
     }
+
+    @Override
+    public String getName() {
+	// TODO Auto-generated method stub
+	return "FlowProgrammer";
+    }
+
+    @Override
+    public boolean isCallbackOrderingPrereq(OFType type, String name) {
+	// TODO Auto-generated method stub
+	return false;
+    }
+
+    @Override
+    public boolean isCallbackOrderingPostreq(OFType type, String name) {
+	// TODO Auto-generated method stub
+	return false;
+    }
+
+    @Override
+    public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
+	switch (msg.getType()) {
+	case FLOW_REMOVED:
+	    OFFlowRemoved flowMsg = (OFFlowRemoved) msg;
+	    log.debug("Got flow removed from "+ sw.getId() +": "+ flowMsg.getCookie());
+	    break;
+	default:
+	    break;
+	}
+
+	return Command.CONTINUE;
+    }
+
+    @Override
+    public void addedSwitch(IOFSwitch sw) {
+	log.debug("Switch added: {}", sw.getId());
+
+	if (enableFlowSync && registryService.hasControl(sw.getId())) {
+	    synchronizer.synchronize(sw);
+	}
+    }
+
+    @Override
+    public void removedSwitch(IOFSwitch sw) {
+	log.debug("Switch removed: {}", sw.getId());
+	
+	if (enableFlowSync) {
+	    synchronizer.interrupt(sw);
+	}
+    }
+
+    @Override
+    public void switchPortChanged(Long switchId) {
+	// TODO Auto-generated method stub
+    }
     
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
index f3f5c50..dcc9022 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/FlowSynchronizer.java
@@ -21,80 +21,44 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.IOFSwitchListener;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
 import net.onrc.onos.graph.GraphDBOperation;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
 import net.onrc.onos.ofcontroller.util.Dpid;
 import net.onrc.onos.ofcontroller.util.FlowEntryId;
-import net.onrc.onos.registry.controller.IControllerRegistryService;
 
-public class FlowSynchronizer implements IFlowSyncService, IOFSwitchListener {
+public class FlowSynchronizer implements IFlowSyncService {
 
-    protected static Logger log = LoggerFactory.getLogger(FlowSynchronizer.class);
-    protected IFloodlightProviderService floodlightProvider;
-    protected IControllerRegistryService registryService;
-    protected IFlowPusherService pusher;
+    private static Logger log = LoggerFactory.getLogger(FlowSynchronizer.class);
 
     private GraphDBOperation dbHandler;
-    private Map<IOFSwitch, Thread> switchThread = new HashMap<IOFSwitch, Thread>();
+    protected IFlowPusherService pusher;
+    private Map<IOFSwitch, Thread> switchThreads; 
 
     public FlowSynchronizer() {
 	dbHandler = new GraphDBOperation("");
+	switchThreads = new HashMap<IOFSwitch, Thread>();
     }
 
+    @Override
     public void synchronize(IOFSwitch sw) {
 	Synchroizer sync = new Synchroizer(sw);
 	Thread t = new Thread(sync);
-	switchThread.put(sw, t);
+	switchThreads.put(sw, t);
 	t.start();
     }
-
+    
     @Override
-    public void addedSwitch(IOFSwitch sw) {
-	log.debug("Switch added: {}", sw.getId());
-
-	if (registryService.hasControl(sw.getId())) {
-	    synchronize(sw);
-	}
-    }
-
-    @Override
-    public void removedSwitch(IOFSwitch sw) {
-	log.debug("Switch removed: {}", sw.getId());
-
-	Thread t = switchThread.remove(sw);
+    public void interrupt(IOFSwitch sw) {
+	Thread t = switchThreads.remove(sw);
 	if(t != null) {
 	    t.interrupt();
-	}
-
+	}	
     }
 
-    @Override
-    public void switchPortChanged(Long switchId) {
-	// TODO Auto-generated method stub
-    }
-
-    @Override
-    public String getName() {
-	return "FlowSynchronizer";
-    }
-
-    //@Override
-    public void init(FloodlightModuleContext context)
-	    throws FloodlightModuleException {
-	floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
-	registryService = context.getServiceImpl(IControllerRegistryService.class);
-	pusher = context.getServiceImpl(IFlowPusherService.class);
-    }
-
-    //@Override
-    public void startUp(FloodlightModuleContext context) {
-	floodlightProvider.addOFSwitchListener(this);
+    public void init(IFlowPusherService pusherService) {
+	pusher = pusherService;
     }
 
     protected class Synchroizer implements Runnable {
@@ -109,9 +73,12 @@
 
 	@Override
 	public void run() {
+	    // TODO: stop adding other flow entries while synchronizing
+	    //pusher.suspend(sw);
 	    Set<FlowEntryWrapper> graphEntries = getFlowEntriesFromGraph();
 	    Set<FlowEntryWrapper> switchEntries = getFlowEntriesFromSwitch();
 	    compare(graphEntries, switchEntries);
+	    //pusher.resume(sw);
 	}
 
 	private void compare(Set<FlowEntryWrapper> graphEntries, Set<FlowEntryWrapper> switchEntries) {
@@ -265,6 +232,8 @@
 	    return id.toString();
 	}
     }
+
+
 }
 
 
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/IFlowSyncService.java b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/IFlowSyncService.java
index 1e71f6a..2b9d51d 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/IFlowSyncService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowprogrammer/IFlowSyncService.java
@@ -10,4 +10,6 @@
  */
 public interface IFlowSyncService extends IFloodlightService {
     public void synchronize(IOFSwitch sw);
+    
+    public void interrupt(IOFSwitch sw);
 }