blob: b2fbf6064266b4b142269f53b9b0bc6d1f951953 [file] [log] [blame]
Ray Milkey37a5d8c2015-11-23 09:40:57 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Ray Milkey37a5d8c2015-11-23 09:40:57 -08003 *
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 */
16package org.onosproject.rest.resources;
17
Ray Milkey094a1352018-01-22 14:03:54 -080018import com.eclipsesource.json.Json;
19import com.eclipsesource.json.JsonObject;
20import com.eclipsesource.json.JsonValue;
21import com.fasterxml.jackson.databind.JsonNode;
22import com.fasterxml.jackson.databind.ObjectMapper;
23import com.google.common.collect.ImmutableSet;
Ray Milkeyb83797c2017-06-12 15:42:42 -070024import org.eclipse.jetty.http.HttpStatus;
Ray Milkey37a5d8c2015-11-23 09:40:57 -080025import org.junit.Assert;
26import org.junit.Before;
27import org.junit.Test;
28import org.onlab.osgi.ServiceDirectory;
29import org.onlab.osgi.TestServiceDirectory;
Ray Milkey37a5d8c2015-11-23 09:40:57 -080030import org.onosproject.net.DefaultDevice;
31import org.onosproject.net.Device;
32import org.onosproject.net.Link;
33import org.onosproject.net.config.Config;
34import org.onosproject.net.config.NetworkConfigService;
35import org.onosproject.net.config.NetworkConfigServiceAdapter;
36import org.onosproject.net.config.SubjectFactory;
Ray Milkey37a5d8c2015-11-23 09:40:57 -080037
Ray Milkey094a1352018-01-22 14:03:54 -080038import javax.ws.rs.NotFoundException;
39import javax.ws.rs.client.Entity;
40import javax.ws.rs.client.WebTarget;
41import javax.ws.rs.core.MediaType;
42import javax.ws.rs.core.Response;
43import java.io.InputStream;
44import java.net.HttpURLConnection;
45import java.util.HashSet;
46import java.util.Set;
Ray Milkey37a5d8c2015-11-23 09:40:57 -080047
48import static org.easymock.EasyMock.createMock;
49import static org.easymock.EasyMock.replay;
50import static org.hamcrest.MatcherAssert.assertThat;
51import static org.hamcrest.Matchers.containsString;
52import static org.hamcrest.Matchers.hasSize;
53import static org.hamcrest.Matchers.is;
54import static org.hamcrest.Matchers.notNullValue;
55import static org.junit.Assert.fail;
56
57/**
58 * Unit tests for network config web resource.
59 */
60public class NetworkConfigWebResourceTest extends ResourceTest {
61
Ray Milkeyb83797c2017-06-12 15:42:42 -070062 private MockNetworkConfigService mockNetworkConfigService;
Ray Milkey37a5d8c2015-11-23 09:40:57 -080063
64 public class MockDeviceConfig extends Config<Device> {
65
66 final String field1Value;
67 final String field2Value;
68
69 MockDeviceConfig(String value1, String value2) {
70 field1Value = value1;
71 field2Value = value2;
72 }
73
74 @Override
75 public String key() {
76 return "basic";
77 }
78
79 @Override
80 public JsonNode node() {
81 return new ObjectMapper()
82 .createObjectNode()
83 .put("field1", field1Value)
84 .put("field2", field2Value);
85 }
86 }
87
88 /**
89 * Mock config factory for devices.
90 */
91 private final SubjectFactory<Device> mockDevicesSubjectFactory =
92 new SubjectFactory<Device>(Device.class, "devices") {
93 @Override
94 public Device createSubject(String subjectKey) {
95 DefaultDevice device = createMock(DefaultDevice.class);
96 replay(device);
97 return device;
98 }
99
100 @Override
101 public Class<Device> subjectClass() {
102 return Device.class;
103 }
104 };
105
106 /**
107 * Mock config factory for links.
108 */
109 private final SubjectFactory<Link> mockLinksSubjectFactory =
110 new SubjectFactory<Link>(Link.class, "links") {
111 @Override
112 public Link createSubject(String subjectKey) {
113 return null;
114 }
115
116 @Override
117 public Class<Link> subjectClass() {
118 return Link.class;
119 }
120 };
121
122 /**
123 * Mocked config service.
124 */
125 class MockNetworkConfigService extends NetworkConfigServiceAdapter {
126
127 Set devicesSubjects = new HashSet<>();
128 Set devicesConfigs = new HashSet<>();
129 Set linksSubjects = new HashSet();
130 Set linksConfigs = new HashSet<>();
131
132 @Override
133 public Set<Class> getSubjectClasses() {
134 return ImmutableSet.of(Device.class, Link.class);
135 }
136
137 @Override
138 public SubjectFactory getSubjectFactory(Class subjectClass) {
139 if (subjectClass == Device.class) {
140 return mockDevicesSubjectFactory;
141 } else if (subjectClass == Link.class) {
142 return mockLinksSubjectFactory;
143 }
144 return null;
145 }
146
147 @Override
148 public SubjectFactory getSubjectFactory(String subjectClassKey) {
Jon Halla3fcf672017-03-28 16:53:22 -0700149 if ("devices".equals(subjectClassKey)) {
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800150 return mockDevicesSubjectFactory;
Jon Halla3fcf672017-03-28 16:53:22 -0700151 } else if ("links".equals(subjectClassKey)) {
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800152 return mockLinksSubjectFactory;
153 }
154 return null;
155 }
156
157 @SuppressWarnings("unchecked")
158 @Override
159 public <S> Set<S> getSubjects(Class<S> subjectClass) {
160 if (subjectClass == Device.class) {
161 return devicesSubjects;
162 } else if (subjectClass == Link.class) {
163 return linksSubjects;
164 }
165 return null;
166 }
167
168 @SuppressWarnings("unchecked")
169 @Override
170 public <S> Set<? extends Config<S>> getConfigs(S subject) {
171 if (subject instanceof Device || subject.toString().contains("device")) {
172 return devicesConfigs;
173 } else if (subject.toString().contains("link")) {
174 return linksConfigs;
175 }
176 return null;
177 }
178
179 @SuppressWarnings("unchecked")
180 @Override
181 public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
182
183 if (configClass == MockDeviceConfig.class) {
184 return (C) devicesConfigs.toArray()[0];
185 }
186 return null;
187 }
188
189 @Override
190 public Class<? extends Config> getConfigClass(String subjectClassKey, String configKey) {
191 return MockDeviceConfig.class;
192 }
193 }
194
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800195 /**
196 * Sets up mocked config service.
197 */
198 @Before
Jian Li9d616492016-03-09 10:52:49 -0800199 public void setUpMocks() {
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800200 mockNetworkConfigService = new MockNetworkConfigService();
201 ServiceDirectory testDirectory =
202 new TestServiceDirectory()
Thomas Vachuska6f350ed2016-01-08 09:53:03 -0800203 .add(NetworkConfigService.class, mockNetworkConfigService);
Ray Milkey094a1352018-01-22 14:03:54 -0800204 setServiceDirectory(testDirectory);
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800205 }
206
207 /**
208 * Sets up test config data.
209 */
210 @SuppressWarnings("unchecked")
Ray Milkeyb83797c2017-06-12 15:42:42 -0700211 private void setUpConfigData() {
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800212 mockNetworkConfigService.devicesSubjects.add("device1");
213 mockNetworkConfigService.devicesConfigs.add(new MockDeviceConfig("v1", "v2"));
214 }
215
216 /**
217 * Tests the result of the rest api GET when there are no configs.
218 */
219 @Test
220 public void testEmptyConfigs() {
Jian Li9d616492016-03-09 10:52:49 -0800221 final WebTarget wt = target();
222 final String response = wt.path("network/configuration").request().get(String.class);
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800223
224 assertThat(response, containsString("\"devices\":{}"));
225 assertThat(response, containsString("\"links\":{}"));
226 }
227
228 /**
229 * Tests the result of the rest api GET for a single subject with no configs.
230 */
231 @Test
232 public void testEmptyConfig() {
Jian Li9d616492016-03-09 10:52:49 -0800233 final WebTarget wt = target();
234 final String response = wt.path("network/configuration/devices").request().get(String.class);
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800235
236 assertThat(response, is("{}"));
237 }
238
239 /**
240 * Tests the result of the rest api GET for a single subject that
241 * is undefined.
242 */
243 @Test
244 public void testNonExistentConfig() {
Jian Li9d616492016-03-09 10:52:49 -0800245 final WebTarget wt = target();
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800246
247 try {
Jian Li9d616492016-03-09 10:52:49 -0800248 final String response = wt.path("network/configuration/nosuchkey").request().get(String.class);
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800249 fail("GET of non-existent key does not produce an exception " + response);
Jian Li9d616492016-03-09 10:52:49 -0800250 } catch (NotFoundException e) {
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800251 assertThat(e.getResponse().getStatus(), is(HttpURLConnection.HTTP_NOT_FOUND));
252 }
253 }
254
255 private void checkBasicAttributes(JsonValue basic) {
256 Assert.assertThat(basic.asObject().get("field1").asString(), is("v1"));
257 Assert.assertThat(basic.asObject().get("field2").asString(), is("v2"));
258 }
259
260 /**
261 * Tests the result of the rest api GET when there is a config.
262 */
263 @Test
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800264 public void testConfigs() {
265 setUpConfigData();
Jian Li9d616492016-03-09 10:52:49 -0800266 final WebTarget wt = target();
267 final String response = wt.path("network/configuration").request().get(String.class);
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800268
Jian Li80cfe452016-01-14 16:04:58 -0800269 final JsonObject result = Json.parse(response).asObject();
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800270 Assert.assertThat(result, notNullValue());
271
272 Assert.assertThat(result.names(), hasSize(2));
273
274 JsonValue devices = result.get("devices");
275 Assert.assertThat(devices, notNullValue());
276
277 JsonValue device1 = devices.asObject().get("device1");
278 Assert.assertThat(device1, notNullValue());
279
280 JsonValue basic = device1.asObject().get("basic");
281 Assert.assertThat(basic, notNullValue());
282
283 checkBasicAttributes(basic);
284 }
285
286 /**
287 * Tests the result of the rest api single subject key GET when
288 * there is a config.
289 */
290 @Test
291 public void testSingleSubjectKeyConfig() {
292 setUpConfigData();
Jian Li9d616492016-03-09 10:52:49 -0800293 final WebTarget wt = target();
294 final String response = wt.path("network/configuration/devices").request().get(String.class);
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800295
Jian Li80cfe452016-01-14 16:04:58 -0800296 final JsonObject result = Json.parse(response).asObject();
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800297 Assert.assertThat(result, notNullValue());
298
299 Assert.assertThat(result.names(), hasSize(1));
300
301 JsonValue device1 = result.asObject().get("device1");
302 Assert.assertThat(device1, notNullValue());
303
304 JsonValue basic = device1.asObject().get("basic");
305 Assert.assertThat(basic, notNullValue());
306
307 checkBasicAttributes(basic);
308 }
309
310 /**
311 * Tests the result of the rest api single subject GET when
312 * there is a config.
313 */
314 @Test
315 public void testSingleSubjectConfig() {
316 setUpConfigData();
Jian Li9d616492016-03-09 10:52:49 -0800317 final WebTarget wt = target();
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800318 final String response =
Jian Li9d616492016-03-09 10:52:49 -0800319 wt.path("network/configuration/devices/device1")
320 .request()
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800321 .get(String.class);
322
Jian Li80cfe452016-01-14 16:04:58 -0800323 final JsonObject result = Json.parse(response).asObject();
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800324 Assert.assertThat(result, notNullValue());
325
326 Assert.assertThat(result.names(), hasSize(1));
327
328 JsonValue basic = result.asObject().get("basic");
329 Assert.assertThat(basic, notNullValue());
330
331 checkBasicAttributes(basic);
332 }
333
334 /**
335 * Tests the result of the rest api single subject single config GET when
336 * there is a config.
337 */
338 @Test
339 public void testSingleSubjectSingleConfig() {
340 setUpConfigData();
Jian Li9d616492016-03-09 10:52:49 -0800341 final WebTarget wt = target();
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800342 final String response =
Jian Li9d616492016-03-09 10:52:49 -0800343 wt.path("network/configuration/devices/device1/basic")
344 .request()
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800345 .get(String.class);
346
Jian Li80cfe452016-01-14 16:04:58 -0800347 final JsonObject result = Json.parse(response).asObject();
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800348 Assert.assertThat(result, notNullValue());
349
350 Assert.assertThat(result.names(), hasSize(2));
351
352 checkBasicAttributes(result);
353 }
354
Ray Milkeyb83797c2017-06-12 15:42:42 -0700355 /**
356 * Tests network configuration with POST and illegal JSON.
357 */
358 @Test
359 public void testBadPost() {
360 String json = "this is invalid!";
361 WebTarget wt = target();
362
363 Response response = wt.path("network/configuration")
364 .request(MediaType.APPLICATION_JSON_TYPE)
365 .post(Entity.json(json));
366 Assert.assertThat(response.getStatus(), is(HttpURLConnection.HTTP_BAD_REQUEST));
367 }
368
369 /**
370 * Tests creating a network config with POST.
371 */
372 @Test
373 public void testPost() {
374 InputStream jsonStream = IntentsResourceTest.class
375 .getResourceAsStream("post-config.json");
376 WebTarget wt = target();
377
378 Response response = wt.path("network/configuration")
379 .request(MediaType.APPLICATION_JSON_TYPE)
380 .post(Entity.json(jsonStream));
381 Assert.assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));
382 }
383
384 /**
385 * Tests creating a network config with POST of valid but incorrect JSON.
386 */
387 @Test
388 public void testBadSyntaxPost() {
389 InputStream jsonStream = IntentsResourceTest.class
390 .getResourceAsStream("post-config-bad-syntax.json");
391 WebTarget wt = target();
392
393 Response response = wt.path("network/configuration")
394 .request(MediaType.APPLICATION_JSON_TYPE)
395 .post(Entity.json(jsonStream));
396 Assert.assertThat(response.getStatus(), is(HttpStatus.MULTI_STATUS_207));
397 }
398
399 // TODO: Add test for DELETE
Ray Milkey37a5d8c2015-11-23 09:40:57 -0800400}