CORD-613 Adding ability to administratively enable or disable a port via CLI.
Currently uses the OpenFlow device provider to change portState.
Also fixes a bug in PortNumberCompleter.
Adds completion options to portstats for deviceId and portNumber.

Change-Id: Idcce775fe8bc5484fdd0e630bcb5026b85125478
diff --git a/core/api/src/main/java/org/onosproject/net/device/DeviceAdminService.java b/core/api/src/main/java/org/onosproject/net/device/DeviceAdminService.java
index 500b635..a750e06 100644
--- a/core/api/src/main/java/org/onosproject/net/device/DeviceAdminService.java
+++ b/core/api/src/main/java/org/onosproject/net/device/DeviceAdminService.java
@@ -16,6 +16,7 @@
 package org.onosproject.net.device;
 
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
 
 /**
  * Service for administering the inventory of infrastructure devices.
@@ -31,4 +32,13 @@
 
     // TODO: add ability to administratively suspend/resume device
 
+
+  /**
+   * Administratively enables or disables a port on a device.
+   *
+   * @param deviceId  device identifier
+   * @param portNumber port identifier
+   * @param enable true if port is to be enabled, false to disable
+   */
+    void changePortState(DeviceId deviceId, PortNumber portNumber, boolean enable);
 }
diff --git a/core/api/src/main/java/org/onosproject/net/device/DeviceProvider.java b/core/api/src/main/java/org/onosproject/net/device/DeviceProvider.java
index d8adbb0..1727fc8 100644
--- a/core/api/src/main/java/org/onosproject/net/device/DeviceProvider.java
+++ b/core/api/src/main/java/org/onosproject/net/device/DeviceProvider.java
@@ -17,6 +17,7 @@
 
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.MastershipRole;
+import org.onosproject.net.PortNumber;
 import org.onosproject.net.provider.Provider;
 
 /**
@@ -54,4 +55,14 @@
      * @return true if reachable, false otherwise
      */
     boolean isReachable(DeviceId deviceId);
+
+    /**
+     * Administratively enables or disables a port.
+     *
+     * @param deviceId device identifier
+     * @param portNumber device identifier
+     * @param enable true if port is to be enabled, false to disable
+     */
+    void changePortState(DeviceId deviceId, PortNumber portNumber,
+                         boolean enable);
 }
diff --git a/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java b/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java
index 5ef70fc..f089203 100644
--- a/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java
+++ b/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java
@@ -248,6 +248,22 @@
     }
 
     @Override
+    public void changePortState(DeviceId deviceId, PortNumber portNumber,
+                                boolean enable) {
+        checkNotNull(deviceId, DEVICE_ID_NULL);
+        checkNotNull(deviceId, PORT_NUMBER_NULL);
+        DeviceProvider provider = getProvider(deviceId);
+        if (provider != null) {
+            log.warn("Port {} on device {} being administratively brought {}",
+                     portNumber, deviceId,
+                     (enable) ? "UP" : "DOWN");
+            provider.changePortState(deviceId, portNumber, enable);
+        } else {
+            log.warn("Provider not found for {}", deviceId);
+        }
+    }
+
+    @Override
     protected DeviceProviderService createProviderService(
             DeviceProvider provider) {
         return new InternalDeviceProviderService(provider);
@@ -340,6 +356,7 @@
                 log.trace("event: {} {}", event.type(), event);
                 post(event);
             }
+
         }
 
         @Override
@@ -790,4 +807,5 @@
             }
         }
     }
+
 }
diff --git a/core/net/src/test/java/org/onosproject/net/device/impl/DeviceManagerTest.java b/core/net/src/test/java/org/onosproject/net/device/impl/DeviceManagerTest.java
index 04f266f..7017481 100644
--- a/core/net/src/test/java/org/onosproject/net/device/impl/DeviceManagerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/device/impl/DeviceManagerTest.java
@@ -274,6 +274,11 @@
         public boolean isReachable(DeviceId device) {
             return false;
         }
+
+        @Override
+        public void changePortState(DeviceId deviceId, PortNumber portNumber,
+                                    boolean enable) {
+        }
     }
 
     private static class TestListener implements DeviceListener {