Brian Stanke
Committed by Gerrit Code Review

ONOS-3658 - Adding REST APIs for query and management of device keys.

Change-Id: I3c70660a15d9085409e43d2d14120d29fd5020be
...@@ -53,6 +53,7 @@ import org.onosproject.net.intent.Constraint; ...@@ -53,6 +53,7 @@ import org.onosproject.net.intent.Constraint;
53 import org.onosproject.net.intent.HostToHostIntent; 53 import org.onosproject.net.intent.HostToHostIntent;
54 import org.onosproject.net.intent.Intent; 54 import org.onosproject.net.intent.Intent;
55 import org.onosproject.net.intent.PointToPointIntent; 55 import org.onosproject.net.intent.PointToPointIntent;
56 +import org.onosproject.net.key.DeviceKey;
56 import org.onosproject.net.mcast.McastRoute; 57 import org.onosproject.net.mcast.McastRoute;
57 import org.onosproject.net.meter.Band; 58 import org.onosproject.net.meter.Band;
58 import org.onosproject.net.meter.Meter; 59 import org.onosproject.net.meter.Meter;
...@@ -119,6 +120,7 @@ public class CodecManager implements CodecService { ...@@ -119,6 +120,7 @@ public class CodecManager implements CodecService {
119 registerCodec(ForwardingObjective.class, new ForwardingObjectiveCodec()); 120 registerCodec(ForwardingObjective.class, new ForwardingObjectiveCodec());
120 registerCodec(NextObjective.class, new NextObjectiveCodec()); 121 registerCodec(NextObjective.class, new NextObjectiveCodec());
121 registerCodec(McastRoute.class, new McastRouteCodec()); 122 registerCodec(McastRoute.class, new McastRouteCodec());
123 + registerCodec(DeviceKey.class, new DeviceKeyCodec());
122 log.info("Started"); 124 log.info("Started");
123 } 125 }
124 126
......
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.codec.impl;
18 +
19 +import com.fasterxml.jackson.databind.node.ObjectNode;
20 +import org.onosproject.codec.CodecContext;
21 +import org.onosproject.net.key.DeviceKey;
22 +import org.onosproject.net.key.DeviceKeyId;
23 +import org.onosproject.net.key.DeviceKeyService;
24 +import org.slf4j.Logger;
25 +
26 +import static com.google.common.base.Preconditions.checkNotNull;
27 +import static org.slf4j.LoggerFactory.getLogger;
28 +
29 +/**
30 + * Device key JSON codec.
31 + */
32 +public class DeviceKeyCodec extends AnnotatedCodec<DeviceKey> {
33 +
34 + private final Logger log = getLogger(getClass());
35 +
36 + // JSON fieldNames
37 + private static final String ID = "id";
38 + private static final String TYPE = "type";
39 + private static final String LABEL = "label";
40 + private static final String COMMUNITY_NAME = "community_name";
41 + private static final String USERNAME = "username";
42 + private static final String PASSWORD = "password";
43 +
44 +
45 + @Override
46 + public ObjectNode encode(DeviceKey deviceKey, CodecContext context) {
47 + checkNotNull(deviceKey, "Device key cannot be null");
48 + DeviceKeyService service = context.getService(DeviceKeyService.class);
49 + ObjectNode result = context.mapper().createObjectNode()
50 + .put(ID, deviceKey.deviceKeyId().id().toString())
51 + .put(TYPE, deviceKey.type().toString())
52 + .put(LABEL, deviceKey.label().toString());
53 +
54 + if (deviceKey.type().equals(DeviceKey.Type.COMMUNITY_NAME)) {
55 + result.put(COMMUNITY_NAME, deviceKey.asCommunityName().name());
56 + } else if (deviceKey.type().equals(DeviceKey.Type.USERNAME_PASSWORD)) {
57 + result.put(USERNAME, deviceKey.asUsernamePassword().username().toString());
58 + result.put(PASSWORD, deviceKey.asUsernamePassword().password().toString());
59 + }
60 +
61 + return annotate(result, deviceKey, context);
62 + }
63 +
64 + @Override
65 + public DeviceKey decode(ObjectNode json, CodecContext context) {
66 + if (json == null || !json.isObject()) {
67 + return null;
68 + }
69 +
70 + DeviceKeyId id = DeviceKeyId.deviceKeyId(json.get(ID).asText());
71 +
72 + DeviceKey.Type type = DeviceKey.Type.valueOf(json.get(TYPE).asText());
73 + String label = json.get(LABEL).asText();
74 +
75 + if (type.equals(DeviceKey.Type.COMMUNITY_NAME)) {
76 + String communityName = json.get(COMMUNITY_NAME).asText();
77 + return DeviceKey.createDeviceKeyUsingCommunityName(id, label, communityName);
78 + } else if (type.equals(DeviceKey.Type.USERNAME_PASSWORD)) {
79 + String username = json.get(USERNAME).asText();
80 + String password = json.get(PASSWORD).asText();
81 + return DeviceKey.createDeviceKeyUsingUsernamePassword(id, label, username, password);
82 + } else {
83 + log.error("Unknown device key type: ", type);
84 + return null;
85 + }
86 + }
87 +}
...@@ -45,7 +45,8 @@ public class CoreWebApplication extends AbstractWebApplication { ...@@ -45,7 +45,8 @@ public class CoreWebApplication extends AbstractWebApplication {
45 StatisticsWebResource.class, 45 StatisticsWebResource.class,
46 MetricsWebResource.class, 46 MetricsWebResource.class,
47 FlowObjectiveWebResource.class, 47 FlowObjectiveWebResource.class,
48 - MulticastRouteWebResource.class 48 + MulticastRouteWebResource.class,
49 + DeviceKeyWebResource.class
49 ); 50 );
50 } 51 }
51 } 52 }
......
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.rest.resources;
18 +
19 +import com.fasterxml.jackson.databind.node.ObjectNode;
20 +import org.onosproject.net.key.DeviceKey;
21 +import org.onosproject.net.key.DeviceKeyAdminService;
22 +import org.onosproject.net.key.DeviceKeyId;
23 +import org.onosproject.net.key.DeviceKeyService;
24 +import org.onosproject.rest.AbstractWebResource;
25 +
26 +import javax.ws.rs.Consumes;
27 +import javax.ws.rs.DELETE;
28 +import javax.ws.rs.GET;
29 +import javax.ws.rs.POST;
30 +import javax.ws.rs.Path;
31 +import javax.ws.rs.PathParam;
32 +import javax.ws.rs.Produces;
33 +import javax.ws.rs.core.Context;
34 +import javax.ws.rs.core.MediaType;
35 +import javax.ws.rs.core.Response;
36 +import javax.ws.rs.core.UriBuilder;
37 +import javax.ws.rs.core.UriInfo;
38 +import java.io.IOException;
39 +import java.io.InputStream;
40 +
41 +import static org.onlab.util.Tools.nullIsNotFound;
42 +
43 +/**
44 + * Query and Manage Device Keys.
45 + */
46 +@Path("keys")
47 +public class DeviceKeyWebResource extends AbstractWebResource {
48 +
49 + @Context
50 + UriInfo uriInfo;
51 +
52 + private static final String DEVICE_KEY_NOT_FOUND = "Device key was not found";
53 +
54 + /**
55 + * Gets all device keys.
56 + * Returns array of all device keys.
57 + *
58 + * @return 200 OK
59 + * @onos.rsModel DeviceKeysGet
60 + */
61 + @GET
62 + public Response getDeviceKeys() {
63 + Iterable<DeviceKey> deviceKeys = get(DeviceKeyService.class).getDeviceKeys();
64 + return ok(encodeArray(DeviceKey.class, "keys", deviceKeys)).build();
65 + }
66 +
67 + /**
68 + * Get a single device key by device key unique identifier.
69 + * Returns the specified device key.
70 + *
71 + * @param id device identifier
72 + * @return 200 OK
73 + * @onos.rsModel DeviceKeyGet
74 + */
75 + @GET
76 + @Path("{id}")
77 + public Response getDeviceKey(@PathParam("id") String id) {
78 + DeviceKey deviceKey = nullIsNotFound(get(DeviceKeyService.class).getDeviceKey(DeviceKeyId.deviceKeyId(id)),
79 + DEVICE_KEY_NOT_FOUND);
80 + return ok(codec(DeviceKey.class).encode(deviceKey, this)).build();
81 + }
82 +
83 + /**
84 + * Adds a new device key from the JSON request.
85 + *
86 + * @param stream input JSON
87 + * @return status of the request - CREATED if the JSON is correct,
88 + * BAD_REQUEST if the JSON is invalid
89 + * @onos.rsModel IntentHost
90 + */
91 + @POST
92 + @Consumes(MediaType.APPLICATION_JSON)
93 + @Produces(MediaType.APPLICATION_JSON)
94 + public Response addDeviceKey(InputStream stream) {
95 + try {
96 + DeviceKeyAdminService service = get(DeviceKeyAdminService.class);
97 + ObjectNode root = (ObjectNode) mapper().readTree(stream);
98 + DeviceKey deviceKey = codec(DeviceKey.class).decode(root, this);
99 + service.addKey(deviceKey);
100 +
101 + UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
102 + .path("keys")
103 + .path(deviceKey.deviceKeyId().id());
104 +
105 + return Response
106 + .created(locationBuilder.build())
107 + .build();
108 +
109 + } catch (IOException ioe) {
110 + throw new IllegalArgumentException(ioe);
111 + }
112 + }
113 +
114 + /**
115 + * Removes a device key by device key identifier.
116 + *
117 + * @param id device identifier
118 + * @return 200 OK
119 + */
120 + @DELETE
121 + @Path("{id}")
122 + public Response removeDeviceKey(@PathParam("id") String id) {
123 + DeviceKey deviceKey = nullIsNotFound(get(DeviceKeyService.class).getDeviceKey(DeviceKeyId.deviceKeyId(id)),
124 + DEVICE_KEY_NOT_FOUND);
125 + get(DeviceKeyAdminService.class).removeKey(DeviceKeyId.deviceKeyId(id));
126 + return ok(codec(DeviceKey.class).encode(deviceKey, this)).build();
127 + }
128 +}
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.rest;
18 +
19 +import com.eclipsesource.json.Json;
20 +import com.eclipsesource.json.JsonArray;
21 +import com.eclipsesource.json.JsonObject;
22 +import com.sun.jersey.api.client.ClientResponse;
23 +import com.sun.jersey.api.client.UniformInterfaceException;
24 +import com.sun.jersey.api.client.WebResource;
25 +import org.hamcrest.Description;
26 +import org.hamcrest.Matchers;
27 +import org.hamcrest.TypeSafeMatcher;
28 +import org.junit.After;
29 +import org.junit.Before;
30 +import org.junit.Test;
31 +import org.onlab.osgi.ServiceDirectory;
32 +import org.onlab.osgi.TestServiceDirectory;
33 +import org.onlab.rest.BaseResource;
34 +import org.onosproject.codec.CodecService;
35 +import org.onosproject.codec.impl.CodecManager;
36 +import org.onosproject.net.key.DeviceKey;
37 +import org.onosproject.net.key.DeviceKeyAdminService;
38 +import org.onosproject.net.key.DeviceKeyId;
39 +import org.onosproject.net.key.DeviceKeyService;
40 +
41 +import javax.ws.rs.core.MediaType;
42 +import java.io.InputStream;
43 +import java.net.HttpURLConnection;
44 +import java.util.HashSet;
45 +
46 +import static org.easymock.EasyMock.*;
47 +import static org.hamcrest.Matchers.*;
48 +import static org.junit.Assert.*;
49 +
50 +/**
51 + * Unit tests for device key REST APIs.
52 + */
53 +public class DeviceKeyWebResourceTest extends ResourceTest {
54 +
55 + final DeviceKeyService mockDeviceKeyService = createMock(DeviceKeyService.class);
56 + final DeviceKeyAdminService mockDeviceKeyAdminService = createMock(DeviceKeyAdminService.class);
57 +
58 + final HashSet<DeviceKey> deviceKeySet = new HashSet<>();
59 +
60 + private static final String ID = "id";
61 + private static final String TYPE = "type";
62 + private static final String LABEL = "label";
63 + private static final String COMMUNITY_NAME = "community_name";
64 + private static final String USERNAME = "username";
65 + private static final String PASSWORD = "password";
66 +
67 + private final String deviceKeyId1 = "DeviceKeyId1";
68 + private final String deviceKeyId2 = "DeviceKeyId2";
69 + private final String deviceKeyId3 = "DeviceKeyId3";
70 + private final String deviceKeyLabel = "DeviceKeyLabel";
71 + private final String deviceKeyCommunityName = "DeviceKeyCommunityName";
72 + private final String deviceKeyUsername = "DeviceKeyUsername";
73 + private final String deviceKeyPassword = "DeviceKeyPassword";
74 +
75 + private final DeviceKey deviceKey1 = DeviceKey.createDeviceKeyUsingCommunityName(
76 + DeviceKeyId.deviceKeyId(deviceKeyId1), deviceKeyLabel, deviceKeyCommunityName);
77 + private final DeviceKey deviceKey2 = DeviceKey.createDeviceKeyUsingUsernamePassword(
78 + DeviceKeyId.deviceKeyId(deviceKeyId2), deviceKeyLabel, deviceKeyUsername, deviceKeyPassword);
79 +
80 + /**
81 + * Initializes test mocks and environment.
82 + */
83 + @Before
84 + public void setUpMocks() {
85 + expect(mockDeviceKeyService.getDeviceKeys()).andReturn(deviceKeySet).anyTimes();
86 +
87 + // Register the services needed for the test
88 + CodecManager codecService = new CodecManager();
89 + codecService.activate();
90 + ServiceDirectory testDirectory =
91 + new TestServiceDirectory()
92 + .add(DeviceKeyService.class, mockDeviceKeyService)
93 + .add(DeviceKeyAdminService.class, mockDeviceKeyAdminService)
94 + .add(CodecService.class, codecService);
95 +
96 + BaseResource.setServiceDirectory(testDirectory);
97 + }
98 +
99 + /**
100 + * Verifies test mocks.
101 + */
102 + @After
103 + public void tearDownMocks() {
104 + verify(mockDeviceKeyService);
105 + verify(mockDeviceKeyAdminService);
106 + }
107 +
108 + /**
109 + * Hamcrest matcher to check that a device key representation in JSON matches
110 + * the actual device key.
111 + */
112 + public static class DeviceKeyJsonMatcher extends TypeSafeMatcher<JsonObject> {
113 + private final DeviceKey deviceKey;
114 + private String reason = "";
115 +
116 + public DeviceKeyJsonMatcher(DeviceKey deviceKeyValue) {
117 + deviceKey = deviceKeyValue;
118 + }
119 +
120 + @Override
121 + public boolean matchesSafely(JsonObject jsonHost) {
122 + // Check the device key id
123 + final String jsonId = jsonHost.get(ID).asString();
124 + if (!jsonId.equals(deviceKey.deviceKeyId().id().toString())) {
125 + reason = ID + " " + deviceKey.deviceKeyId().id().toString();
126 + return false;
127 + }
128 +
129 + // Check the device key label
130 + final String jsonLabel = jsonHost.get(LABEL).asString();
131 + if (!jsonLabel.equals(deviceKey.label().toString())) {
132 + reason = LABEL + " " + deviceKey.label().toString();
133 + return false;
134 + }
135 +
136 + // Check the device key type
137 + final String jsonType = jsonHost.get(TYPE).asString();
138 + if (!jsonType.equals(deviceKey.type().toString())) {
139 + reason = TYPE + " " + deviceKey.type().toString();
140 + return false;
141 + }
142 +
143 + if (jsonType.equals(DeviceKey.Type.COMMUNITY_NAME.toString())) {
144 + // Check the device key community name
145 + final String jsonCommunityName = jsonHost.get(COMMUNITY_NAME).asString();
146 + if (!jsonCommunityName.equals(deviceKey.asCommunityName().name().toString())) {
147 + reason = COMMUNITY_NAME + " " + deviceKey.asCommunityName().name().toString();
148 + return false;
149 + }
150 + } else if (jsonType.equals(DeviceKey.Type.USERNAME_PASSWORD.toString())) {
151 + // Check the device key username
152 + final String jsonUsername = jsonHost.get(USERNAME).asString();
153 + if (!jsonUsername.equals(deviceKey.asUsernamePassword().username().toString())) {
154 + reason = USERNAME + " " + deviceKey.asUsernamePassword().username().toString();
155 + return false;
156 + }
157 +
158 + // Check the device key password
159 + final String jsonPassword = jsonHost.get(PASSWORD).asString();
160 + if (!jsonPassword.equals(deviceKey.asUsernamePassword().password().toString())) {
161 + reason = PASSWORD + " " + deviceKey.asUsernamePassword().password().toString();
162 + return false;
163 + }
164 + } else {
165 + reason = "Unknown " + TYPE + " " + deviceKey.type().toString();
166 + return false;
167 + }
168 +
169 + return true;
170 + }
171 +
172 + @Override
173 + public void describeTo(Description description) {
174 + description.appendText(reason);
175 + }
176 + }
177 +
178 + /**
179 + * Factory to allocate a device key array matcher.
180 + *
181 + * @param deviceKey device key object we are looking for
182 + * @return matcher
183 + */
184 + private static DeviceKeyJsonMatcher matchesDeviceKey(DeviceKey deviceKey) {
185 + return new DeviceKeyJsonMatcher(deviceKey);
186 + }
187 +
188 + /**
189 + * Hamcrest matcher to check that a device key is represented properly in a JSON
190 + * array of device keys.
191 + */
192 + public static class DeviceKeyJsonArrayMatcher extends TypeSafeMatcher<JsonArray> {
193 + private final DeviceKey deviceKey;
194 + private String reason = "";
195 +
196 + public DeviceKeyJsonArrayMatcher(DeviceKey deviceKeyValue) {
197 + deviceKey = deviceKeyValue;
198 + }
199 +
200 + @Override
201 + public boolean matchesSafely(JsonArray json) {
202 + boolean deviceKeyFound = false;
203 + final int expectedAttributes = 5;
204 + for (int jsonDeviceKeyIndex = 0; jsonDeviceKeyIndex < json.size();
205 + jsonDeviceKeyIndex++) {
206 +
207 + final JsonObject jsonHost = json.get(jsonDeviceKeyIndex).asObject();
208 +
209 + // Device keys can have a variable number of attribute so we check
210 + // that there is a minimum number.
211 + if (jsonHost.names().size() < expectedAttributes) {
212 + reason = "Found a device key with the wrong number of attributes";
213 + return false;
214 + }
215 +
216 + final String jsonDeviceKeyId = jsonHost.get(ID).asString();
217 + if (jsonDeviceKeyId.equals(deviceKey.deviceKeyId().id().toString())) {
218 + deviceKeyFound = true;
219 +
220 + // We found the correct device key, check the device key attribute values
221 + assertThat(jsonHost, matchesDeviceKey(deviceKey));
222 + }
223 + }
224 + if (!deviceKeyFound) {
225 + reason = "Device key with id " + deviceKey.deviceKeyId().id().toString() + " was not found";
226 + return false;
227 + } else {
228 + return true;
229 + }
230 + }
231 +
232 + @Override
233 + public void describeTo(Description description) {
234 + description.appendText(reason);
235 + }
236 + }
237 +
238 + /**
239 + * Factory to allocate a device key array matcher.
240 + *
241 + * @param deviceKey device key object we are looking for
242 + * @return matcher
243 + */
244 + private static DeviceKeyJsonArrayMatcher hasDeviceKey(DeviceKey deviceKey) {
245 + return new DeviceKeyJsonArrayMatcher(deviceKey);
246 + }
247 +
248 + /**
249 + * Tests the result of the REST API GET when there are no device keys.
250 + */
251 + @Test
252 + public void testGetDeviceKeysEmptyArray() {
253 + replay(mockDeviceKeyService);
254 + replay(mockDeviceKeyAdminService);
255 +
256 + WebResource rs = resource();
257 + String response = rs.path("keys").get(String.class);
258 + assertThat(response, is("{\"keys\":[]}"));
259 + }
260 +
261 + /**
262 + * Tests the result of the REST API GET when device keys are defined.
263 + */
264 + @Test
265 + public void testGetDeviceKeysArray() {
266 + replay(mockDeviceKeyService);
267 + replay(mockDeviceKeyAdminService);
268 + deviceKeySet.add(deviceKey1);
269 + deviceKeySet.add(deviceKey2);
270 +
271 + WebResource rs = resource();
272 + String response = rs.path("keys").get(String.class);
273 + assertThat(response, containsString("{\"keys\":["));
274 +
275 + final JsonObject result = Json.parse(response).asObject();
276 + assertThat(result, notNullValue());
277 +
278 + assertThat(result.names(), hasSize(1));
279 + assertThat(result.names().get(0), is("keys"));
280 +
281 + final JsonArray deviceKeys = result.get("keys").asArray();
282 + assertThat(deviceKeys, notNullValue());
283 + assertEquals("Device keys array is not the correct size.", 2, deviceKeys.size());
284 +
285 + assertThat(deviceKeys, hasDeviceKey(deviceKey1));
286 + assertThat(deviceKeys, hasDeviceKey(deviceKey2));
287 + }
288 +
289 + /**
290 + * Tests the result of the REST API GET using a device key identifier.
291 + */
292 + @Test
293 + public void testGetDeviceKeyById() {
294 + deviceKeySet.add(deviceKey1);
295 +
296 + expect(mockDeviceKeyService.getDeviceKey(DeviceKeyId.deviceKeyId(deviceKeyId1)))
297 + .andReturn(deviceKey1)
298 + .anyTimes();
299 + replay(mockDeviceKeyService);
300 + replay(mockDeviceKeyAdminService);
301 +
302 + WebResource rs = resource();
303 + String response = rs.path("keys/" + deviceKeyId1).get(String.class);
304 + final JsonObject result = Json.parse(response).asObject();
305 + assertThat(result, notNullValue());
306 +
307 + assertThat(result, matchesDeviceKey(deviceKey1));
308 + }
309 +
310 + /**
311 + * Tests that a GET of a non-existent object throws an exception.
312 + */
313 + @Test
314 + public void testGetNonExistentDeviceKey() {
315 +
316 + expect(mockDeviceKeyService.getDeviceKey(DeviceKeyId.deviceKeyId(deviceKeyId1)))
317 + .andReturn(null)
318 + .anyTimes();
319 + replay(mockDeviceKeyService);
320 + replay(mockDeviceKeyAdminService);
321 +
322 + WebResource rs = resource();
323 + try {
324 + String response = rs.path("keys/" + deviceKeyId1).get(String.class);
325 + fail("GET of a non-existent device key did not throw an exception");
326 + } catch (UniformInterfaceException ex) {
327 + assertThat(ex.getMessage(),
328 + containsString("returned a response status of"));
329 + }
330 + }
331 +
332 + /**
333 + * Tests adding of new device key using POST via JSON stream.
334 + */
335 + @Test
336 + public void testPost() {
337 +
338 + mockDeviceKeyAdminService.addKey(anyObject());
339 + expectLastCall();
340 +
341 + replay(mockDeviceKeyService);
342 + replay(mockDeviceKeyAdminService);
343 +
344 + WebResource rs = resource();
345 + InputStream jsonStream = DeviceKeyWebResourceTest.class
346 + .getResourceAsStream("post-device-key.json");
347 +
348 + ClientResponse response = rs.path("keys")
349 + .type(MediaType.APPLICATION_JSON_TYPE)
350 + .post(ClientResponse.class, jsonStream);
351 + assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
352 +
353 + String location = response.getLocation().getPath();
354 + assertThat(location, Matchers.startsWith("/keys/" + deviceKeyId3));
355 + }
356 +
357 + /**
358 + * Tests adding of a null device key using POST via JSON stream.
359 + */
360 + @Test
361 + public void testPostNullDeviceKey() {
362 +
363 + replay(mockDeviceKeyService);
364 + replay(mockDeviceKeyAdminService);
365 +
366 + WebResource rs = resource();
367 + try {
368 + String response = rs.path("keys")
369 + .type(MediaType.APPLICATION_JSON_TYPE)
370 + .post(String.class);
371 + fail("POST of null device key did not throw an exception");
372 + } catch (UniformInterfaceException ex) {
373 + assertThat(ex.getMessage(),
374 + containsString("returned a response status of"));
375 + }
376 + }
377 +
378 + /**
379 + * Tests removing a device key with DELETE request.
380 + */
381 + @Test
382 + public void testDelete() {
383 + expect(mockDeviceKeyService.getDeviceKey(DeviceKeyId.deviceKeyId(deviceKeyId2)))
384 + .andReturn(deviceKey2)
385 + .anyTimes();
386 + mockDeviceKeyAdminService.removeKey(anyObject());
387 + expectLastCall();
388 +
389 + replay(mockDeviceKeyService);
390 + replay(mockDeviceKeyAdminService);
391 +
392 + WebResource rs = resource();
393 +
394 + ClientResponse response = rs.path("keys/" + deviceKeyId2)
395 + .type(MediaType.APPLICATION_JSON_TYPE)
396 + .delete(ClientResponse.class);
397 + assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));
398 + }
399 +
400 + /**
401 + * Tests that a DELETE of a non-existent device key throws an exception.
402 + */
403 + @Test
404 + public void testDeleteNonExistentDeviceKey() {
405 + expect(mockDeviceKeyService.getDeviceKey(anyObject()))
406 + .andReturn(null)
407 + .anyTimes();
408 +
409 + expectLastCall();
410 +
411 + replay(mockDeviceKeyService);
412 + replay(mockDeviceKeyAdminService);
413 +
414 + WebResource rs = resource();
415 +
416 + try {
417 + String response = rs.path("keys/" + "NON_EXISTENT_DEVICE_KEY")
418 + .delete(String.class);
419 + fail("Delete of a non-existent device key did not throw an exception");
420 + } catch (UniformInterfaceException ex) {
421 + assertThat(ex.getMessage(),
422 + containsString("returned a response status of"));
423 + }
424 + }
425 +}
...\ No newline at end of file ...\ No newline at end of file
1 +{
2 + "id": "DeviceKeyId3",
3 + "type": "USERNAME_PASSWORD",
4 + "label": "DeviceKeyLabel3",
5 + "username": "DeviceKeyUsername3",
6 + "password": "DeviceKeyPassword3"
7 +}