Changes to Device and Switch storage to improve accuracy of device data. For now we will clear the devices when we add or remove ports.
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
index cfc411c..e9e2bd1 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
@@ -1,5 +1,6 @@
 package net.onrc.onos.ofcontroller.core.internal;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
@@ -16,6 +17,7 @@
 import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.Lists;
+import com.google.common.net.InetAddresses;
 import com.thinkaurelius.titan.core.TitanException;
 
 /**
@@ -23,7 +25,7 @@
  * @author Pankaj
  */
 public class DeviceStorageImpl implements IDeviceStorage {
-	protected final static Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
+	protected final static Logger log = LoggerFactory.getLogger(DeviceStorageImpl.class);
 	
 	private GraphDBOperation ope;
 
@@ -110,19 +112,26 @@
 	@Override
 	public void removeDevice(IDevice device) {
 		IDeviceObject dev;
+		
+		if ((dev = ope.searchDevice(device.getMACAddressString())) != null) {
+			removeDevice(dev);
+		}
+	}
+	
+	public void removeDevice(IDeviceObject deviceObject) {
+		String deviceMac = deviceObject.getMACAddress();
+
+		for (IIpv4Address ipv4AddressVertex : deviceObject.getIpv4Addresses()) {
+			ope.removeIpv4Address(ipv4AddressVertex);
+		}
+
 		try {
-			if ((dev = ope.searchDevice(device.getMACAddressString())) != null) {
-				for (IIpv4Address ipv4AddressVertex : dev.getIpv4Addresses()) {
-					ope.removeIpv4Address(ipv4AddressVertex);
-				}
-				
-             	ope.removeDevice(dev);
-             	ope.commit();
-            	log.error("DeviceStorage:removeDevice mac:{} done", device.getMACAddressString());
-            }
+			ope.removeDevice(deviceObject);
+			ope.commit();
+			log.error("DeviceStorage:removeDevice mac:{} done", deviceMac);
 		} catch (TitanException e) {
 			ope.rollback();
-			log.error("DeviceStorage:removeDevice mac:{} failed", device.getMACAddressString());
+			log.error("DeviceStorage:removeDevice mac:{} failed", deviceMac);
 		}
 	}
 
@@ -212,6 +221,14 @@
 		for (IPortObject port: attachedPorts) {
 			log.debug("Detaching the device {}: detaching from port", device.getMACAddressString());
 			port.removeDevice(obj);
+			
+			if (!obj.getAttachedPorts().iterator().hasNext()) {
+				// XXX If there are no more ports attached to the device,
+				// delete it. Otherwise we have a situation where the
+				// device remains forever with an IP address attached.
+				// When we implement device probing we should get rid of this.
+				removeDevice(obj);
+			}
 		}
 	}
 
