Began integration with ONOS discovery code by implementing add switch and add link

Change-Id: I21426ea7031df20701d186cb2840a380fa334728

Made NetworkGraphModule to provide access to the global NetworkGraph instance

Change-Id: Ie2293b97f9fb6bdeaa5140c244a21c107d5e1ca7
diff --git a/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/INetworkGraphService.java b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/INetworkGraphService.java
deleted file mode 100644
index 121eaf9..0000000
--- a/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/INetworkGraphService.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package net.onrc.onos.ofcontroller.floodlightlistener;
-
-import net.floodlightcontroller.core.module.IFloodlightService;
-
-/**
- * Interface for providing Network Graph Service to other module.
- */
-public interface INetworkGraphService extends IFloodlightService {
-    // TODO
-}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
index fefaadf..bc5962a 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
@@ -58,8 +58,7 @@
 					      IOFSwitchListener,
 					      IOFSwitchPortListener,
 					      ILinkDiscoveryListener,
-					      IFloodlightModule,
-					      INetworkGraphService {
+					      IFloodlightModule {
 
 	protected IDeviceStorage devStore;
 	protected ISwitchStorage swStore;
@@ -427,31 +426,23 @@
 
 	@Override
 	public Collection<Class<? extends IFloodlightService>> getModuleServices() {
-		Collection<Class<? extends IFloodlightService>> l =
-		    new ArrayList<Class<? extends IFloodlightService>>();
-		l.add(INetworkGraphService.class);
-		return l;
+		return null;
 	}
 
 	@Override
 	public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
-		Map<Class<? extends IFloodlightService>,
-		    IFloodlightService> m =
-		    new HashMap<Class<? extends IFloodlightService>,
-		    IFloodlightService>();
-		m.put(INetworkGraphService.class, this);
-		return m;
+		return null;
 	}
 
 	@Override
 	public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
 	    Collection<Class<? extends IFloodlightService>> l =
 	            new ArrayList<Class<? extends IFloodlightService>>();
-	        l.add(IFloodlightProviderService.class);
-	        //l.add(IDeviceService.class);
-	        l.add(IDatagridService.class);
-	        l.add(IThreadPoolService.class);
-	        return l;
+        l.add(IFloodlightProviderService.class);
+        //l.add(IDeviceService.class);
+        l.add(IDatagridService.class);
+        l.add(IThreadPoolService.class);
+        return l;
 	}
 
 	@Override
