blob: 9581e3a358d34b5c35c21e8ddc1bbdf7cf416ff7 [file] [log] [blame]
Claudine Chiufb8b8162016-04-01 23:50:51 +00001/*
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
17package org.onosproject.rest.resources;
18
19import com.eclipsesource.json.Json;
20import com.eclipsesource.json.JsonArray;
21import com.eclipsesource.json.JsonObject;
22import com.google.common.collect.ImmutableList;
23import com.google.common.collect.ImmutableSet;
24import org.glassfish.jersey.client.ClientProperties;
25import org.hamcrest.Description;
26import org.hamcrest.Matchers;
27import org.hamcrest.TypeSafeMatcher;
28import org.junit.Before;
29import org.junit.Test;
30import org.onlab.osgi.ServiceDirectory;
31import org.onlab.osgi.TestServiceDirectory;
32import org.onlab.rest.BaseResource;
33import org.onosproject.codec.CodecService;
34import org.onosproject.codec.impl.CodecManager;
35import org.onosproject.incubator.net.virtual.DefaultVirtualDevice;
36import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork;
37import org.onosproject.incubator.net.virtual.DefaultVirtualPort;
38import org.onosproject.incubator.net.virtual.NetworkId;
39import org.onosproject.incubator.net.virtual.TenantId;
40import org.onosproject.incubator.net.virtual.VirtualDevice;
41import org.onosproject.incubator.net.virtual.VirtualNetwork;
42import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
43import org.onosproject.incubator.net.virtual.VirtualNetworkService;
44import org.onosproject.incubator.net.virtual.VirtualPort;
45import org.onosproject.net.DefaultAnnotations;
46import org.onosproject.net.DefaultDevice;
47import org.onosproject.net.DefaultPort;
48import org.onosproject.net.Device;
49import org.onosproject.net.DeviceId;
50import org.onosproject.net.NetTestTools;
51import org.onosproject.net.Port;
52import org.onosproject.net.PortNumber;
53
54import javax.ws.rs.BadRequestException;
55import javax.ws.rs.NotFoundException;
56import javax.ws.rs.client.Entity;
57import javax.ws.rs.client.WebTarget;
58import javax.ws.rs.core.MediaType;
59import javax.ws.rs.core.Response;
60import java.io.InputStream;
61import java.net.HttpURLConnection;
62import java.util.HashSet;
63import java.util.List;
64import java.util.function.BiFunction;
65import java.util.function.BiPredicate;
66import java.util.function.Function;
67
68import static org.easymock.EasyMock.*;
69import static org.hamcrest.Matchers.*;
70import static org.junit.Assert.*;
71import static org.onosproject.net.PortNumber.portNumber;
72
73/**
74 * Unit tests for virtual network REST APIs.
75 */
76public class VirtualNetworkWebResourceTest extends ResourceTest {
77
78 private final VirtualNetworkAdminService mockVnetAdminService = createMock(VirtualNetworkAdminService.class);
79 private final VirtualNetworkService mockVnetService = createMock(VirtualNetworkService.class);
80 private CodecManager codecService;
81
82 final HashSet<TenantId> tenantIdSet = new HashSet<>();
83 final HashSet<VirtualNetwork> vnetSet = new HashSet<>();
84 final HashSet<VirtualDevice> vdevSet = new HashSet<>();
85 final HashSet<VirtualPort> vportSet = new HashSet<>();
86
87 private static final String ID = "networkId";
88 private static final String TENANT_ID = "tenantId";
89 private static final String DEVICE_ID = "deviceId";
90 private static final String PORT_NUM = "portNum";
91 private static final String PHYS_DEVICE_ID = "physDeviceId";
92 private static final String PHYS_PORT_NUM = "physPortNum";
93
94 private final TenantId tenantId1 = TenantId.tenantId("TenantId1");
95 private final TenantId tenantId2 = TenantId.tenantId("TenantId2");
96 private final TenantId tenantId3 = TenantId.tenantId("TenantId3");
97 private final TenantId tenantId4 = TenantId.tenantId("TenantId4");
98
99 private final NetworkId networkId1 = NetworkId.networkId(1);
100 private final NetworkId networkId2 = NetworkId.networkId(2);
101 private final NetworkId networkId3 = NetworkId.networkId(3);
102 private final NetworkId networkId4 = NetworkId.networkId(4);
103
104 private final VirtualNetwork vnet1 = new DefaultVirtualNetwork(networkId1, tenantId3);
105 private final VirtualNetwork vnet2 = new DefaultVirtualNetwork(networkId2, tenantId3);
106 private final VirtualNetwork vnet3 = new DefaultVirtualNetwork(networkId3, tenantId3);
107 private final VirtualNetwork vnet4 = new DefaultVirtualNetwork(networkId4, tenantId3);
108
109 private final DeviceId devId1 = DeviceId.deviceId("devId1");
110 private final DeviceId devId2 = DeviceId.deviceId("devId2");
111 private final DeviceId devId22 = DeviceId.deviceId("dev22");
112
113 private final VirtualDevice vdev1 = new DefaultVirtualDevice(networkId3, devId1);
114 private final VirtualDevice vdev2 = new DefaultVirtualDevice(networkId3, devId2);
115
116 private final Device dev1 = NetTestTools.device("dev1");
117 private final Device dev2 = NetTestTools.device("dev2");
118 private final Device dev22 = NetTestTools.device("dev22");
119
120 Port port1 = new DefaultPort(dev1, portNumber(1), true);
121 Port port2 = new DefaultPort(dev2, portNumber(2), true);
122
123 private final VirtualPort vport22 = new DefaultVirtualPort(networkId3,
124 dev22, portNumber(22), port1);
125 private final VirtualPort vport23 = new DefaultVirtualPort(networkId3,
126 dev22, portNumber(23), port2);
127
128 /**
129 * Sets up the global values for all the tests.
130 */
131 @Before
132 public void setUpTest() {
133 // Register the services needed for the test
134 codecService = new CodecManager();
135 codecService.activate();
136 ServiceDirectory testDirectory =
137 new TestServiceDirectory()
138 .add(VirtualNetworkAdminService.class, mockVnetAdminService)
139 .add(VirtualNetworkService.class, mockVnetService)
140 .add(CodecService.class, codecService);
141
142 BaseResource.setServiceDirectory(testDirectory);
143 }
144
145 /**
146 * Hamcrest matcher to check that a virtual network entity representation in JSON matches
147 * the actual virtual network entity.
148 */
149 public static class JsonObjectMatcher<T> extends TypeSafeMatcher<JsonObject> {
150 private final T vnetEntity;
151 private List<String> jsonFieldNames;
152 private String reason = "";
153 private BiFunction<T, String, String> getValue; // get vnetEntity's value
154
155 public JsonObjectMatcher(T vnetEntityValue,
156 List<String> jsonFieldNames1,
157 BiFunction<T, String, String> getValue1) {
158 vnetEntity = vnetEntityValue;
159 jsonFieldNames = jsonFieldNames1;
160 getValue = getValue1;
161 }
162
163 @Override
164 public boolean matchesSafely(JsonObject jsonHost) {
165 return jsonFieldNames
166 .stream()
167 .allMatch(s -> checkField(jsonHost, s, getValue.apply(vnetEntity, s)));
168 }
169
170 private boolean checkField(JsonObject jsonHost, String jsonFieldName,
171 String objectValue) {
172 final String jsonValue = jsonHost.get(jsonFieldName).asString();
173 if (!jsonValue.equals(objectValue)) {
174 reason = jsonFieldName + " " + objectValue;
175 return false;
176 }
177 return true;
178 }
179
180 @Override
181 public void describeTo(Description description) {
182 description.appendText(reason);
183 }
184 }
185
186 /**
187 * Factory to allocate a virtual network id array matcher.
188 *
189 * @param obj virtual network id object we are looking for
190 * @return matcher
191 */
192 /**
193 * Factory to allocate a virtual network entity matcher.
194 *
195 * @param obj virtual network object we are looking for
196 * @param jsonFieldNames JSON field names to check against
197 * @param getValue function to retrieve value from virtual network object
198 * @param <T>
199 * @return JsonObjectMatcher
200 */
201 private static <T> JsonObjectMatcher matchesVnetEntity(T obj, List<String> jsonFieldNames,
202 BiFunction<T, String, String> getValue) {
203 return new JsonObjectMatcher(obj, jsonFieldNames, getValue);
204 }
205
206 /**
207 * Hamcrest matcher to check that a virtual network entity is represented properly in a JSON
208 * array of virtual network entities.
209 */
210 public static class JsonArrayMatcher<T> extends TypeSafeMatcher<JsonArray> {
211 private final T vnetEntity;
212 private String reason = "";
213 private Function<T, String> getKey; // gets vnetEntity's key
214 private BiPredicate<T, JsonObject> checkKey; // check vnetEntity's key with JSON rep'n
215 private List<String> jsonFieldNames; // field/property names
216 private BiFunction<T, String, String> getValue; // get vnetEntity's value
217
218 public JsonArrayMatcher(T vnetEntityValue, Function<T, String> getKey1,
219 BiPredicate<T, JsonObject> checkKey1,
220 List<String> jsonFieldNames1,
221 BiFunction<T, String, String> getValue1) {
222 vnetEntity = vnetEntityValue;
223 getKey = getKey1;
224 checkKey = checkKey1;
225 jsonFieldNames = jsonFieldNames1;
226 getValue = getValue1;
227 }
228
229 @Override
230 public boolean matchesSafely(JsonArray json) {
231 boolean itemFound = false;
232 final int expectedAttributes = jsonFieldNames.size();
233 for (int jsonArrayIndex = 0; jsonArrayIndex < json.size();
234 jsonArrayIndex++) {
235
236 final JsonObject jsonHost = json.get(jsonArrayIndex).asObject();
237
238 if (jsonHost.names().size() < expectedAttributes) {
239 reason = "Found a virtual network with the wrong number of attributes";
240 return false;
241 }
242
243 if (checkKey != null && checkKey.test(vnetEntity, jsonHost)) {
244 itemFound = true;
245 assertThat(jsonHost, matchesVnetEntity(vnetEntity, jsonFieldNames, getValue));
246 }
247 }
248 if (!itemFound) {
249 reason = getKey.apply(vnetEntity) + " was not found";
250 return false;
251 }
252 return true;
253 }
254
255 @Override
256 public void describeTo(Description description) {
257 description.appendText(reason);
258 }
259 }
260
261 /**
262 * Array matcher for VirtualNetwork.
263 */
264 public static class VnetJsonArrayMatcher extends JsonArrayMatcher<VirtualNetwork> {
265
266 public VnetJsonArrayMatcher(VirtualNetwork vnetIn) {
267 super(vnetIn,
268 vnet -> "Virtual network " + vnet.id().toString(),
269 (vnet, jsonObject) -> {
270 return jsonObject.get(ID).asString().equals(vnet.id().toString()); },
271 ImmutableList.of(ID, TENANT_ID),
272 (vnet, s) -> {
273 return s.equals(ID) ? vnet.id().toString()
274 : s.equals(TENANT_ID) ? vnet.tenantId().toString()
275 : null;
276 }
277 );
278 }
279 }
280
281 /**
282 * Factory to allocate a virtual network array matcher.
283 *
284 * @param vnet virtual network object we are looking for
285 * @return matcher
286 */
287 private VnetJsonArrayMatcher hasVnet(VirtualNetwork vnet) {
288 return new VnetJsonArrayMatcher(vnet);
289 }
290
291 // Tests for Virtual Networks
292
293 /**
294 * Tests the result of the REST API GET when there are no virtual networks.
295 */
296 @Test
297 public void testGetVirtualNetworksEmptyArray() {
298 expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of()).anyTimes();
299 replay(mockVnetAdminService);
300 expect(mockVnetService.getVirtualNetworks(tenantId4)).andReturn(ImmutableSet.of()).anyTimes();
301 replay(mockVnetService);
302
303 WebTarget wt = target();
304 String response = wt.path("vnets").request().get(String.class);
305 assertThat(response, is("{\"vnets\":[]}"));
306
307 verify(mockVnetService);
308 verify(mockVnetAdminService);
309 }
310
311 /**
312 * Tests the result of the REST API GET when virtual networks are defined.
313 */
314 @Test
315 public void testGetVirtualNetworksArray() {
316 expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of(tenantId3)).anyTimes();
317 replay(mockVnetAdminService);
318 vnetSet.add(vnet1);
319 vnetSet.add(vnet2);
320 vnetSet.add(vnet3);
321 vnetSet.add(vnet4);
322 expect(mockVnetService.getVirtualNetworks(tenantId3)).andReturn(vnetSet).anyTimes();
323 replay(mockVnetService);
324
325 WebTarget wt = target();
326 String response = wt.path("vnets").request().get(String.class);
327 assertThat(response, containsString("{\"vnets\":["));
328
329 final JsonObject result = Json.parse(response).asObject();
330 assertThat(result, notNullValue());
331
332 assertThat(result.names(), hasSize(1));
333 assertThat(result.names().get(0), is("vnets"));
334
335 final JsonArray vnetJsonArray = result.get("vnets").asArray();
336 assertThat(vnetJsonArray, notNullValue());
337 assertEquals("Virtual networks array is not the correct size.",
338 vnetSet.size(), vnetJsonArray.size());
339
340 vnetSet.forEach(vnet -> assertThat(vnetJsonArray, hasVnet(vnet)));
341
342 verify(mockVnetService);
343 verify(mockVnetAdminService);
344 }
345
346 /**
347 * Tests adding of new virtual network using POST via JSON stream.
348 */
349 @Test
350 public void testPostVirtualNetwork() {
351 expect(mockVnetAdminService.createVirtualNetwork(tenantId2)).andReturn(vnet1);
352 expectLastCall();
353
354 replay(mockVnetAdminService);
355
356 WebTarget wt = target();
357 InputStream jsonStream = TenantWebResourceTest.class
358 .getResourceAsStream("post-tenant.json");
359
360 Response response = wt.path("vnets").request(MediaType.APPLICATION_JSON_TYPE)
361 .post(Entity.json(jsonStream));
362 assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
363
364 String location = response.getLocation().getPath();
365 assertThat(location, Matchers.startsWith("/vnets/" + vnet1.id().toString()));
366
367 verify(mockVnetAdminService);
368 }
369
370 /**
371 * Tests adding of a null virtual network using POST via JSON stream.
372 */
373 @Test
374 public void testPostVirtualNetworkNullTenantId() {
375
376 replay(mockVnetAdminService);
377
378 WebTarget wt = target();
379 try {
380 String response = wt.path("vnets")
381 .request(MediaType.APPLICATION_JSON_TYPE)
382 .post(Entity.json(null), String.class);
383 fail("POST of null virtual network did not throw an exception");
384 } catch (BadRequestException ex) {
385 assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
386 }
387
388 verify(mockVnetAdminService);
389 }
390
391 /**
392 * Tests removing a virtual network with DELETE request.
393 */
394 @Test
395 public void testDeleteVirtualNetwork() {
396 mockVnetAdminService.removeVirtualNetwork(anyObject());
397 expectLastCall();
398 replay(mockVnetAdminService);
399
400 WebTarget wt = target()
401 .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
402 Response response = wt.path("vnets/" + "2")
403 .request(MediaType.APPLICATION_JSON_TYPE)
404 .delete();
405
406 assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));
407
408 verify(mockVnetAdminService);
409 }
410
411 /**
412 * Tests that a DELETE of a non-existent virtual network throws an exception.
413 */
414 @Test
415 public void testDeleteNetworkNonExistentNetworkId() {
416 expect(mockVnetAdminService.getTenantIds())
417 .andReturn(ImmutableSet.of())
418 .anyTimes();
419 expectLastCall();
420
421 replay(mockVnetAdminService);
422
423 WebTarget wt = target();
424
425 try {
426 wt.path("vnets/" + "NON_EXISTENT_NETWORK_ID")
427 .request()
428 .delete(String.class);
429 fail("Delete of a non-existent virtual network did not throw an exception");
430 } catch (NotFoundException ex) {
431 assertThat(ex.getMessage(), containsString("HTTP 404 Not Found"));
432 }
433
434 verify(mockVnetAdminService);
435 }
436
437 // Tests for Virtual Device
438
439 /**
440 * Tests the result of the REST API GET when there are no virtual devices.
441 */
442 @Test
443 public void testGetVirtualDevicesEmptyArray() {
444 NetworkId networkId = networkId4;
445 expect(mockVnetService.getVirtualDevices(networkId)).andReturn(ImmutableSet.of()).anyTimes();
446 replay(mockVnetService);
447
448 WebTarget wt = target();
449 String location = "vnets/" + networkId.toString() + "/devices";
450 String response = wt.path(location).request().get(String.class);
451 assertThat(response, is("{\"devices\":[]}"));
452
453 verify(mockVnetService);
454 }
455
456 /**
457 * Tests the result of the REST API GET when virtual devices are defined.
458 */
459 @Test
460 public void testGetVirtualDevicesArray() {
461 NetworkId networkId = networkId3;
462 vdevSet.add(vdev1);
463 vdevSet.add(vdev2);
464 expect(mockVnetService.getVirtualDevices(networkId)).andReturn(vdevSet).anyTimes();
465 replay(mockVnetService);
466
467 WebTarget wt = target();
468 String location = "vnets/" + networkId.toString() + "/devices";
469 String response = wt.path(location).request().get(String.class);
470 assertThat(response, containsString("{\"devices\":["));
471
472 final JsonObject result = Json.parse(response).asObject();
473 assertThat(result, notNullValue());
474
475 assertThat(result.names(), hasSize(1));
476 assertThat(result.names().get(0), is("devices"));
477
478 final JsonArray vnetJsonArray = result.get("devices").asArray();
479 assertThat(vnetJsonArray, notNullValue());
480 assertEquals("Virtual devices array is not the correct size.",
481 vdevSet.size(), vnetJsonArray.size());
482
483 vdevSet.forEach(vdev -> assertThat(vnetJsonArray, hasVdev(vdev)));
484
485 verify(mockVnetService);
486 }
487
488 /**
489 * Array matcher for VirtualDevice.
490 */
491 public static class VdevJsonArrayMatcher extends JsonArrayMatcher<VirtualDevice> {
492
493 public VdevJsonArrayMatcher(VirtualDevice vdevIn) {
494 super(vdevIn,
495 vdev -> "Virtual device " + vdev.networkId().toString()
496 + " " + vdev.id().toString(),
497 (vdev, jsonObject) -> {
498 return jsonObject.get(ID).asString().equals(vdev.networkId().toString())
499 && jsonObject.get(DEVICE_ID).asString().equals(vdev.id().toString()); },
500 ImmutableList.of(ID, DEVICE_ID),
501 (vdev, s) -> {
502 return s.equals(ID) ? vdev.networkId().toString()
503 : s.equals(DEVICE_ID) ? vdev.id().toString()
504 : null;
505 }
506 );
507 }
508 }
509
510 /**
511 * Factory to allocate a virtual device array matcher.
512 *
513 * @param vdev virtual device object we are looking for
514 * @return matcher
515 */
516 private VdevJsonArrayMatcher hasVdev(VirtualDevice vdev) {
517 return new VdevJsonArrayMatcher(vdev);
518 }
519 /**
520 * Tests adding of new virtual device using POST via JSON stream.
521 */
522 @Test
523 public void testPostVirtualDevice() {
524 NetworkId networkId = networkId3;
525 DeviceId deviceId = devId2;
526 expect(mockVnetAdminService.createVirtualDevice(networkId, deviceId)).andReturn(vdev2);
527 expectLastCall();
528
529 replay(mockVnetAdminService);
530
531 WebTarget wt = target();
532 InputStream jsonStream = VirtualNetworkWebResourceTest.class
533 .getResourceAsStream("post-virtual-device.json");
534 String reqLocation = "vnets/" + networkId.toString() + "/devices";
535 Response response = wt.path(reqLocation).request(MediaType.APPLICATION_JSON_TYPE)
536 .post(Entity.json(jsonStream));
537 assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
538
539 String location = response.getLocation().getPath();
540 assertThat(location, Matchers.startsWith("/" + reqLocation + "/" + vdev2.id().toString()));
541
542 verify(mockVnetAdminService);
543 }
544
545 /**
546 * Tests adding of a null virtual device using POST via JSON stream.
547 */
548 @Test
549 public void testPostVirtualDeviceNullJsonStream() {
550 NetworkId networkId = networkId3;
551 replay(mockVnetAdminService);
552
553 WebTarget wt = target();
554 try {
555 String reqLocation = "vnets/" + networkId.toString() + "/devices";
556 String response = wt.path(reqLocation)
557 .request(MediaType.APPLICATION_JSON_TYPE)
558 .post(Entity.json(null), String.class);
559 fail("POST of null virtual device did not throw an exception");
560 } catch (BadRequestException ex) {
561 assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
562 }
563
564 verify(mockVnetAdminService);
565 }
566
567 /**
568 * Tests removing a virtual device with DELETE request.
569 */
570 @Test
571 public void testDeleteVirtualDevice() {
572 NetworkId networkId = networkId3;
573 DeviceId deviceId = devId2;
574 mockVnetAdminService.removeVirtualDevice(networkId, deviceId);
575 expectLastCall();
576 replay(mockVnetAdminService);
577
578 WebTarget wt = target()
579 .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
580 String reqLocation = "vnets/" + networkId.toString() + "/devices/" + deviceId.toString();
581 Response response = wt.path(reqLocation)
582 .request(MediaType.APPLICATION_JSON_TYPE)
583 .delete();
584
585 assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));
586
587 verify(mockVnetAdminService);
588 }
589
590 // Tests for Virtual Ports
591
592 /**
593 * Tests the result of the REST API GET when there are no virtual ports.
594 */
595 @Test
596 public void testGetVirtualPortsEmptyArray() {
597 NetworkId networkId = networkId4;
598 DeviceId deviceId = devId2;
599 expect(mockVnetService.getVirtualPorts(networkId, deviceId))
600 .andReturn(ImmutableSet.of()).anyTimes();
601 replay(mockVnetService);
602
603 WebTarget wt = target();
604 String location = "vnets/" + networkId.toString()
605 + "/devices/" + deviceId.toString() + "/ports";
606 String response = wt.path(location).request().get(String.class);
607 assertThat(response, is("{\"ports\":[]}"));
608
609 verify(mockVnetService);
610 }
611
612 /**
613 * Tests the result of the REST API GET when virtual ports are defined.
614 */
615 @Test
616 public void testGetVirtualPortsArray() {
617 NetworkId networkId = networkId3;
618 DeviceId deviceId = dev22.id();
619 vportSet.add(vport23);
620 vportSet.add(vport22);
621 expect(mockVnetService.getVirtualPorts(networkId, deviceId)).andReturn(vportSet).anyTimes();
622 replay(mockVnetService);
623
624 WebTarget wt = target();
625 String location = "vnets/" + networkId.toString()
626 + "/devices/" + deviceId.toString() + "/ports";
627 String response = wt.path(location).request().get(String.class);
628 assertThat(response, containsString("{\"ports\":["));
629
630 final JsonObject result = Json.parse(response).asObject();
631 assertThat(result, notNullValue());
632
633 assertThat(result.names(), hasSize(1));
634 assertThat(result.names().get(0), is("ports"));
635
636 final JsonArray vnetJsonArray = result.get("ports").asArray();
637 assertThat(vnetJsonArray, notNullValue());
638 assertEquals("Virtual ports array is not the correct size.",
639 vportSet.size(), vnetJsonArray.size());
640
641 vportSet.forEach(vport -> assertThat(vnetJsonArray, hasVport(vport)));
642
643 verify(mockVnetService);
644 }
645
646 /**
647 * Array matcher for VirtualPort.
648 */
649 public static class VportJsonArrayMatcher extends JsonArrayMatcher<VirtualPort> {
650
651 public VportJsonArrayMatcher(VirtualPort vportIn) {
652 super(vportIn,
653 vport -> "Virtual port " + vport.networkId().toString() + " "
654 + vport.element().id().toString() + " " + vport.number().toString(),
655 (vport, jsonObject) -> {
656 return jsonObject.get(ID).asString().equals(vport.networkId().toString())
657 && jsonObject.get(PORT_NUM).asString().equals(vport.number().toString())
658 && jsonObject.get(DEVICE_ID).asString().equals(vport.element().id().toString()); },
659 ImmutableList.of(ID, DEVICE_ID, PORT_NUM, PHYS_DEVICE_ID, PHYS_PORT_NUM),
660 (vport, s) -> {
661 return s.equals(ID) ? vport.networkId().toString()
662 : s.equals(DEVICE_ID) ? vport.element().id().toString()
663 : s.equals(PORT_NUM) ? vport.number().toString()
664 : s.equals(PHYS_DEVICE_ID) ? vport.realizedBy().element().id().toString()
665 : s.equals(PHYS_PORT_NUM) ? vport.realizedBy().number().toString()
666 : null;
667 }
668 );
669 }
670 }
671
672 /**
673 * Factory to allocate a virtual port array matcher.
674 *
675 * @param vport virtual port object we are looking for
676 * @return matcher
677 */
678 private VportJsonArrayMatcher hasVport(VirtualPort vport) {
679 return new VportJsonArrayMatcher(vport);
680 }
681
682 /**
683 * Tests adding of new virtual port using POST via JSON stream.
684 */
685 @Test
686 public void testPostVirtualPort() {
687 NetworkId networkId = networkId3;
688 DeviceId deviceId = devId22;
689 DefaultAnnotations annotations = DefaultAnnotations.builder().build();
690 Device physDevice = new DefaultDevice(null, DeviceId.deviceId("dev1"),
691 null, null, null, null, null, null, annotations);
692 Port port1 = new DefaultPort(physDevice, portNumber(1), true);
693 expect(mockVnetAdminService.createVirtualPort(networkId, deviceId, portNumber(22), port1))
694 .andReturn(vport22);
695
696 replay(mockVnetAdminService);
697
698 WebTarget wt = target();
699 InputStream jsonStream = VirtualNetworkWebResourceTest.class
700 .getResourceAsStream("post-virtual-port.json");
701 String reqLocation = "vnets/" + networkId.toString()
702 + "/devices/" + deviceId.toString() + "/ports";
703 Response response = wt.path(reqLocation).request(MediaType.APPLICATION_JSON_TYPE)
704 .post(Entity.json(jsonStream));
705 assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
706
707 verify(mockVnetAdminService);
708 }
709
710 /**
711 * Tests adding of a null virtual port using POST via JSON stream.
712 */
713 @Test
714 public void testPostVirtualPortNullJsonStream() {
715 NetworkId networkId = networkId3;
716 DeviceId deviceId = devId2;
717 replay(mockVnetAdminService);
718
719 WebTarget wt = target();
720 try {
721 String reqLocation = "vnets/" + networkId.toString()
722 + "/devices/" + deviceId.toString() + "/ports";
723 String response = wt.path(reqLocation)
724 .request(MediaType.APPLICATION_JSON_TYPE)
725 .post(Entity.json(null), String.class);
726 fail("POST of null virtual port did not throw an exception");
727 } catch (BadRequestException ex) {
728 assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
729 }
730
731 verify(mockVnetAdminService);
732 }
733
734 /**
735 * Tests removing a virtual port with DELETE request.
736 */
737 @Test
738 public void testDeleteVirtualPort() {
739 NetworkId networkId = networkId3;
740 DeviceId deviceId = devId2;
741 PortNumber portNum = portNumber(2);
742 mockVnetAdminService.removeVirtualPort(networkId, deviceId, portNum);
743 expectLastCall();
744 replay(mockVnetAdminService);
745
746 WebTarget wt = target()
747 .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
748 String reqLocation = "vnets/" + networkId.toString()
749 + "/devices/" + deviceId.toString() + "/ports/" + portNum.toLong();
750 Response response = wt.path(reqLocation)
751 .request(MediaType.APPLICATION_JSON_TYPE)
752 .delete();
753
754 assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));
755
756 verify(mockVnetAdminService);
757 }
758
759 // TODO Tests for Virtual Links
760}