Add package scope methods to update the network map.
To be used by TopologyEventHandler?(a.k.a TopologyManager)

Change-Id: Iaade917cddf3c2ce03d84ac6ca878d77459c424d
diff --git a/src/main/java/net/onrc/onos/ofcontroller/networkgraph/AbstractNetworkGraph.java b/src/main/java/net/onrc/onos/ofcontroller/networkgraph/AbstractNetworkGraph.java
new file mode 100644
index 0000000..3fa4ad9
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/networkgraph/AbstractNetworkGraph.java
@@ -0,0 +1,96 @@
+package net.onrc.onos.ofcontroller.networkgraph;
+
+import java.net.InetAddress;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import net.floodlightcontroller.util.MACAddress;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AbstractNetworkGraph implements NetworkGraph {
+    @SuppressWarnings("unused")
+    private static final Logger log = LoggerFactory
+	    .getLogger(AbstractNetworkGraph.class);
+
+    // DPID -> Switch
+    protected ConcurrentMap<Long, Switch> switches;
+
+    protected ConcurrentMap<InetAddress, Set<Device>> addr2Device;
+    protected ConcurrentMap<MACAddress, Set<Device>> mac2Device;
+
+    public AbstractNetworkGraph() {
+	// TODO: Does these object need to be stored in Concurrent Collection?
+	switches = new ConcurrentHashMap<>();
+	addr2Device = new ConcurrentHashMap<>();
+	mac2Device = new ConcurrentHashMap<>();
+    }
+
+    @Override
+    public Switch getSwitch(long dpid) {
+	// TODO Check if it is safe to directly return this Object.
+	return switches.get(dpid);
+    }
+
+    @Override
+    public Iterable<Switch> getSwitches() {
+	// TODO Check if it is safe to directly return this Object.
+	return Collections.unmodifiableCollection(switches.values());
+    }
+
+    @Override
+    public Iterable<Link> getLinks() {
+	List<Link> linklist = new LinkedList<>();
+
+	for (Switch sw : switches.values()) {
+	    Iterable<Link> links = sw.getLinks();
+	    for (Link l : links) {
+		linklist.add(l);
+	    }
+	}
+	return linklist;
+    }
+
+    @Override
+    public Iterable<Link> getLinksFromSwitch(long dpid) {
+	Switch sw = getSwitch(dpid);
+	if (sw == null) {
+	    return Collections.emptyList();
+	}
+	Iterable<Link> links = sw.getLinks();
+	if (links instanceof Collection) {
+	    return Collections.unmodifiableCollection((Collection<Link>) links);
+	} else {
+	    List<Link> linklist = new LinkedList<>();
+	    for (Link l : links) {
+		linklist.add(l);
+	    }
+	    return linklist;
+	}
+    }
+
+    @Override
+    public Iterable<Device> getDeviceByIp(InetAddress ipAddress) {
+	Set<Device> devices = addr2Device.get(ipAddress);
+	if (devices == null) {
+	    return Collections.emptyList();
+	}
+	return Collections.unmodifiableCollection(devices);
+    }
+
+    @Override
+    public Iterable<Device> getDeviceByMac(MACAddress address) {
+	Set<Device> devices = mac2Device.get(address);
+	if (devices == null) {
+	    return Collections.emptyList();
+	}
+	return Collections.unmodifiableCollection(devices);
+    }
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/networkgraph/NetworkGraphImpl.java b/src/main/java/net/onrc/onos/ofcontroller/networkgraph/NetworkGraphImpl.java
index 0530147..29cc1d7 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/networkgraph/NetworkGraphImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/networkgraph/NetworkGraphImpl.java
@@ -1,8 +1,5 @@
 package net.onrc.onos.ofcontroller.networkgraph;
 
-import java.net.InetAddress;
-
-import net.floodlightcontroller.util.MACAddress;
 import net.onrc.onos.datastore.topology.RCPort;
 import net.onrc.onos.datastore.topology.RCSwitch;
 
@@ -14,78 +11,136 @@
 /**
  * The "NB" read-only Network Map.
  *
- * TODO Current implementation directly read from DB, but
- * eventually, it should read from In-memory shared Network Map instance within ONOS process.
+ * TODO Current implementation directly read from DB, but eventually, it should
+ * read from In-memory shared Network Map instance within ONOS process.
  *
  */
-public class NetworkGraphImpl implements NetworkGraph {
+public class NetworkGraphImpl extends AbstractNetworkGraph {
 
-	private static final Logger log = LoggerFactory.getLogger(NetworkGraphImpl.class);
+    private static final Logger log = LoggerFactory
+	    .getLogger(NetworkGraphImpl.class);
 
-	@Override
-	public Switch getSwitch(long dpid) {
-		SwitchImpl sw = new SwitchImpl(this);
+    public NetworkGraphImpl() {
+	super();
+    }
 
-		RCSwitch rcSwitch = new RCSwitch(dpid);
-		try {
-			rcSwitch.read();
-		} catch (ObjectDoesntExistException e) {
-			log.warn("Tried to get a switch that doesn't exist {}", dpid);
-			return null;
-		}
+    void addSwitch(Switch sw) {
+	if ( sw == null ) {
+	    throw new IllegalArgumentException("Switch cannot be null");
+	}
+	switches.put(sw.getDpid(), sw);
 
-		sw.setDpid(rcSwitch.getDpid());
+    }
 
-		for (byte[] portId : rcSwitch.getAllPortIds()) {
-			RCPort rcPort = RCPort.createFromKey(portId);
-			try {
-				rcPort.read();
+    /**
+     * Deactivate Switch (and its Ports)
+     * @param sw
+     */
+    void deactivateSwitch(Switch sw) {
+	if ( sw == null ) {
+	    throw new IllegalArgumentException("Switch cannot be null");
+	}
+	SwitchImpl s = getSwitchImpl(sw);
+	// TODO Deactivate Switch
 
-				PortImpl port = new PortImpl(this);
-				//port.setDpid(dpid);
+	// XXX Are we sure we want to deactivate Ports also?
 
-				// TODO why are port numbers long?
-				//port.setPortNumber((short)rcPort.getNumber());
+	// TODO Auto-generated method stub
 
-				port.setSwitch(sw);
-				sw.addPort(port);
+    }
 
-			} catch (ObjectDoesntExistException e) {
-				log.warn("Tried to read port that doesn't exist", rcPort);
-			}
-		}
+    void addPort(Port port) {
+	if ( port == null ) {
+	    throw new IllegalArgumentException("Port cannot be null");
+	}
+	// TODO Auto-generated method stub
 
-		return sw;
+    }
+
+    void deactivatePort(Port port) {
+	if ( port == null ) {
+	    throw new IllegalArgumentException("Port cannot be null");
+	}
+	// TODO Auto-generated method stub
+
+    }
+
+    void addLink(Link link) {
+	if ( link == null ) {
+	    throw new IllegalArgumentException("Link cannot be null");
+	}
+	// TODO Auto-generated method stub
+
+    }
+
+    void removeLink(Link link) {
+	if ( link == null ) {
+	    throw new IllegalArgumentException("Link cannot be null");
+	}
+	// TODO Auto-generated method stub
+
+    }
+
+    void updateDevice(Device device) {
+	if ( device == null ) {
+	    throw new IllegalArgumentException("Device cannot be null");
+	}
+	// TODO Auto-generated method stub
+
+    }
+
+    void removeDevice(Device device) {
+	if ( device == null ) {
+	    throw new IllegalArgumentException("Device cannot be null");
+	}
+	// TODO Auto-generated method stub
+
+    }
+
+    private SwitchImpl getSwitchImpl(Switch sw) {
+	if( sw instanceof SwitchImpl ) {
+	    return (SwitchImpl) sw;
+	}
+	throw new ClassCastException("SwitchImpl expected, but found:" + sw.getClass().getName()  );
+    }
+
+    // FIXME To be removed later this class should never read from DB.
+    public void readSwitchFromTopology(long dpid) {
+	SwitchImpl sw = new SwitchImpl(this);
+
+	RCSwitch rcSwitch = new RCSwitch(dpid);
+	try {
+	    rcSwitch.read();
+	} catch (ObjectDoesntExistException e) {
+	    log.warn("Tried to get a switch that doesn't exist {}", dpid);
+	    return;
 	}
 
-	@Override
-	public Iterable<Switch> getSwitches() {
-		// TODO Auto-generated method stub
-		return null;
+	sw.setDpid(rcSwitch.getDpid());
+
+	addSwitch(sw);
+
+	for (byte[] portId : rcSwitch.getAllPortIds()) {
+	    RCPort rcPort = RCPort.createFromKey(portId);
+	    try {
+		rcPort.read();
+
+		PortImpl port = new PortImpl(this);
+		// port.setDpid(dpid);
+
+		// TODO why are port numbers long?
+		// port.setPortNumber((short)rcPort.getNumber());
+
+		port.setSwitch(sw);
+		sw.addPort(port);
+
+		addPort(port);
+
+	    } catch (ObjectDoesntExistException e) {
+		log.warn("Tried to read port that doesn't exist", rcPort);
+	    }
 	}
 
-	@Override
-	public Iterable<Link> getLinks() {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	@Override
-	public Iterable<Link> getLinksFromSwitch(long dpid) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	@Override
-	public Iterable<Device> getDeviceByIp(InetAddress ipAddress) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	@Override
-	public Iterable<Device> getDeviceByMac(MACAddress address) {
-		// TODO Auto-generated method stub
-		return null;
-	}
+    }
 
 }