diff --git a/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/RCNetworkGraphPublisher.java b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/RCNetworkGraphPublisher.java
new file mode 100644
index 0000000..ecf7b0d
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/RCNetworkGraphPublisher.java
@@ -0,0 +1,215 @@
+package net.onrc.onos.ofcontroller.floodlightlistener;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.IOFSwitch;
+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.datagrid.IDatagridService;
+import net.onrc.onos.ofcontroller.core.IOFSwitchPortListener;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryListener;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
+import net.onrc.onos.ofcontroller.networkgraph.FloodlightToOnosMappers;
+import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
+import net.onrc.onos.ofcontroller.networkgraph.LinkImpl;
+import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
+import net.onrc.onos.ofcontroller.networkgraph.SouthboundNetworkGraph;
+import net.onrc.onos.ofcontroller.networkgraph.Switch;
+import net.onrc.onos.registry.controller.IControllerRegistryService;
+
+import org.openflow.protocol.OFPhysicalPort;
+
+/*
+ * I've created a copy of the NetworkGraphPublisher so I can integrate
+ * the new API with ONOS while still having the old NetworkGraphPublisher
+ * to reference. I've renamed to RCNetworkGraphPublisher.
+ * TODO Remove old NetworkGraphPublisher once the integration of the new
+ * API is complete.
+ * For now, we just write to the database and don't worry about sending
+ * notifications. 
+ * TODO Send notification after each database write
+ */
+public class RCNetworkGraphPublisher implements /*IOFSwitchListener,*/
+												IOFSwitchPortListener,
+												ILinkDiscoveryListener,
+												IFloodlightModule {
+
+	private IFloodlightProviderService floodlightProvider;
+	private ILinkDiscoveryService linkDiscovery;
+	private IControllerRegistryService registryService;
+	private IDatagridService datagridService;
+	private INetworkGraphService networkGraphService;
+	
+	private NetworkGraph networkGraph;
+	private SouthboundNetworkGraph southboundNetworkGraph;
+	
+
+	@Override
+	public void linkDiscoveryUpdate(LDUpdate update) {
+		// TODO Auto-generated method stub
+		LinkImpl link = new LinkImpl(networkGraph);
+		link.setSrcSwitch(update.getSrc());
+		link.setSrcPort(update.getSrcPort());
+		link.setDstSwitch(update.getDst());
+		link.setDstPort(update.getDstPort());
+		
+		switch (update.getOperation()) {
+		case LINK_ADDED:
+			southboundNetworkGraph.addLink(link);
+			/*
+			TopologyElement topologyElement =
+					new TopologyElement(update.getSrc(),
+							update.getSrcPort(),
+							update.getDst(),
+							update.getDstPort());
+			datagridService.notificationSendTopologyElementAdded(topologyElement);
+			*/
+			break;
+		case LINK_UPDATED:
+			// I don't know what a LINK_UPDATED event is.
+			// We never use it.
+			break;
+		case LINK_REMOVED:
+			southboundNetworkGraph.removeLink(link);
+			/*
+			TopologyElement topologyElement =
+					new TopologyElement(update.getSrc(),
+							update.getSrcPort(),
+							update.getDst(),
+							update.getDstPort());
+			datagridService.notificationSendTopologyElementRemoved(topologyElement);
+			*/
+			break;
+		default:
+			break;
+		}
+	}
+
+	@Override
+	public void switchPortAdded(Long switchId, OFPhysicalPort port) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void switchPortRemoved(Long switchId, OFPhysicalPort port) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void addedSwitch(IOFSwitch sw) {
+		// TODO Not very robust
+		if (!registryService.hasControl(sw.getId())) {
+			return;
+		}
+		
+		Switch onosSwitch = FloodlightToOnosMappers.map(networkGraph, sw);
+		southboundNetworkGraph.addSwitch(onosSwitch);
+		
+		/*
+		// TODO publish ADD_SWITCH event here
+	    TopologyElement topologyElement =
+		new TopologyElement(sw.getId());
+	    datagridService.notificationSendTopologyElementAdded(topologyElement);
+
+	    // Publish: add the ports
+	    // TODO: Add only ports that are UP?
+	    for (OFPhysicalPort port : sw.getPorts()) {
+			TopologyElement topologyElementPort =
+			    new TopologyElement(sw.getId(), port.getPortNumber());
+			datagridService.notificationSendTopologyElementAdded(topologyElementPort);
+
+			// Allow links to be discovered on this port now that it's
+			// in the database
+			linkDiscovery.RemoveFromSuppressLLDPs(sw.getId(), port.getPortNumber());
+	    }
+
+	    // Add all links that might be connected already
+	    List<Link> links = linkStore.getLinks(HexString.toHexString(sw.getId()));
+	    // Add all reverse links as well
+	    List<Link> reverseLinks = linkStore.getReverseLinks(HexString.toHexString(sw.getId()));
+	    links.addAll(reverseLinks);
+
+	    // Publish: add the links
+	    for (Link link : links) {
+		TopologyElement topologyElementLink =
+		    new TopologyElement(link.getSrc(),
+					link.getSrcPort(),
+					link.getDst(),
+					link.getDstPort());
+		datagridService.notificationSendTopologyElementAdded(topologyElementLink);
+		*/
+	}
+
+	@Override
+	public void removedSwitch(IOFSwitch sw) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void switchPortChanged(Long switchId) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public String getName() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/* *****************
+	 * IFloodlightModule
+	 * *****************/
+	
+	@Override
+	public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+		return null;
+	}
+
+	@Override
+	public Map<Class<? extends IFloodlightService>, IFloodlightService> 
+			getServiceImpls() {
+		return null;
+	}
+
+	@Override
+	public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+		Collection<Class<? extends IFloodlightService>> l =
+	            new ArrayList<Class<? extends IFloodlightService>>();
+        l.add(IFloodlightProviderService.class);
+        l.add(ILinkDiscoveryService.class);
+        l.add(IControllerRegistryService.class);
+        l.add(IDatagridService.class);
+        l.add(INetworkGraphService.class);
+        return l;
+	}
+
+	@Override
+	public void init(FloodlightModuleContext context)
+			throws FloodlightModuleException {
+		floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
+		linkDiscovery = context.getServiceImpl(ILinkDiscoveryService.class);
+		registryService = context.getServiceImpl(IControllerRegistryService.class);
+		datagridService = context.getServiceImpl(IDatagridService.class);
+		
+		networkGraphService = context.getServiceImpl(INetworkGraphService.class);
+	}
+
+	@Override
+	public void startUp(FloodlightModuleContext context) {
+		// TODO enable cleanup thread
+		floodlightProvider.addOFSwitchListener(this);
+		linkDiscovery.addListener(this);
+		
+		networkGraph = networkGraphService.getNetworkGraph();
+		southboundNetworkGraph = networkGraphService.getSouthboundNetworkGraph();
+	}
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
index de847de..715f9df 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
@@ -24,10 +24,10 @@
 import net.onrc.onos.graph.GraphDBManager;
 import net.onrc.onos.datagrid.IDatagridService;
 import net.onrc.onos.ofcontroller.core.INetMapStorage;
