Revise Mastership REST API to use synchronous methods
- Add missing swagger docs
- Add missing unit tests
Change-Id: I21a20410ea322e7893c5c0c48f5d9fd0f2f9dfe1
diff --git a/web/api/src/main/java/org/onosproject/rest/resources/MastershipWebResource.java b/web/api/src/main/java/org/onosproject/rest/resources/MastershipWebResource.java
index 4dfc28f..99cc28c 100644
--- a/web/api/src/main/java/org/onosproject/rest/resources/MastershipWebResource.java
+++ b/web/api/src/main/java/org/onosproject/rest/resources/MastershipWebResource.java
@@ -37,8 +37,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
import static org.onlab.util.Tools.nullIsNotFound;
@@ -48,8 +46,7 @@
@Path("mastership")
public final class MastershipWebResource extends AbstractWebResource {
- private static final String NODE = "node";
- private static final String DEVICES = "devices";
+ private static final String DEVICE_IDS = "deviceIds";
private static final String DEVICE_ID = "deviceId";
private static final String NODE_ID = "nodeId";
@@ -59,7 +56,6 @@
private static final String NODE_ID_NOT_FOUND = "Node id is not found";
private static final String ROLE_INFO_NOT_FOUND = "Role info is not found";
private static final String MASTERSHIP_ROLE_NOT_FOUND = "Mastership role is not found";
- private static final String RESULT_NOT_FOUND = "Result is not found";
private final MastershipService mastershipService = get(MastershipService.class);
private final MastershipAdminService mastershipAdminService =
@@ -86,7 +82,7 @@
*
* @param deviceId device identifier
* @return the identifier of the master controller for the device
- * // TODO: add swagger doc
+ * @onos.rsModel NodeId
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@@ -96,7 +92,7 @@
DeviceId.deviceId(deviceId)), NODE_ID_NOT_FOUND);
ObjectNode root = mapper().createObjectNode();
- root.put(NODE, id.id());
+ root.put(NODE_ID, id.id());
return ok(root).build();
}
@@ -123,14 +119,14 @@
*
* @param nodeId controller identifier
* @return a set of device identifiers
- * // TODO: add swagger doc
+ * @onos.rsModel DeviceIds
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("{nodeId}/device")
public Response getDeviceOf(@PathParam("nodeId") String nodeId) {
ObjectNode root = mapper().createObjectNode();
- ArrayNode devicesNode = root.putArray(DEVICES);
+ ArrayNode devicesNode = root.putArray(DEVICE_IDS);
Set<DeviceId> devices = mastershipService.getDevicesOf(NodeId.nodeId(nodeId));
if (devices != null) {
@@ -152,20 +148,10 @@
@Produces(MediaType.APPLICATION_JSON)
@Path("{deviceId}/request")
public Response requestRoleFor(@PathParam("deviceId") String deviceId) {
-
- // TODO: will not use CompletableFuture when MastershipService
- // provides a non CompletableFuture object as an output
- CompletableFuture<MastershipRole> result =
- nullIsNotFound(mastershipService.requestRoleFor(
- DeviceId.deviceId(deviceId)), MASTERSHIP_ROLE_NOT_FOUND);
-
- try {
- MastershipRole role = result.get();
- ObjectNode root = codec(MastershipRole.class).encode(role, this);
- return ok(root).build();
- } catch (InterruptedException | ExecutionException e) {
- throw new IllegalArgumentException(e);
- }
+ MastershipRole role = nullIsNotFound(mastershipService.requestRoleForSync(
+ DeviceId.deviceId(deviceId)), MASTERSHIP_ROLE_NOT_FOUND);
+ ObjectNode root = codec(MastershipRole.class).encode(role, this);
+ return ok(root).build();
}
/**
@@ -181,18 +167,8 @@
@Path("{deviceId}/relinquish")
public Response relinquishMastership(@PathParam("deviceId") String deviceId) {
DeviceId id = DeviceId.deviceId(deviceId);
-
- // TODO: will not use CompletableFuture when MastershipService
- // provides a non CompletableFuture object as an output
- CompletableFuture<Void> result =
- nullIsNotFound(mastershipService.relinquishMastership(id), RESULT_NOT_FOUND);
-
- try {
- result.get();
- return Response.created(id.uri()).build();
- } catch (InterruptedException | ExecutionException e) {
- throw new IllegalArgumentException(e);
- }
+ mastershipService.relinquishMastershipSync(id);
+ return Response.created(id.uri()).build();
}
/**
@@ -222,15 +198,11 @@
throw new IllegalArgumentException(NODE_ID_INVALID);
}
- // TODO: will not use CompletableFuture when MastershipAdminService
- // provides a non CompletableFuture object as an output
- CompletableFuture<Void> result =
- nullIsNotFound(mastershipAdminService.setRole(NodeId.nodeId(nodeIdJson.asText()),
- DeviceId.deviceId(deviceIdJson.asText()), role), RESULT_NOT_FOUND);
- result.get();
+ mastershipAdminService.setRoleSync(NodeId.nodeId(nodeIdJson.asText()),
+ DeviceId.deviceId(deviceIdJson.asText()), role);
return Response.ok().build();
- } catch (InterruptedException | ExecutionException | IOException e) {
+ } catch (IOException e) {
throw new IllegalArgumentException(e);
}
}
diff --git a/web/api/src/main/resources/definitions/DeviceIds.json b/web/api/src/main/resources/definitions/DeviceIds.json
new file mode 100644
index 0000000..9911022
--- /dev/null
+++ b/web/api/src/main/resources/definitions/DeviceIds.json
@@ -0,0 +1,20 @@
+{
+ "type": "object",
+ "title": "deviceIds",
+ "required": [
+ "deviceIds"
+ ],
+ "properties": {
+ "deviceIds": {
+ "type": "array",
+ "xml": {
+ "name": "deviceId",
+ "wrapped": true
+ },
+ "items": {
+ "type": "string",
+ "example": "of:0000000000000001"
+ }
+ }
+ }
+}
diff --git a/web/api/src/main/resources/definitions/NodeId.json b/web/api/src/main/resources/definitions/NodeId.json
new file mode 100644
index 0000000..43deb94
--- /dev/null
+++ b/web/api/src/main/resources/definitions/NodeId.json
@@ -0,0 +1,13 @@
+{
+ "type": "object",
+ "title": "nodeId",
+ "required": [
+ "nodeId"
+ ],
+ "properties": {
+ "nodeId": {
+ "type": "string",
+ "example": "1"
+ }
+ }
+}
\ No newline at end of file
diff --git a/web/api/src/test/java/org/onosproject/rest/resources/MastershipResourceTest.java b/web/api/src/test/java/org/onosproject/rest/resources/MastershipResourceTest.java
index de92cd5..994e138 100644
--- a/web/api/src/test/java/org/onosproject/rest/resources/MastershipResourceTest.java
+++ b/web/api/src/test/java/org/onosproject/rest/resources/MastershipResourceTest.java
@@ -22,6 +22,7 @@
import com.google.common.collect.ImmutableSet;
import org.apache.commons.lang3.StringUtils;
import org.hamcrest.Description;
+import org.hamcrest.Matchers;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Before;
import org.junit.Test;
@@ -37,8 +38,10 @@
import org.onosproject.net.DeviceId;
import org.onosproject.net.MastershipRole;
+import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
+import java.io.InputStream;
import java.net.HttpURLConnection;
import java.util.List;
import java.util.Set;
@@ -214,9 +217,9 @@
assertThat(result, notNullValue());
assertThat(result.names(), hasSize(1));
- assertThat(result.names().get(0), is("node"));
+ assertThat(result.names().get(0), is("nodeId"));
- final String node = result.get("node").asString();
+ final String node = result.get("nodeId").asString();
assertThat(node, notNullValue());
assertThat(node, is("node:1"));
}
@@ -269,9 +272,9 @@
assertThat(result, notNullValue());
assertThat(result.names(), hasSize(1));
- assertThat(result.names().get(0), is("devices"));
+ assertThat(result.names().get(0), is("deviceIds"));
- final JsonArray jsonDevices = result.get("devices").asArray();
+ final JsonArray jsonDevices = result.get("deviceIds").asArray();
assertThat(jsonDevices, notNullValue());
assertThat(jsonDevices.size(), is(3));
}
@@ -281,7 +284,21 @@
*/
@Test
public void testRequestRoleFor() {
- // TODO: will be added when CompletableFuture is removed
+ expect(mockService.requestRoleForSync(anyObject())).andReturn(role1).anyTimes();
+ replay(mockService);
+
+ final WebTarget wt = target();
+ final String response = wt.path("mastership/" + deviceId1.toString() +
+ "/request").request().get(String.class);
+ final JsonObject result = Json.parse(response).asObject();
+ assertThat(result, notNullValue());
+
+ assertThat(result.names(), hasSize(1));
+ assertThat(result.names().get(0), is("role"));
+
+ final String role = result.get("role").asString();
+ assertThat(role, notNullValue());
+ assertThat(role, is("MASTER"));
}
/**
@@ -289,7 +306,16 @@
*/
@Test
public void testRelinquishMastership() {
- // TODO: will be added when CompletableFuture is removed
+ mockService.relinquishMastershipSync(anyObject());
+ expectLastCall();
+ replay(mockService);
+
+ final WebTarget wt = target();
+ final Response response = wt.path("mastership/" + deviceId1.toString() +
+ "/relinquish").request().get();
+ assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
+ String location = response.getLocation().toString();
+ assertThat(location, Matchers.startsWith(deviceId1.toString()));
}
/**
@@ -297,7 +323,16 @@
*/
@Test
public void testSetRole() {
- // TODO: will be added when CompletableFuture is removed
+ mockAdminService.setRoleSync(anyObject(), anyObject(), anyObject());
+ expectLastCall();
+ replay(mockAdminService);
+
+ final WebTarget wt = target();
+ final InputStream jsonStream = MetersResourceTest.class
+ .getResourceAsStream("put-set-roles.json");
+ final Response response = wt.path("mastership")
+ .request().put(Entity.json(jsonStream));
+ assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));
}
/**