Fixing device key REST API bugs and adding json definitions.

Change-Id: I41a98702e781544fe6e0bebe3e281ff2bcd9a6fa
diff --git a/web/api/src/main/java/org/onosproject/rest/resources/DeviceKeyWebResource.java b/web/api/src/main/java/org/onosproject/rest/resources/DeviceKeyWebResource.java
index 3e78825..c4020e1 100644
--- a/web/api/src/main/java/org/onosproject/rest/resources/DeviceKeyWebResource.java
+++ b/web/api/src/main/java/org/onosproject/rest/resources/DeviceKeyWebResource.java
@@ -56,9 +56,8 @@
      * Returns array of all device keys.
      *
      * @return 200 OK
+     * @onos.rsModel Devicekeys
      */
-// FIXME DeviceKeysGet.json not found
-//   * @onos.rsModel DeviceKeysGet
     @GET
     public Response getDeviceKeys() {
         Iterable<DeviceKey> deviceKeys = get(DeviceKeyService.class).getDeviceKeys();
@@ -69,11 +68,10 @@
      * Get a single device key by device key unique identifier.
      * Returns the specified device key.
      *
-     * @param id device identifier
-     * @return 200 OK
+     * @param id device key identifier
+     * @return 200 OK, 404 not found
+     * @onos.rsModel Devicekey
      */
-// FIXME DeviceKeyGet.json not found
-//   * @onos.rsModel DeviceKeyGet
     @GET
     @Path("{id}")
     public Response getDeviceKey(@PathParam("id") String id) {
@@ -83,14 +81,13 @@
     }
 
     /**
-     * Adds a new device key from the JSON request.
+     * Adds a new device key from the JSON input stream.
      *
-     * @param stream input JSON
+     * @param stream device key JSON stream
      * @return status of the request - CREATED if the JSON is correct,
      * BAD_REQUEST if the JSON is invalid
+     * @onos.rsModel Devicekey
      */
-// FIXME wrong schema definition?
-//   * @onos.rsModel IntentHost
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
@@ -117,8 +114,8 @@
     /**
      * Removes a device key by device key identifier.
      *
-     * @param id device identifier
-     * @return 200 OK
+     * @param id device key identifier
+     * @return 200 OK, 404 not found
      */
     @DELETE
     @Path("{id}")
diff --git a/web/api/src/main/resources/definitions/Devicekey.json b/web/api/src/main/resources/definitions/Devicekey.json
new file mode 100644
index 0000000..a8bee2d
--- /dev/null
+++ b/web/api/src/main/resources/definitions/Devicekey.json
@@ -0,0 +1,35 @@
+{
+  "type": "object",
+  "title": "Devicekey",
+  "required": [
+    "id",
+    "type",
+    "label"
+  ],
+  "properties": {
+    "id": {
+      "type": "String",
+      "example": "Device key unique identifier"
+    },
+    "type": {
+      "type": "String",
+      "example": "COMMUNITY_NAME, OR USERNAME_PASSWORD"
+    },
+    "label": {
+      "type": "String",
+      "example": "Device key user label"
+    },
+    "community_name": {
+      "type": "String",
+      "example": "Device key community name"
+    },
+    "username": {
+      "type": "String",
+      "example": "Device key username"
+    },
+    "password": {
+      "type": "String",
+      "example": "Device key password"
+    }
+  }
+}
diff --git a/web/api/src/main/resources/definitions/Devicekeys.json b/web/api/src/main/resources/definitions/Devicekeys.json
new file mode 100644
index 0000000..57871f5
--- /dev/null
+++ b/web/api/src/main/resources/definitions/Devicekeys.json
@@ -0,0 +1,51 @@
+{
+  "type": "object",
+  "title": "Devicekeys",
+  "required": [
+    "keys"
+  ],
+  "properties": {
+    "keys": {
+      "type": "array",
+      "xml": {
+        "name": "keys",
+        "wrapped": true
+      },
+      "items": {
+        "type": "object",
+        "title": "key",
+        "required": [
+          "id",
+          "type",
+          "label"
+        ],
+        "properties": {
+          "id": {
+            "type": "String",
+            "example": "Device key unique identifier"
+          },
+          "type": {
+            "type": "String",
+            "example": "COMMUNITY_NAME, OR USERNAME_PASSWORD"
+          },
+          "label": {
+            "type": "String",
+            "example": "Device key user label"
+          },
+          "community_name": {
+            "type": "String",
+            "example": "Device key community name"
+          },
+          "username": {
+            "type": "String",
+            "example": "Device key username"
+          },
+          "password": {
+            "type": "String",
+            "example": "Device key password"
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/web/api/src/test/java/org/onosproject/rest/DeviceKeyWebResourceTest.java b/web/api/src/test/java/org/onosproject/rest/DeviceKeyWebResourceTest.java
index 886674c..54f1bea 100644
--- a/web/api/src/test/java/org/onosproject/rest/DeviceKeyWebResourceTest.java
+++ b/web/api/src/test/java/org/onosproject/rest/DeviceKeyWebResourceTest.java
@@ -25,7 +25,6 @@
 import org.hamcrest.Description;
 import org.hamcrest.Matchers;
 import org.hamcrest.TypeSafeMatcher;
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.onlab.osgi.ServiceDirectory;
@@ -67,6 +66,7 @@
     private final String deviceKeyId1 = "DeviceKeyId1";
     private final String deviceKeyId2 = "DeviceKeyId2";
     private final String deviceKeyId3 = "DeviceKeyId3";
+    private final String deviceKeyId4 = "DeviceKeyId4";
     private final String deviceKeyLabel = "DeviceKeyLabel";
     private final String deviceKeyCommunityName = "DeviceKeyCommunityName";
     private final String deviceKeyUsername = "DeviceKeyUsername";
@@ -75,7 +75,11 @@
     private final DeviceKey deviceKey1 = DeviceKey.createDeviceKeyUsingCommunityName(
             DeviceKeyId.deviceKeyId(deviceKeyId1), deviceKeyLabel, deviceKeyCommunityName);
     private final DeviceKey deviceKey2 = DeviceKey.createDeviceKeyUsingUsernamePassword(
-            DeviceKeyId.deviceKeyId(deviceKeyId2), deviceKeyLabel, deviceKeyUsername, deviceKeyPassword);
+            DeviceKeyId.deviceKeyId(deviceKeyId2), null, deviceKeyUsername, deviceKeyPassword);
+    private final DeviceKey deviceKey3 = DeviceKey.createDeviceKeyUsingUsernamePassword(
+            DeviceKeyId.deviceKeyId(deviceKeyId3), null, null, null);
+    private final DeviceKey deviceKey4 = DeviceKey.createDeviceKeyUsingCommunityName(
+            DeviceKeyId.deviceKeyId(deviceKeyId4), null, null);
 
     /**
      * Initializes test mocks and environment.
@@ -97,15 +101,6 @@
     }
 
     /**
-     * Verifies test mocks.
-     */
-    @After
-    public void tearDownMocks() {
-        verify(mockDeviceKeyService);
-        verify(mockDeviceKeyAdminService);
-    }
-
-    /**
      * Hamcrest matcher to check that a device key representation in JSON matches
      * the actual device key.
      */
@@ -127,10 +122,12 @@
             }
 
             // Check the device key label
-            final String jsonLabel = jsonHost.get(LABEL).asString();
-            if (!jsonLabel.equals(deviceKey.label().toString())) {
-                reason = LABEL + " " + deviceKey.label().toString();
-                return false;
+            final String jsonLabel = (jsonHost.get(LABEL).isNull()) ? null : jsonHost.get(LABEL).asString();
+            if (deviceKey.label() != null) {
+                if ((jsonLabel == null) || !jsonLabel.equals(deviceKey.label())) {
+                    reason = LABEL + " " + deviceKey.label();
+                    return false;
+                }
             }
 
             // Check the device key type
@@ -142,24 +139,33 @@
 
             if (jsonType.equals(DeviceKey.Type.COMMUNITY_NAME.toString())) {
                 // Check the device key community name
-                final String jsonCommunityName = jsonHost.get(COMMUNITY_NAME).asString();
-                if (!jsonCommunityName.equals(deviceKey.asCommunityName().name().toString())) {
-                    reason = COMMUNITY_NAME + " " + deviceKey.asCommunityName().name().toString();
-                    return false;
+                final String jsonCommunityName = jsonHost.get(COMMUNITY_NAME).isNull() ?
+                        null : jsonHost.get(COMMUNITY_NAME).asString();
+                if (deviceKey.asCommunityName().name() != null) {
+                    if (!jsonCommunityName.equals(deviceKey.asCommunityName().name().toString())) {
+                        reason = COMMUNITY_NAME + " " + deviceKey.asCommunityName().name().toString();
+                        return false;
+                    }
                 }
             } else if (jsonType.equals(DeviceKey.Type.USERNAME_PASSWORD.toString())) {
                 // Check the device key username
-                final String jsonUsername = jsonHost.get(USERNAME).asString();
-                if (!jsonUsername.equals(deviceKey.asUsernamePassword().username().toString())) {
-                    reason = USERNAME + " " + deviceKey.asUsernamePassword().username().toString();
-                    return false;
+                final String jsonUsername = jsonHost.get(USERNAME).isNull() ?
+                        null : jsonHost.get(USERNAME).asString();
+                if (deviceKey.asUsernamePassword().username() != null) {
+                    if (!jsonUsername.equals(deviceKey.asUsernamePassword().username().toString())) {
+                        reason = USERNAME + " " + deviceKey.asUsernamePassword().username().toString();
+                        return false;
+                    }
                 }
 
                 // Check the device key password
-                final String jsonPassword = jsonHost.get(PASSWORD).asString();
-                if (!jsonPassword.equals(deviceKey.asUsernamePassword().password().toString())) {
-                    reason = PASSWORD + " " + deviceKey.asUsernamePassword().password().toString();
-                    return false;
+                final String jsonPassword = jsonHost.get(PASSWORD).isNull() ?
+                        null : jsonHost.get(PASSWORD).asString();
+                if (deviceKey.asUsernamePassword().password() != null) {
+                    if (!jsonPassword.equals(deviceKey.asUsernamePassword().password().toString())) {
+                        reason = PASSWORD + " " + deviceKey.asUsernamePassword().password().toString();
+                        return false;
+                    }
                 }
             } else {
                 reason = "Unknown " + TYPE + " " + deviceKey.type().toString();
@@ -251,11 +257,12 @@
     @Test
     public void testGetDeviceKeysEmptyArray() {
         replay(mockDeviceKeyService);
-        replay(mockDeviceKeyAdminService);
 
         WebResource rs = resource();
         String response = rs.path("keys").get(String.class);
         assertThat(response, is("{\"keys\":[]}"));
+
+        verify(mockDeviceKeyService);
     }
 
     /**
@@ -264,9 +271,10 @@
     @Test
     public void testGetDeviceKeysArray() {
         replay(mockDeviceKeyService);
-        replay(mockDeviceKeyAdminService);
         deviceKeySet.add(deviceKey1);
         deviceKeySet.add(deviceKey2);
+        deviceKeySet.add(deviceKey3);
+        deviceKeySet.add(deviceKey4);
 
         WebResource rs = resource();
         String response = rs.path("keys").get(String.class);
@@ -280,10 +288,14 @@
 
         final JsonArray deviceKeys = result.get("keys").asArray();
         assertThat(deviceKeys, notNullValue());
-        assertEquals("Device keys array is not the correct size.", 2, deviceKeys.size());
+        assertEquals("Device keys array is not the correct size.", 4, deviceKeys.size());
 
         assertThat(deviceKeys, hasDeviceKey(deviceKey1));
         assertThat(deviceKeys, hasDeviceKey(deviceKey2));
+        assertThat(deviceKeys, hasDeviceKey(deviceKey3));
+        assertThat(deviceKeys, hasDeviceKey(deviceKey4));
+
+        verify(mockDeviceKeyService);
     }
 
     /**
@@ -297,7 +309,6 @@
                 .andReturn(deviceKey1)
                 .anyTimes();
         replay(mockDeviceKeyService);
-        replay(mockDeviceKeyAdminService);
 
         WebResource rs = resource();
         String response = rs.path("keys/" + deviceKeyId1).get(String.class);
@@ -305,6 +316,8 @@
         assertThat(result, notNullValue());
 
         assertThat(result, matchesDeviceKey(deviceKey1));
+
+        verify(mockDeviceKeyService);
     }
 
     /**
@@ -317,7 +330,6 @@
                 .andReturn(null)
                 .anyTimes();
         replay(mockDeviceKeyService);
-        replay(mockDeviceKeyAdminService);
 
         WebResource rs = resource();
         try {
@@ -327,6 +339,8 @@
             assertThat(ex.getMessage(),
                        containsString("returned a response status of"));
         }
+
+        verify(mockDeviceKeyService);
     }
 
     /**
@@ -338,7 +352,6 @@
         mockDeviceKeyAdminService.addKey(anyObject());
         expectLastCall();
 
-        replay(mockDeviceKeyService);
         replay(mockDeviceKeyAdminService);
 
         WebResource rs = resource();
@@ -352,6 +365,8 @@
 
         String location = response.getLocation().getPath();
         assertThat(location, Matchers.startsWith("/keys/" + deviceKeyId3));
+
+        verify(mockDeviceKeyAdminService);
     }
 
     /**
@@ -360,7 +375,6 @@
     @Test
     public void testPostNullDeviceKey() {
 
-        replay(mockDeviceKeyService);
         replay(mockDeviceKeyAdminService);
 
         WebResource rs = resource();
@@ -373,6 +387,8 @@
             assertThat(ex.getMessage(),
                        containsString("returned a response status of"));
         }
+
+        verify(mockDeviceKeyAdminService);
     }
 
     /**
@@ -395,6 +411,9 @@
                 .type(MediaType.APPLICATION_JSON_TYPE)
                 .delete(ClientResponse.class);
         assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));
+
+        verify(mockDeviceKeyService);
+        verify(mockDeviceKeyAdminService);
     }
 
     /**
@@ -421,5 +440,8 @@
             assertThat(ex.getMessage(),
                        containsString("returned a response status of"));
         }
+
+        verify(mockDeviceKeyService);
+        verify(mockDeviceKeyAdminService);
     }
 }
\ No newline at end of file