-import net.onrc.onos.ofcontroller.floodlightlistener.INetworkGraphService;
 import net.onrc.onos.ofcontroller.flowmanager.web.FlowWebRoutable;
 import net.onrc.onos.ofcontroller.flowprogrammer.IFlowPusherService;
 import net.onrc.onos.ofcontroller.forwarding.IForwardingService;
+import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
 import net.onrc.onos.ofcontroller.topology.Topology;
 import net.onrc.onos.ofcontroller.util.Dpid;
 import net.onrc.onos.ofcontroller.util.FlowEntry;
@@ -41,7 +41,6 @@
 import net.onrc.onos.ofcontroller.util.serializers.KryoFactory;
 
 import com.thinkaurelius.titan.core.TitanException;
-
 import com.esotericsoftware.kryo.Kryo;
 
 import org.slf4j.Logger;
@@ -151,7 +150,6 @@
 	Collection<Class<? extends IFloodlightService>> l =
 	    new ArrayList<Class<? extends IFloodlightService>>();
 	l.add(IFloodlightProviderService.class);
-	l.add(INetworkGraphService.class);
 	l.add(IDatagridService.class);
 	l.add(IRestApiService.class);
 	l.add(IFlowPusherService.class);
diff --git a/src/main/java/net/onrc/onos/ofcontroller/networkgraph/INetworkGraphService.java b/src/main/java/net/onrc/onos/ofcontroller/networkgraph/INetworkGraphService.java
new file mode 100644
index 0000000..71a5d53
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/networkgraph/INetworkGraphService.java
@@ -0,0 +1,23 @@
+package net.onrc.onos.ofcontroller.networkgraph;
+
+import net.floodlightcontroller.core.module.IFloodlightService;
+
+/**
+ * Interface for providing the Network Graph Service to other modules.
+ */
+public interface INetworkGraphService extends IFloodlightService {
+	/**
+	 * Allows a module to get a reference to the global network graph object.
+	 * @return
+	 */
+    public NetworkGraph getNetworkGraph();
+    
+    /**
+     * Allows a module to get a reference to the southbound interface to
+     * the network graph.
+     * TODO Figure out how to hide the southbound interface from 
+     * applications/modules that shouldn't touch it
+     * @return
+     */
+    public SouthboundNetworkGraph getSouthboundNetworkGraph();
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/networkgraph/NetworkGraphModule.java b/src/main/java/net/onrc/onos/ofcontroller/networkgraph/NetworkGraphModule.java
new file mode 100644
index 0000000..490f30f
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/networkgraph/NetworkGraphModule.java
@@ -0,0 +1,68 @@
+package net.onrc.onos.ofcontroller.networkgraph;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.FloodlightModuleException;
+import net.floodlightcontroller.core.module.IFloodlightModule;
+import net.floodlightcontroller.core.module.IFloodlightService;
+
+public class NetworkGraphModule implements IFloodlightModule, INetworkGraphService {
+
+	// This is initialized as a module for now
+	// private RCNetworkGraphPublisher eventListener;
+	
+	private NetworkGraphImpl networkGraph;
+	private SouthboundNetworkGraph southboundNetworkGraph;
+
+
+	@Override
+	public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+		List<Class<? extends IFloodlightService>> services = 
+				new ArrayList<Class<? extends IFloodlightService>>();
+		services.add(INetworkGraphService.class);
+		return services;
+	}
+
+	@Override
+	public Map<Class<? extends IFloodlightService>, IFloodlightService> 
+			getServiceImpls() {
+		Map<Class<? extends IFloodlightService>, IFloodlightService> impls = 
+				new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
+		impls.put(INetworkGraphService.class, this);
+		return impls;
+	}
+
+	@Override
+	public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+		return null;
+	}
+	
+	@Override
+	public void init(FloodlightModuleContext context)
+			throws FloodlightModuleException {
+		networkGraph = new NetworkGraphImpl();
+		southboundNetworkGraph = new SouthboundNetworkGraph(networkGraph);
+	}
+
+	@Override
+	public void startUp(FloodlightModuleContext context) {
+		// TODO Auto-generated method stub
+
+	}
+
+	@Override
+	public NetworkGraph getNetworkGraph() {
+		return networkGraph;
+	}
+
+	@Override
+	public SouthboundNetworkGraph getSouthboundNetworkGraph() {
+		return southboundNetworkGraph;
+	}
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/networkgraph/SouthboundNetworkGraph.java b/src/main/java/net/onrc/onos/ofcontroller/networkgraph/SouthboundNetworkGraph.java
index b1f4213..e9de665 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/networkgraph/SouthboundNetworkGraph.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/networkgraph/SouthboundNetworkGraph.java
@@ -36,10 +36,15 @@
 	private static final Logger log = LoggerFactory.getLogger(SouthboundNetworkGraph.class);
 
 	private static final int NUM_RETRIES = 10;
