Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next
diff --git a/net/api/src/main/java/org/onlab/onos/net/device/DeviceService.java b/net/api/src/main/java/org/onlab/onos/net/device/DeviceService.java
index 42b9a31..6c46627 100644
--- a/net/api/src/main/java/org/onlab/onos/net/device/DeviceService.java
+++ b/net/api/src/main/java/org/onlab/onos/net/device/DeviceService.java
@@ -14,12 +14,11 @@
 public interface DeviceService {
 
     /**
-     * Returns the current mastership role for the specified device.
+     * Returns the number of infrastructure devices known to the system.
      *
-     * @param deviceId device identifier
-     * @return designated mastership role
+     * @return number of infrastructure devices
      */
-    MastershipRole getRole(DeviceId deviceId);
+    int getDeviceCount();
 
     /**
      * Returns a collection of the currently known infrastructure
@@ -37,6 +36,14 @@
      */
     Device getDevice(DeviceId deviceId);
 
+    /**
+     * Returns the current mastership role for the specified device.
+     *
+     * @param deviceId device identifier
+     * @return designated mastership role
+     */
+    MastershipRole getRole(DeviceId deviceId);
+
 
     /**
      * Returns the list of ports associated with the device.
diff --git a/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceManager.java b/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceManager.java
index 9cfc784..b8f5788 100644
--- a/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceManager.java
+++ b/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceManager.java
@@ -69,9 +69,8 @@
     }
 
     @Override
-    public MastershipRole getRole(DeviceId deviceId) {
-        checkNotNull(deviceId, DEVICE_ID_NULL);
-        return store.getRole(deviceId);
+    public int getDeviceCount() {
+        return store.getDeviceCount();
     }
 
     @Override
@@ -86,6 +85,12 @@
     }
 
     @Override
+    public MastershipRole getRole(DeviceId deviceId) {
+        checkNotNull(deviceId, DEVICE_ID_NULL);
+        return store.getRole(deviceId);
+    }
+
+    @Override
     public List<Port> getPorts(DeviceId deviceId) {
         checkNotNull(deviceId, DEVICE_ID_NULL);
         return store.getPorts(deviceId);
@@ -147,7 +152,7 @@
         public void deviceConnected(DeviceId deviceId, DeviceDescription deviceDescription) {
             checkNotNull(deviceId, DEVICE_ID_NULL);
             checkNotNull(deviceDescription, DEVICE_DESCRIPTION_NULL);
-            log.info("Device {} connected: {}", deviceId, deviceDescription);
+            log.info("Device {} connected", deviceId);
             DeviceEvent event = store.createOrUpdateDevice(provider().id(),
                                                            deviceId, deviceDescription);
             post(event);
@@ -165,7 +170,7 @@
         public void updatePorts(DeviceId deviceId, List<PortDescription> portDescriptions) {
             checkNotNull(deviceId, DEVICE_ID_NULL);
             checkNotNull(portDescriptions, "Port descriptions list cannot be null");
-            log.info("Device {} ports updated: {}", portDescriptions);
+            log.info("Device {} ports updated", deviceId);
             List<DeviceEvent> events = store.updatePorts(deviceId, portDescriptions);
             for (DeviceEvent event : events) {
                 post(event);
@@ -176,7 +181,7 @@
         public void portStatusChanged(DeviceId deviceId, PortDescription portDescription) {
             checkNotNull(deviceId, DEVICE_ID_NULL);
             checkNotNull(portDescription, PORT_DESCRIPTION_NULL);
-            log.info("Device {} port status changed: {}", deviceId, portDescription);
+            log.info("Device {} port status changed", deviceId);
             DeviceEvent event = store.updatePortStatus(deviceId, portDescription);
             post(event);
         }
diff --git a/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceStore.java b/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceStore.java
index dbff8d1..dd63469 100644
--- a/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceStore.java
+++ b/net/core/trivial/src/main/java/org/onlab/onos/net/trivial/impl/SimpleDeviceStore.java
@@ -28,7 +28,8 @@
 import static org.onlab.onos.net.device.DeviceEvent.Type.*;
 
 /**
- * Manages inventory of infrastructure devices.
+ * Manages inventory of infrastructure devices using trivial in-memory
+ * implementation.
  */
 class SimpleDeviceStore {
 
@@ -40,6 +41,15 @@
     private final Map<DeviceId, Map<PortNumber, Port>> devicePorts = new HashMap<>();
 
     /**
+     * Returns the number of devices known to the system.
+     *
+     * @return number of devices
+     */
+    public int getDeviceCount() {
+        return devices.size();
+    }
+
+    /**
      * Returns an iterable collection of all devices known to the system.
      *
      * @return device collection
@@ -153,9 +163,9 @@
             Set<PortNumber> processed = new HashSet<>();
             for (PortDescription portDescription : portDescriptions) {
                 Port port = ports.get(portDescription.portNumber());
-                DeviceEvent event = port == null ?
-                        createPort(device, portDescription, ports) :
-                        updatePort(device, port, portDescription, ports);
+                events.add(port == null ?
+                                   createPort(device, portDescription, ports) :
+                                   updatePort(device, port, portDescription, ports));
                 processed.add(portDescription.portNumber());
             }
 
@@ -198,7 +208,7 @@
         Iterator<PortNumber> iterator = ports.keySet().iterator();
         while (iterator.hasNext()) {
             PortNumber portNumber = iterator.next();
-            if (processed.contains(portNumber)) {
+            if (!processed.contains(portNumber)) {
                 events.add(new DeviceEvent(PORT_REMOVED, device,
                                            ports.get(portNumber)));
                 iterator.remove();
@@ -301,5 +311,4 @@
                     new DeviceEvent(DEVICE_REMOVED, device, null);
         }
     }
-
 }
diff --git a/net/core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleDeviceManagerTest.java b/net/core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleDeviceManagerTest.java
index d3458a5..a6c9414 100644
--- a/net/core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleDeviceManagerTest.java
+++ b/net/core/trivial/src/test/java/org/onlab/onos/net/trivial/impl/SimpleDeviceManagerTest.java
@@ -7,7 +7,10 @@
 import org.onlab.onos.net.Device;
 import org.onlab.onos.net.DeviceId;
 import org.onlab.onos.net.MastershipRole;
+import org.onlab.onos.net.Port;
+import org.onlab.onos.net.PortNumber;
 import org.onlab.onos.net.device.DefaultDeviceDescription;
+import org.onlab.onos.net.device.DefaultPortDescription;
 import org.onlab.onos.net.device.DeviceAdminService;
 import org.onlab.onos.net.device.DeviceDescription;
 import org.onlab.onos.net.device.DeviceEvent;
@@ -16,6 +19,7 @@
 import org.onlab.onos.net.device.DeviceProviderRegistry;
 import org.onlab.onos.net.device.DeviceProviderService;
 import org.onlab.onos.net.device.DeviceService;
+import org.onlab.onos.net.device.PortDescription;
 import org.onlab.onos.net.provider.AbstractProvider;
 import org.onlab.onos.net.provider.ProviderId;
 
@@ -42,6 +46,10 @@
     private static final String SW2 = "3.9.5";
     private static final String SN = "43311-12345";
 
+    private static final PortNumber P1 = PortNumber.portNumber(1);
+    private static final PortNumber P2 = PortNumber.portNumber(2);
+    private static final PortNumber P3 = PortNumber.portNumber(3);
+
 
     private SimpleDeviceManager mgr;
 
@@ -95,6 +103,7 @@
         Iterator<Device> it = service.getDevices().iterator();
         assertNotNull("one device expected", it.next());
         assertFalse("only one device expected", it.hasNext());
+        assertEquals("incorrect device count", 1, service.getDeviceCount());
     }
 
     @Test
@@ -111,6 +120,8 @@
         // Reconnect
         connectDevice(DID1, SW1);
         validateEvents(DEVICE_AVAILABILITY_CHANGED);
+
+        assertEquals("incorrect device count", 2, service.getDeviceCount());
     }
 
     @Test
@@ -138,7 +149,64 @@
         assertEquals("incorrect role", MastershipRole.MASTER, provider.roleReceived);
     }
 
+    @Test
+    public void updatePorts() {
+        connectDevice(DID1, SW1);
+        List<PortDescription> pds = new ArrayList<>();
+        pds.add(new DefaultPortDescription(P1, true));
+        pds.add(new DefaultPortDescription(P2, true));
+        pds.add(new DefaultPortDescription(P3, true));
+        providerService.updatePorts(DID1, pds);
+        validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED, PORT_ADDED);
+        pds.clear();
 
+        pds.add(new DefaultPortDescription(P1, false));
+        pds.add(new DefaultPortDescription(P3, true));
+        providerService.updatePorts(DID1, pds);
+        validateEvents(PORT_UPDATED, PORT_REMOVED);
+    }
+
+    @Test
+    public void updatePortStatus() {
+        connectDevice(DID1, SW1);
+        List<PortDescription> pds = new ArrayList<>();
+        pds.add(new DefaultPortDescription(P1, true));
+        pds.add(new DefaultPortDescription(P2, true));
+        providerService.updatePorts(DID1, pds);
+        validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED);
+
+        providerService.portStatusChanged(DID1, new DefaultPortDescription(P1, false));
+        validateEvents(PORT_UPDATED);
+        providerService.portStatusChanged(DID1, new DefaultPortDescription(P1, false));
+        assertTrue("no events expected", listener.events.isEmpty());
+    }
+
+    @Test
+    public void getPorts() {
+        connectDevice(DID1, SW1);
+        List<PortDescription> pds = new ArrayList<>();
+        pds.add(new DefaultPortDescription(P1, true));
+        pds.add(new DefaultPortDescription(P2, true));
+        providerService.updatePorts(DID1, pds);
+        validateEvents(DEVICE_ADDED, PORT_ADDED, PORT_ADDED);
+        assertEquals("wrong port count", 2, service.getPorts(DID1).size());
+
+        Port port = service.getPort(DID1, P1);
+        assertEquals("incorrect port", P1, service.getPort(DID1, P1).number());
+        assertEquals("incorrect state", true, service.getPort(DID1, P1).isEnabled());
+    }
+
+    @Test
+    public void removeDevice() {
+        connectDevice(DID1, SW1);
+        connectDevice(DID2, SW2);
+        assertEquals("incorrect device count", 2, service.getDeviceCount());
+        admin.removeDevice(DID1);
+        assertNull("device should not be found", service.getDevice(DID1));
+        assertNotNull("device should be found", service.getDevice(DID2));
+        assertEquals("incorrect device count", 1, service.getDeviceCount());
+
+    }
 
     protected void validateEvents(Enum... types) {
         int i = 0;