@@ -239,9 +256,30 @@
 	}
 	
 	private void changeDeviceIpv4Addresses(IDevice device, IDeviceObject deviceObject) {
+		List<String> dbIpv4Addresses = new ArrayList<String>();
+		for (IIpv4Address ipv4Vertex : deviceObject.getIpv4Addresses()) {
+			dbIpv4Addresses.add(InetAddresses.fromInteger(ipv4Vertex.getIpv4Address()).getHostAddress());
+		}
+		
+		List<String> memIpv4Addresses = new ArrayList<String>();
+		for (int addr : device.getIPv4Addresses()) {
+			memIpv4Addresses.add(InetAddresses.fromInteger(addr).getHostAddress());
+		}
+		
+		log.debug("Device IP addresses {}, database IP addresses {}",
+				memIpv4Addresses, dbIpv4Addresses);
+		
 		for (int ipv4Address : device.getIPv4Addresses()) {
 			if (deviceObject.getIpv4Address(ipv4Address) == null) {
 				IIpv4Address dbIpv4Address = ope.ensureIpv4Address(ipv4Address);
+				
+				IDeviceObject oldDevice = dbIpv4Address.getDevice();
+				if (oldDevice != null) {
+					oldDevice.removeIpv4Address(dbIpv4Address);
+				}
+				
+				log.debug("Adding IP address {}", 
+						InetAddresses.fromInteger(ipv4Address).getHostAddress());
 				deviceObject.addIpv4Address(dbIpv4Address);
 			}
 		}
@@ -249,6 +287,9 @@
 		List<Integer> deviceIpv4Addresses = Arrays.asList(device.getIPv4Addresses());
 		for (IIpv4Address dbIpv4Address : deviceObject.getIpv4Addresses()) {
 			if (!deviceIpv4Addresses.contains(dbIpv4Address.getIpv4Address())) {
+				log.debug("Removing IP address {}",
+						InetAddresses.fromInteger(dbIpv4Address.getIpv4Address())
+						.getHostAddress());
 				deviceObject.removeIpv4Address(dbIpv4Address);
 			}
 		}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
index 6377605..59f59b7 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
@@ -6,9 +6,10 @@
 import net.floodlightcontroller.core.IOFSwitch;
 import net.onrc.onos.graph.GraphDBConnection;
 import net.onrc.onos.graph.GraphDBOperation;
-import net.onrc.onos.ofcontroller.core.ISwitchStorage;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.ISwitchStorage;
 
 import org.openflow.protocol.OFPhysicalPort;
 import org.openflow.protocol.OFPhysicalPort.OFPortConfig;
@@ -146,7 +147,8 @@
 			}
 	
 			for (OFPhysicalPort port: sw.getPorts()) {
-				IPortObject p = op.searchPort(dpid, port.getPortNumber());
+				addPort(dpid, port);
+				/*IPortObject p = op.searchPort(dpid, port.getPortNumber());
 				if (p != null) {
 		    		log.debug("SwitchStorage:addPort dpid:{} port:{} exists", dpid, port.getPortNumber());
 		    		setPortStateImpl(p, port.getState(), port.getName());
@@ -158,7 +160,7 @@
 				} else {
 					p = addPortImpl(curr, port.getPortNumber());
 					setPortStateImpl(p, port.getState(), port.getName());
-				}         		
+				} */        		
 			}
 			op.commit();
 			success = true;
@@ -290,6 +292,9 @@
 	public boolean addPort(String dpid, OFPhysicalPort phport) {
 		boolean success = false;
 		
+		DeviceStorageImpl deviceStorage = new DeviceStorageImpl();
+		deviceStorage.init("");
+		
 		if(((OFPortConfig.OFPPC_PORT_DOWN.getValue() & phport.getConfig()) > 0) ||
 				((OFPortState.OFPPS_LINK_DOWN.getValue() & phport.getState()) > 0)) {
 			// just dispatch to deletePort()
@@ -306,6 +311,18 @@
 	        	log.info("SwitchStorage:addPort dpid:{} port:{}", dpid, phport.getPortNumber());
 	        	if (p != null) {
 	        		setPortStateImpl(p, phport.getState(), phport.getName());
+	        		
+	        		if (sw.getPort(phport.getPortNumber()) == null) {
+		    			// The port exists but the switch has no "on" link to it
+		    			sw.addPort(p);
+		    		}
+	        		
+	        		// XXX for now delete devices when we change a port to prevent
+	        		// having stale devices.
+	        		for (IDeviceObject deviceObject : p.getDevices()) {
+	        			deviceStorage.removeDevice(deviceObject);
+	        		}
+	        		
 	        		log.error("SwitchStorage:addPort dpid:{} port:{} exists setting as ACTIVE", dpid, phport.getPortNumber());
 	        	} else {
 	        		addPortImpl(sw, phport.getPortNumber());
@@ -334,6 +351,9 @@
 	public boolean deletePort(String dpid, short port) {
 		boolean success = false;
 		
+		DeviceStorageImpl deviceStorage = new DeviceStorageImpl();
+		deviceStorage.init("");
+		
 		try {
 			ISwitchObject sw = op.searchSwitch(dpid);
 	
@@ -343,10 +363,17 @@
 	        		log.info("SwitchStorage:deletePort dpid:{} port:{} found and set INACTIVE", dpid, port);
 	        		//deletePortImpl(p);
 	        		p.setState("INACTIVE");
+	        		
+	        		// XXX for now delete devices when we change a port to prevent
+	        		// having stale devices.
+	        		for (IDeviceObject d : p.getDevices()) {
+	        			deviceStorage.removeDevice(d);
+	        		}
 	        		op.commit();
 	        	}
 	        }
-		success = true;
+	        
+	        success = true;
 		} catch (Exception e) {
 			op.rollback();
 			e.printStackTrace();