+	
+	private final NetworkGraphImpl graph;
 
+	public SouthboundNetworkGraph(NetworkGraphImpl graph) {
+		this.graph = graph;
+	}
 
 	public void addSwitch(Switch sw) {
-
+		log.debug("Adding switch {}", sw);
 		ArrayList<WriteOp> groupOp = new ArrayList<>();
 
 		RCSwitch rcSwitch = new RCSwitch(sw.getDpid());
@@ -61,7 +66,7 @@
 		boolean failed = RCObject.multiWrite( groupOp );
 
 		if ( failed ) {
-		    log.error("Adding Switch {} and it's ports failed.", sw.getDpid());
+		    log.error("Adding Switch {} and its ports failed.", sw.getDpid());
 		    for ( WriteOp op : groupOp ) {
 			log.debug("Operation:{} for {} - Result:{}", op.getOp(), op.getObject(), op.getStatus() );
 
@@ -69,10 +74,15 @@
 			// Conditional operation (Create/Update) then we should retry here.
 		    }
 		}
+		else {
+			// Publish event to the in-memory cache
+			graph.addSwitch(sw);
+		}
 
 	}
 
 	public void deactivateSwitch(Switch sw) {
+		log.debug("Deactivating switch {}", sw);
 		RCSwitch rcSwitch = new RCSwitch(sw.getDpid());
 
 		List<RCObject> objectsToDeactive = new ArrayList<RCObject>();
@@ -111,6 +121,7 @@
 	}
 
 	public void addPort(Switch sw, Port port) {
+		log.debug("Adding port {}", port);
 		RCSwitch rcSwitch = new RCSwitch(sw.getDpid());
 
 		try {
@@ -129,6 +140,7 @@
 	}
 
 	public void deactivatePort(Port port) {
+		log.debug("Deactivating port {}", port);
 		RCPort rcPort = new RCPort(port.getSwitch().getDpid(), (long)port.getNumber());
 
 		for (int i = 0; i < NUM_RETRIES; i++) {
@@ -152,6 +164,7 @@
 	}
 
 	public void addLink(Link link) {
+		log.debug("Adding link {}", link);
 		RCLink rcLink = new RCLink(link.getSourceSwitchDpid(), (long)link.getSourcePortNumber(),
 				link.getDestinationSwitchDpid(), (long)link.getDestinationPortNumber());
 
@@ -187,9 +200,13 @@
 				// retry
 			}
 		}
+		
+		// Publish event to in-memory cache
+		graph.addLink(link);
 	}
 
 	public void removeLink(Link link) {
+		log.debug("Removing link {}", link);
 		RCLink rcLink = new RCLink(link.getSourceSwitchDpid(), (long)link.getSourcePortNumber(),
 				link.getDestinationSwitchDpid(), (long)link.getDestinationPortNumber());
 
diff --git a/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java b/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
index f326f4c..bf2fd6f 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
@@ -14,7 +14,7 @@
 import net.onrc.onos.datagrid.IDatagridService;
 import net.onrc.onos.graph.DBOperation;
 import net.onrc.onos.graph.GraphDBManager;
-import net.onrc.onos.ofcontroller.floodlightlistener.INetworkGraphService;
+import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
 import net.onrc.onos.ofcontroller.topology.web.OnosTopologyWebRoutable;
 import net.onrc.onos.ofcontroller.util.DataPath;
 import net.onrc.onos.ofcontroller.util.FlowEntry;
@@ -141,7 +141,6 @@
 	Collection<Class<? extends IFloodlightService>> l =
 	    new ArrayList<Class<? extends IFloodlightService>>();
 	l.add(IFloodlightProviderService.class);
-	l.add(INetworkGraphService.class);
 	l.add(IDatagridService.class);
         return l;
     }
diff --git a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
index dfd31ab..e796810 100644
--- a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
+++ b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
@@ -1,5 +1,5 @@
 net.floodlightcontroller.core.FloodlightProvider
-net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher
+net.onrc.onos.ofcontroller.floodlightlistener.RCNetworkGraphPublisher
 net.onrc.onos.ofcontroller.linkdiscovery.internal.LinkDiscoveryManager
 net.floodlightcontroller.topology.TopologyManager
 net.floodlightcontroller.forwarding.Forwarding
@@ -21,3 +21,4 @@
 net.onrc.onos.ofcontroller.proxyarp.ProxyArpManager
 net.onrc.onos.ofcontroller.core.config.DefaultConfiguration
 net.onrc.onos.ofcontroller.devicemanager.OnosDeviceManager
+net.onrc.onos.ofcontroller.networkgraph.NetworkGraphModule