blob: 99ab65665c65aac6fe65c502fef688a617e8c1d8 [file] [log] [blame]
Claudine Chiufb8b8162016-04-01 23:50:51 +00001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Claudine Chiufb8b8162016-04-01 23:50:51 +00003 *
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;
Claudine Chiu25f07be2016-06-27 16:21:21 +000024import com.google.common.collect.Sets;
Claudine Chiufb8b8162016-04-01 23:50:51 +000025import org.glassfish.jersey.client.ClientProperties;
26import org.hamcrest.Description;
27import org.hamcrest.Matchers;
28import org.hamcrest.TypeSafeMatcher;
29import org.junit.Before;
30import org.junit.Test;
31import org.onlab.osgi.ServiceDirectory;
32import org.onlab.osgi.TestServiceDirectory;
Claudine Chiu25f07be2016-06-27 16:21:21 +000033import org.onlab.packet.IpAddress;
34import org.onlab.packet.MacAddress;
35import org.onlab.packet.VlanId;
Claudine Chiufb8b8162016-04-01 23:50:51 +000036import org.onlab.rest.BaseResource;
37import org.onosproject.codec.CodecService;
38import org.onosproject.codec.impl.CodecManager;
39import org.onosproject.incubator.net.virtual.DefaultVirtualDevice;
Claudine Chiu25f07be2016-06-27 16:21:21 +000040import org.onosproject.incubator.net.virtual.DefaultVirtualHost;
Claudine Chiuf6bf8d52016-04-08 01:31:54 +000041import org.onosproject.incubator.net.virtual.DefaultVirtualLink;
Claudine Chiufb8b8162016-04-01 23:50:51 +000042import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork;
43import org.onosproject.incubator.net.virtual.DefaultVirtualPort;
44import org.onosproject.incubator.net.virtual.NetworkId;
45import org.onosproject.incubator.net.virtual.TenantId;
46import org.onosproject.incubator.net.virtual.VirtualDevice;
Claudine Chiu25f07be2016-06-27 16:21:21 +000047import org.onosproject.incubator.net.virtual.VirtualHost;
Claudine Chiuf6bf8d52016-04-08 01:31:54 +000048import org.onosproject.incubator.net.virtual.VirtualLink;
Claudine Chiufb8b8162016-04-01 23:50:51 +000049import org.onosproject.incubator.net.virtual.VirtualNetwork;
50import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
51import org.onosproject.incubator.net.virtual.VirtualNetworkService;
52import org.onosproject.incubator.net.virtual.VirtualPort;
Claudine Chiuf6bf8d52016-04-08 01:31:54 +000053import org.onosproject.net.ConnectPoint;
Claudine Chiufb8b8162016-04-01 23:50:51 +000054import org.onosproject.net.DefaultAnnotations;
55import org.onosproject.net.DefaultDevice;
Claudine Chiufb8b8162016-04-01 23:50:51 +000056import org.onosproject.net.Device;
57import org.onosproject.net.DeviceId;
Claudine Chiu25f07be2016-06-27 16:21:21 +000058import org.onosproject.net.HostId;
59import org.onosproject.net.HostLocation;
Claudine Chiufb8b8162016-04-01 23:50:51 +000060import org.onosproject.net.NetTestTools;
Claudine Chiufb8b8162016-04-01 23:50:51 +000061import org.onosproject.net.PortNumber;
62
63import javax.ws.rs.BadRequestException;
64import javax.ws.rs.NotFoundException;
65import javax.ws.rs.client.Entity;
66import javax.ws.rs.client.WebTarget;
67import javax.ws.rs.core.MediaType;
68import javax.ws.rs.core.Response;
69import java.io.InputStream;
70import java.net.HttpURLConnection;
71import java.util.HashSet;
72import java.util.List;
Claudine Chiuf6bf8d52016-04-08 01:31:54 +000073import java.util.Set;
Claudine Chiufb8b8162016-04-01 23:50:51 +000074import java.util.function.BiFunction;
75import java.util.function.BiPredicate;
76import java.util.function.Function;
77
Yoonseon Han6c603892016-09-01 11:52:21 -070078import static org.easymock.EasyMock.*;
79import static org.hamcrest.Matchers.*;
Jian Li08d65cf2016-04-20 10:07:17 -070080import static org.junit.Assert.assertEquals;
81import static org.junit.Assert.assertThat;
82import static org.junit.Assert.fail;
Claudine Chiufb8b8162016-04-01 23:50:51 +000083import static org.onosproject.net.PortNumber.portNumber;
84
85/**
86 * Unit tests for virtual network REST APIs.
87 */
88public class VirtualNetworkWebResourceTest extends ResourceTest {
89
90 private final VirtualNetworkAdminService mockVnetAdminService = createMock(VirtualNetworkAdminService.class);
91 private final VirtualNetworkService mockVnetService = createMock(VirtualNetworkService.class);
92 private CodecManager codecService;
93
Claudine Chiu25f07be2016-06-27 16:21:21 +000094 private final HashSet<VirtualDevice> vdevSet = new HashSet<>();
95 private final HashSet<VirtualPort> vportSet = new HashSet<>();
Claudine Chiufb8b8162016-04-01 23:50:51 +000096
97 private static final String ID = "networkId";
98 private static final String TENANT_ID = "tenantId";
99 private static final String DEVICE_ID = "deviceId";
100 private static final String PORT_NUM = "portNum";
101 private static final String PHYS_DEVICE_ID = "physDeviceId";
102 private static final String PHYS_PORT_NUM = "physPortNum";
103
Claudine Chiufb8b8162016-04-01 23:50:51 +0000104 private final TenantId tenantId2 = TenantId.tenantId("TenantId2");
105 private final TenantId tenantId3 = TenantId.tenantId("TenantId3");
106 private final TenantId tenantId4 = TenantId.tenantId("TenantId4");
107
108 private final NetworkId networkId1 = NetworkId.networkId(1);
109 private final NetworkId networkId2 = NetworkId.networkId(2);
110 private final NetworkId networkId3 = NetworkId.networkId(3);
111 private final NetworkId networkId4 = NetworkId.networkId(4);
112
113 private final VirtualNetwork vnet1 = new DefaultVirtualNetwork(networkId1, tenantId3);
114 private final VirtualNetwork vnet2 = new DefaultVirtualNetwork(networkId2, tenantId3);
115 private final VirtualNetwork vnet3 = new DefaultVirtualNetwork(networkId3, tenantId3);
116 private final VirtualNetwork vnet4 = new DefaultVirtualNetwork(networkId4, tenantId3);
117
Claudine Chiuf6bf8d52016-04-08 01:31:54 +0000118 private final DeviceId devId1 = DeviceId.deviceId("devid1");
119 private final DeviceId devId2 = DeviceId.deviceId("devid2");
Claudine Chiufb8b8162016-04-01 23:50:51 +0000120 private final DeviceId devId22 = DeviceId.deviceId("dev22");
121
122 private final VirtualDevice vdev1 = new DefaultVirtualDevice(networkId3, devId1);
123 private final VirtualDevice vdev2 = new DefaultVirtualDevice(networkId3, devId2);
124
125 private final Device dev1 = NetTestTools.device("dev1");
126 private final Device dev2 = NetTestTools.device("dev2");
127 private final Device dev22 = NetTestTools.device("dev22");
128
Yoonseon Han6c603892016-09-01 11:52:21 -0700129 private final ConnectPoint cp1 = new ConnectPoint(dev1.id(), portNumber(1));
130 private final ConnectPoint cp2 = new ConnectPoint(dev2.id(), portNumber(2));
Claudine Chiufb8b8162016-04-01 23:50:51 +0000131
132 private final VirtualPort vport22 = new DefaultVirtualPort(networkId3,
Yoonseon Han6c603892016-09-01 11:52:21 -0700133 dev22, portNumber(22), cp1);
Claudine Chiufb8b8162016-04-01 23:50:51 +0000134 private final VirtualPort vport23 = new DefaultVirtualPort(networkId3,
Yoonseon Han6c603892016-09-01 11:52:21 -0700135 dev22, portNumber(23), cp2);
Claudine Chiufb8b8162016-04-01 23:50:51 +0000136
Claudine Chiuf6bf8d52016-04-08 01:31:54 +0000137 private final ConnectPoint cp11 = NetTestTools.connectPoint(devId1.toString(), 21);
138 private final ConnectPoint cp21 = NetTestTools.connectPoint(devId2.toString(), 22);
139 private final ConnectPoint cp12 = NetTestTools.connectPoint(devId1.toString(), 2);
140 private final ConnectPoint cp22 = NetTestTools.connectPoint(devId2.toString(), 22);
141
Brian Stanke9a108972016-04-11 15:25:17 -0400142 private final VirtualLink vlink1 = DefaultVirtualLink.builder()
143 .networkId(networkId3)
144 .src(cp22)
145 .dst(cp11)
146 .build();
147
148 private final VirtualLink vlink2 = DefaultVirtualLink.builder()
149 .networkId(networkId3)
150 .src(cp12)
151 .dst(cp21)
152 .build();
Claudine Chiuf6bf8d52016-04-08 01:31:54 +0000153
Claudine Chiu25f07be2016-06-27 16:21:21 +0000154 private final MacAddress mac1 = MacAddress.valueOf("00:11:00:00:00:01");
155 private final MacAddress mac2 = MacAddress.valueOf("00:22:00:00:00:02");
156 private final VlanId vlan1 = VlanId.vlanId((short) 11);
157 private final VlanId vlan2 = VlanId.vlanId((short) 22);
158 private final IpAddress ip1 = IpAddress.valueOf("10.0.0.1");
159 private final IpAddress ip2 = IpAddress.valueOf("10.0.0.2");
160 private final IpAddress ip3 = IpAddress.valueOf("10.0.0.3");
161
162 private final HostId hId1 = HostId.hostId(mac1, vlan1);
163 private final HostId hId2 = HostId.hostId(mac2, vlan2);
164 private final HostLocation loc1 = new HostLocation(devId1, portNumber(100), 123L);
165 private final HostLocation loc2 = new HostLocation(devId2, portNumber(200), 123L);
166 private final Set<IpAddress> ipSet1 = Sets.newHashSet(ip1, ip2);
167 private final Set<IpAddress> ipSet2 = Sets.newHashSet(ip1, ip3);
168 private final VirtualHost vhost1 = new DefaultVirtualHost(networkId1, hId1,
169 mac1, vlan1, loc1, ipSet1);
170 private final VirtualHost vhost2 = new DefaultVirtualHost(networkId2, hId2,
171 mac2, vlan2, loc2, ipSet2);
172
173
174
175
Claudine Chiufb8b8162016-04-01 23:50:51 +0000176 /**
177 * Sets up the global values for all the tests.
178 */
179 @Before
180 public void setUpTest() {
181 // Register the services needed for the test
182 codecService = new CodecManager();
183 codecService.activate();
184 ServiceDirectory testDirectory =
185 new TestServiceDirectory()
186 .add(VirtualNetworkAdminService.class, mockVnetAdminService)
187 .add(VirtualNetworkService.class, mockVnetService)
188 .add(CodecService.class, codecService);
189
190 BaseResource.setServiceDirectory(testDirectory);
191 }
192
193 /**
194 * Hamcrest matcher to check that a virtual network entity representation in JSON matches
195 * the actual virtual network entity.
196 */
Claudine Chiu25f07be2016-06-27 16:21:21 +0000197 private static final class JsonObjectMatcher<T> extends TypeSafeMatcher<JsonObject> {
Claudine Chiufb8b8162016-04-01 23:50:51 +0000198 private final T vnetEntity;
199 private List<String> jsonFieldNames;
200 private String reason = "";
201 private BiFunction<T, String, String> getValue; // get vnetEntity's value
202
Claudine Chiu25f07be2016-06-27 16:21:21 +0000203 private JsonObjectMatcher(T vnetEntityValue,
204 List<String> jsonFieldNames1,
205 BiFunction<T, String, String> getValue1) {
Claudine Chiufb8b8162016-04-01 23:50:51 +0000206 vnetEntity = vnetEntityValue;
207 jsonFieldNames = jsonFieldNames1;
208 getValue = getValue1;
209 }
210
211 @Override
212 public boolean matchesSafely(JsonObject jsonHost) {
213 return jsonFieldNames
214 .stream()
215 .allMatch(s -> checkField(jsonHost, s, getValue.apply(vnetEntity, s)));
216 }
217
218 private boolean checkField(JsonObject jsonHost, String jsonFieldName,
219 String objectValue) {
220 final String jsonValue = jsonHost.get(jsonFieldName).asString();
221 if (!jsonValue.equals(objectValue)) {
222 reason = jsonFieldName + " " + objectValue;
223 return false;
224 }
225 return true;
226 }
227
228 @Override
229 public void describeTo(Description description) {
230 description.appendText(reason);
231 }
232 }
233
234 /**
235 * Factory to allocate a virtual network id array matcher.
236 *
237 * @param obj virtual network id object we are looking for
238 * @return matcher
239 */
240 /**
241 * Factory to allocate a virtual network entity matcher.
242 *
Brian Stanke9a108972016-04-11 15:25:17 -0400243 * @param obj virtual network object we are looking for
Claudine Chiufb8b8162016-04-01 23:50:51 +0000244 * @param jsonFieldNames JSON field names to check against
Brian Stanke9a108972016-04-11 15:25:17 -0400245 * @param getValue function to retrieve value from virtual network object
Claudine Chiua98c2ea2016-04-19 16:09:18 +0000246 * @param <T> the type of virtual network object
247 * @return matcher
Claudine Chiufb8b8162016-04-01 23:50:51 +0000248 */
249 private static <T> JsonObjectMatcher matchesVnetEntity(T obj, List<String> jsonFieldNames,
Brian Stanke9a108972016-04-11 15:25:17 -0400250 BiFunction<T, String, String> getValue) {
Claudine Chiua98c2ea2016-04-19 16:09:18 +0000251 return new JsonObjectMatcher<T>(obj, jsonFieldNames, getValue);
Claudine Chiufb8b8162016-04-01 23:50:51 +0000252 }
253
254 /**
255 * Hamcrest matcher to check that a virtual network entity is represented properly in a JSON
256 * array of virtual network entities.
257 */
Claudine Chiu25f07be2016-06-27 16:21:21 +0000258 protected static class JsonArrayMatcher<T> extends TypeSafeMatcher<JsonArray> {
Claudine Chiufb8b8162016-04-01 23:50:51 +0000259 private final T vnetEntity;
260 private String reason = "";
261 private Function<T, String> getKey; // gets vnetEntity's key
262 private BiPredicate<T, JsonObject> checkKey; // check vnetEntity's key with JSON rep'n
263 private List<String> jsonFieldNames; // field/property names
264 private BiFunction<T, String, String> getValue; // get vnetEntity's value
265
Claudine Chiu25f07be2016-06-27 16:21:21 +0000266 protected JsonArrayMatcher(T vnetEntityValue, Function<T, String> getKey1,
267 BiPredicate<T, JsonObject> checkKey1,
268 List<String> jsonFieldNames1,
269 BiFunction<T, String, String> getValue1) {
Claudine Chiufb8b8162016-04-01 23:50:51 +0000270 vnetEntity = vnetEntityValue;
271 getKey = getKey1;
272 checkKey = checkKey1;
273 jsonFieldNames = jsonFieldNames1;
274 getValue = getValue1;
275 }
276
277 @Override
278 public boolean matchesSafely(JsonArray json) {
279 boolean itemFound = false;
280 final int expectedAttributes = jsonFieldNames.size();
281 for (int jsonArrayIndex = 0; jsonArrayIndex < json.size();
282 jsonArrayIndex++) {
283
284 final JsonObject jsonHost = json.get(jsonArrayIndex).asObject();
285
286 if (jsonHost.names().size() < expectedAttributes) {
287 reason = "Found a virtual network with the wrong number of attributes";
288 return false;
289 }
290
291 if (checkKey != null && checkKey.test(vnetEntity, jsonHost)) {
292 itemFound = true;
293 assertThat(jsonHost, matchesVnetEntity(vnetEntity, jsonFieldNames, getValue));
294 }
295 }
296 if (!itemFound) {
297 reason = getKey.apply(vnetEntity) + " was not found";
298 return false;
299 }
300 return true;
301 }
302
303 @Override
304 public void describeTo(Description description) {
305 description.appendText(reason);
306 }
307 }
308
309 /**
310 * Array matcher for VirtualNetwork.
311 */
Claudine Chiu25f07be2016-06-27 16:21:21 +0000312 private static final class VnetJsonArrayMatcher extends JsonArrayMatcher<VirtualNetwork> {
Claudine Chiufb8b8162016-04-01 23:50:51 +0000313
Claudine Chiu25f07be2016-06-27 16:21:21 +0000314 private VnetJsonArrayMatcher(VirtualNetwork vnetIn) {
Claudine Chiufb8b8162016-04-01 23:50:51 +0000315 super(vnetIn,
316 vnet -> "Virtual network " + vnet.id().toString(),
Jian Li08d65cf2016-04-20 10:07:17 -0700317 (vnet, jsonObject) -> jsonObject.get(ID).asString().equals(vnet.id().toString()),
Claudine Chiufb8b8162016-04-01 23:50:51 +0000318 ImmutableList.of(ID, TENANT_ID),
Jian Li08d65cf2016-04-20 10:07:17 -0700319 (vnet, s) -> s.equals(ID) ? vnet.id().toString()
320 : s.equals(TENANT_ID) ? vnet.tenantId().toString()
321 : null
Claudine Chiufb8b8162016-04-01 23:50:51 +0000322 );
323 }
324 }
325
326 /**
327 * Factory to allocate a virtual network array matcher.
328 *
329 * @param vnet virtual network object we are looking for
330 * @return matcher
331 */
332 private VnetJsonArrayMatcher hasVnet(VirtualNetwork vnet) {
333 return new VnetJsonArrayMatcher(vnet);
334 }
335
336 // Tests for Virtual Networks
337
338 /**
339 * Tests the result of the REST API GET when there are no virtual networks.
340 */
341 @Test
342 public void testGetVirtualNetworksEmptyArray() {
343 expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of()).anyTimes();
344 replay(mockVnetAdminService);
345 expect(mockVnetService.getVirtualNetworks(tenantId4)).andReturn(ImmutableSet.of()).anyTimes();
346 replay(mockVnetService);
347
348 WebTarget wt = target();
349 String response = wt.path("vnets").request().get(String.class);
350 assertThat(response, is("{\"vnets\":[]}"));
351
352 verify(mockVnetService);
353 verify(mockVnetAdminService);
354 }
355
356 /**
357 * Tests the result of the REST API GET when virtual networks are defined.
358 */
359 @Test
360 public void testGetVirtualNetworksArray() {
Claudine Chiuf6bf8d52016-04-08 01:31:54 +0000361 final Set<VirtualNetwork> vnetSet = ImmutableSet.of(vnet1, vnet2, vnet3, vnet4);
Claudine Chiufb8b8162016-04-01 23:50:51 +0000362 expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of(tenantId3)).anyTimes();
363 replay(mockVnetAdminService);
Claudine Chiufb8b8162016-04-01 23:50:51 +0000364 expect(mockVnetService.getVirtualNetworks(tenantId3)).andReturn(vnetSet).anyTimes();
365 replay(mockVnetService);
366
367 WebTarget wt = target();
368 String response = wt.path("vnets").request().get(String.class);
369 assertThat(response, containsString("{\"vnets\":["));
370
371 final JsonObject result = Json.parse(response).asObject();
372 assertThat(result, notNullValue());
373
374 assertThat(result.names(), hasSize(1));
375 assertThat(result.names().get(0), is("vnets"));
376
377 final JsonArray vnetJsonArray = result.get("vnets").asArray();
378 assertThat(vnetJsonArray, notNullValue());
379 assertEquals("Virtual networks array is not the correct size.",
380 vnetSet.size(), vnetJsonArray.size());
381
382 vnetSet.forEach(vnet -> assertThat(vnetJsonArray, hasVnet(vnet)));
383
384 verify(mockVnetService);
385 verify(mockVnetAdminService);
386 }
387
388 /**
Claudine Chiuf6bf8d52016-04-08 01:31:54 +0000389 * Tests the result of the REST API GET for virtual networks with tenant id.
390 */
391 @Test
392 public void testGetVirtualNetworksByTenantId() {
393 final Set<VirtualNetwork> vnetSet = ImmutableSet.of(vnet1, vnet2, vnet3, vnet4);
394 expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of(tenantId3)).anyTimes();
395 replay(mockVnetAdminService);
396 expect(mockVnetService.getVirtualNetworks(tenantId3)).andReturn(vnetSet).anyTimes();
397 replay(mockVnetService);
398
399 WebTarget wt = target();
400 String response = wt.path("vnets/" + tenantId3.id()).request().get(String.class);
401 assertThat(response, containsString("{\"vnets\":["));
402
403 final JsonObject result = Json.parse(response).asObject();
404 assertThat(result, notNullValue());
405
406 assertThat(result.names(), hasSize(1));
407 assertThat(result.names().get(0), is("vnets"));
408
409 final JsonArray vnetJsonArray = result.get("vnets").asArray();
410 assertThat(vnetJsonArray, notNullValue());
411 assertEquals("Virtual networks array is not the correct size.",
412 vnetSet.size(), vnetJsonArray.size());
413
414 vnetSet.forEach(vnet -> assertThat(vnetJsonArray, hasVnet(vnet)));
415
416 verify(mockVnetService);
417 verify(mockVnetAdminService);
418 }
419
420 /**
421 * Tests the result of the REST API GET for virtual networks with tenant id.
422 */
423 @Test
424 public void testGetVirtualNetworksByNonExistentTenantId() {
425 String tenantIdName = "NON_EXISTENT_TENANT_ID";
426 expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of(tenantId3)).anyTimes();
427 replay(mockVnetAdminService);
428 expect(mockVnetService.getVirtualNetworks(anyObject())).andReturn(ImmutableSet.of()).anyTimes();
429 replay(mockVnetService);
430
431 WebTarget wt = target();
432
433 try {
434 wt.path("vnets/" + tenantIdName)
435 .request()
436 .get(String.class);
437 fail("Get of a non-existent virtual network did not throw an exception");
438 } catch (NotFoundException ex) {
439 assertThat(ex.getMessage(), containsString("HTTP 404 Not Found"));
440 }
441
442 verify(mockVnetService);
443 verify(mockVnetAdminService);
444 }
445
446 /**
Claudine Chiufb8b8162016-04-01 23:50:51 +0000447 * Tests adding of new virtual network using POST via JSON stream.
448 */
449 @Test
450 public void testPostVirtualNetwork() {
451 expect(mockVnetAdminService.createVirtualNetwork(tenantId2)).andReturn(vnet1);
452 expectLastCall();
453
454 replay(mockVnetAdminService);
455
456 WebTarget wt = target();
457 InputStream jsonStream = TenantWebResourceTest.class
458 .getResourceAsStream("post-tenant.json");
459
460 Response response = wt.path("vnets").request(MediaType.APPLICATION_JSON_TYPE)
461 .post(Entity.json(jsonStream));
462 assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
463
464 String location = response.getLocation().getPath();
465 assertThat(location, Matchers.startsWith("/vnets/" + vnet1.id().toString()));
466
467 verify(mockVnetAdminService);
468 }
469
470 /**
471 * Tests adding of a null virtual network using POST via JSON stream.
472 */
473 @Test
474 public void testPostVirtualNetworkNullTenantId() {
475
476 replay(mockVnetAdminService);
477
478 WebTarget wt = target();
479 try {
Jian Li08d65cf2016-04-20 10:07:17 -0700480 wt.path("vnets")
Claudine Chiufb8b8162016-04-01 23:50:51 +0000481 .request(MediaType.APPLICATION_JSON_TYPE)
482 .post(Entity.json(null), String.class);
483 fail("POST of null virtual network did not throw an exception");
484 } catch (BadRequestException ex) {
485 assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
486 }
487
488 verify(mockVnetAdminService);
489 }
490
491 /**
492 * Tests removing a virtual network with DELETE request.
493 */
494 @Test
495 public void testDeleteVirtualNetwork() {
496 mockVnetAdminService.removeVirtualNetwork(anyObject());
497 expectLastCall();
498 replay(mockVnetAdminService);
499
500 WebTarget wt = target()
501 .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
502 Response response = wt.path("vnets/" + "2")
503 .request(MediaType.APPLICATION_JSON_TYPE)
504 .delete();
505
Jian Lic2a542b2016-05-10 11:48:19 -0700506 assertThat(response.getStatus(), is(HttpURLConnection.HTTP_NO_CONTENT));
Claudine Chiufb8b8162016-04-01 23:50:51 +0000507
508 verify(mockVnetAdminService);
509 }
510
511 /**
512 * Tests that a DELETE of a non-existent virtual network throws an exception.
513 */
514 @Test
515 public void testDeleteNetworkNonExistentNetworkId() {
516 expect(mockVnetAdminService.getTenantIds())
517 .andReturn(ImmutableSet.of())
518 .anyTimes();
519 expectLastCall();
520
521 replay(mockVnetAdminService);
522
523 WebTarget wt = target();
524
525 try {
526 wt.path("vnets/" + "NON_EXISTENT_NETWORK_ID")
527 .request()
528 .delete(String.class);
529 fail("Delete of a non-existent virtual network did not throw an exception");
530 } catch (NotFoundException ex) {
531 assertThat(ex.getMessage(), containsString("HTTP 404 Not Found"));
532 }
533
534 verify(mockVnetAdminService);
535 }
536
537 // Tests for Virtual Device
538
539 /**
540 * Tests the result of the REST API GET when there are no virtual devices.
541 */
542 @Test
543 public void testGetVirtualDevicesEmptyArray() {
544 NetworkId networkId = networkId4;
545 expect(mockVnetService.getVirtualDevices(networkId)).andReturn(ImmutableSet.of()).anyTimes();
546 replay(mockVnetService);
547
548 WebTarget wt = target();
549 String location = "vnets/" + networkId.toString() + "/devices";
550 String response = wt.path(location).request().get(String.class);
551 assertThat(response, is("{\"devices\":[]}"));
552
553 verify(mockVnetService);
554 }
555
556 /**
557 * Tests the result of the REST API GET when virtual devices are defined.
558 */
559 @Test
560 public void testGetVirtualDevicesArray() {
561 NetworkId networkId = networkId3;
562 vdevSet.add(vdev1);
563 vdevSet.add(vdev2);
564 expect(mockVnetService.getVirtualDevices(networkId)).andReturn(vdevSet).anyTimes();
565 replay(mockVnetService);
566
567 WebTarget wt = target();
568 String location = "vnets/" + networkId.toString() + "/devices";
569 String response = wt.path(location).request().get(String.class);
570 assertThat(response, containsString("{\"devices\":["));
571
572 final JsonObject result = Json.parse(response).asObject();
573 assertThat(result, notNullValue());
574
575 assertThat(result.names(), hasSize(1));
576 assertThat(result.names().get(0), is("devices"));
577
578 final JsonArray vnetJsonArray = result.get("devices").asArray();
579 assertThat(vnetJsonArray, notNullValue());
580 assertEquals("Virtual devices array is not the correct size.",
581 vdevSet.size(), vnetJsonArray.size());
582
583 vdevSet.forEach(vdev -> assertThat(vnetJsonArray, hasVdev(vdev)));
584
585 verify(mockVnetService);
586 }
587
588 /**
589 * Array matcher for VirtualDevice.
590 */
Claudine Chiu25f07be2016-06-27 16:21:21 +0000591 private static final class VdevJsonArrayMatcher extends JsonArrayMatcher<VirtualDevice> {
Claudine Chiufb8b8162016-04-01 23:50:51 +0000592
Claudine Chiu25f07be2016-06-27 16:21:21 +0000593 private VdevJsonArrayMatcher(VirtualDevice vdevIn) {
Claudine Chiufb8b8162016-04-01 23:50:51 +0000594 super(vdevIn,
595 vdev -> "Virtual device " + vdev.networkId().toString()
596 + " " + vdev.id().toString(),
Jian Li08d65cf2016-04-20 10:07:17 -0700597 (vdev, jsonObject) -> jsonObject.get(ID).asString().equals(vdev.networkId().toString())
598 && jsonObject.get(DEVICE_ID).asString().equals(vdev.id().toString()),
Claudine Chiufb8b8162016-04-01 23:50:51 +0000599 ImmutableList.of(ID, DEVICE_ID),
Jian Li08d65cf2016-04-20 10:07:17 -0700600 (vdev, s) -> s.equals(ID) ? vdev.networkId().toString()
601 : s.equals(DEVICE_ID) ? vdev.id().toString()
602 : null
Claudine Chiufb8b8162016-04-01 23:50:51 +0000603 );
604 }
605 }
606
607 /**
608 * Factory to allocate a virtual device array matcher.
609 *
610 * @param vdev virtual device object we are looking for
611 * @return matcher
612 */
613 private VdevJsonArrayMatcher hasVdev(VirtualDevice vdev) {
614 return new VdevJsonArrayMatcher(vdev);
615 }
616 /**
617 * Tests adding of new virtual device using POST via JSON stream.
618 */
619 @Test
620 public void testPostVirtualDevice() {
621 NetworkId networkId = networkId3;
622 DeviceId deviceId = devId2;
623 expect(mockVnetAdminService.createVirtualDevice(networkId, deviceId)).andReturn(vdev2);
624 expectLastCall();
625
626 replay(mockVnetAdminService);
627
628 WebTarget wt = target();
629 InputStream jsonStream = VirtualNetworkWebResourceTest.class
630 .getResourceAsStream("post-virtual-device.json");
631 String reqLocation = "vnets/" + networkId.toString() + "/devices";
632 Response response = wt.path(reqLocation).request(MediaType.APPLICATION_JSON_TYPE)
633 .post(Entity.json(jsonStream));
634 assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
635
636 String location = response.getLocation().getPath();
637 assertThat(location, Matchers.startsWith("/" + reqLocation + "/" + vdev2.id().toString()));
638
639 verify(mockVnetAdminService);
640 }
641
642 /**
643 * Tests adding of a null virtual device using POST via JSON stream.
644 */
645 @Test
646 public void testPostVirtualDeviceNullJsonStream() {
647 NetworkId networkId = networkId3;
648 replay(mockVnetAdminService);
649
650 WebTarget wt = target();
651 try {
652 String reqLocation = "vnets/" + networkId.toString() + "/devices";
Jian Li08d65cf2016-04-20 10:07:17 -0700653 wt.path(reqLocation)
Claudine Chiufb8b8162016-04-01 23:50:51 +0000654 .request(MediaType.APPLICATION_JSON_TYPE)
655 .post(Entity.json(null), String.class);
656 fail("POST of null virtual device did not throw an exception");
657 } catch (BadRequestException ex) {
658 assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
659 }
660
661 verify(mockVnetAdminService);
662 }
663
664 /**
665 * Tests removing a virtual device with DELETE request.
666 */
667 @Test
668 public void testDeleteVirtualDevice() {
669 NetworkId networkId = networkId3;
670 DeviceId deviceId = devId2;
671 mockVnetAdminService.removeVirtualDevice(networkId, deviceId);
672 expectLastCall();
673 replay(mockVnetAdminService);
674
675 WebTarget wt = target()
676 .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
677 String reqLocation = "vnets/" + networkId.toString() + "/devices/" + deviceId.toString();
678 Response response = wt.path(reqLocation)
679 .request(MediaType.APPLICATION_JSON_TYPE)
680 .delete();
681
Jian Lic2a542b2016-05-10 11:48:19 -0700682 assertThat(response.getStatus(), is(HttpURLConnection.HTTP_NO_CONTENT));
Claudine Chiufb8b8162016-04-01 23:50:51 +0000683
684 verify(mockVnetAdminService);
685 }
686
687 // Tests for Virtual Ports
688
689 /**
690 * Tests the result of the REST API GET when there are no virtual ports.
691 */
692 @Test
693 public void testGetVirtualPortsEmptyArray() {
694 NetworkId networkId = networkId4;
695 DeviceId deviceId = devId2;
696 expect(mockVnetService.getVirtualPorts(networkId, deviceId))
697 .andReturn(ImmutableSet.of()).anyTimes();
698 replay(mockVnetService);
699
700 WebTarget wt = target();
701 String location = "vnets/" + networkId.toString()
702 + "/devices/" + deviceId.toString() + "/ports";
703 String response = wt.path(location).request().get(String.class);
704 assertThat(response, is("{\"ports\":[]}"));
705
706 verify(mockVnetService);
707 }
708
709 /**
710 * Tests the result of the REST API GET when virtual ports are defined.
711 */
712 @Test
713 public void testGetVirtualPortsArray() {
714 NetworkId networkId = networkId3;
715 DeviceId deviceId = dev22.id();
716 vportSet.add(vport23);
717 vportSet.add(vport22);
718 expect(mockVnetService.getVirtualPorts(networkId, deviceId)).andReturn(vportSet).anyTimes();
719 replay(mockVnetService);
720
721 WebTarget wt = target();
722 String location = "vnets/" + networkId.toString()
723 + "/devices/" + deviceId.toString() + "/ports";
724 String response = wt.path(location).request().get(String.class);
725 assertThat(response, containsString("{\"ports\":["));
726
727 final JsonObject result = Json.parse(response).asObject();
728 assertThat(result, notNullValue());
729
730 assertThat(result.names(), hasSize(1));
731 assertThat(result.names().get(0), is("ports"));
732
733 final JsonArray vnetJsonArray = result.get("ports").asArray();
734 assertThat(vnetJsonArray, notNullValue());
735 assertEquals("Virtual ports array is not the correct size.",
Brian Stanke9a108972016-04-11 15:25:17 -0400736 vportSet.size(), vnetJsonArray.size());
Claudine Chiufb8b8162016-04-01 23:50:51 +0000737
738 vportSet.forEach(vport -> assertThat(vnetJsonArray, hasVport(vport)));
739
740 verify(mockVnetService);
741 }
742
743 /**
744 * Array matcher for VirtualPort.
745 */
Claudine Chiu25f07be2016-06-27 16:21:21 +0000746 private static final class VportJsonArrayMatcher extends JsonArrayMatcher<VirtualPort> {
Claudine Chiufb8b8162016-04-01 23:50:51 +0000747
Claudine Chiu25f07be2016-06-27 16:21:21 +0000748 private VportJsonArrayMatcher(VirtualPort vportIn) {
Claudine Chiufb8b8162016-04-01 23:50:51 +0000749 super(vportIn,
750 vport -> "Virtual port " + vport.networkId().toString() + " "
751 + vport.element().id().toString() + " " + vport.number().toString(),
Jian Li08d65cf2016-04-20 10:07:17 -0700752 (vport, jsonObject) -> jsonObject.get(ID).asString().equals(vport.networkId().toString())
753 && jsonObject.get(PORT_NUM).asString().equals(vport.number().toString())
754 && jsonObject.get(DEVICE_ID).asString().equals(vport.element().id().toString()),
Claudine Chiufb8b8162016-04-01 23:50:51 +0000755 ImmutableList.of(ID, DEVICE_ID, PORT_NUM, PHYS_DEVICE_ID, PHYS_PORT_NUM),
Jian Li08d65cf2016-04-20 10:07:17 -0700756 (vport, s) -> s.equals(ID) ? vport.networkId().toString()
757 : s.equals(DEVICE_ID) ? vport.element().id().toString()
758 : s.equals(PORT_NUM) ? vport.number().toString()
Yoonseon Han6c603892016-09-01 11:52:21 -0700759 : s.equals(PHYS_DEVICE_ID) ? vport.realizedBy().deviceId().toString()
760 : s.equals(PHYS_PORT_NUM) ? vport.realizedBy().port().toString()
Jian Li08d65cf2016-04-20 10:07:17 -0700761 : null
Claudine Chiufb8b8162016-04-01 23:50:51 +0000762 );
763 }
764 }
765
766 /**
767 * Factory to allocate a virtual port array matcher.
768 *
769 * @param vport virtual port object we are looking for
770 * @return matcher
771 */
772 private VportJsonArrayMatcher hasVport(VirtualPort vport) {
773 return new VportJsonArrayMatcher(vport);
774 }
775
776 /**
777 * Tests adding of new virtual port using POST via JSON stream.
778 */
779 @Test
780 public void testPostVirtualPort() {
781 NetworkId networkId = networkId3;
782 DeviceId deviceId = devId22;
783 DefaultAnnotations annotations = DefaultAnnotations.builder().build();
784 Device physDevice = new DefaultDevice(null, DeviceId.deviceId("dev1"),
Brian Stanke9a108972016-04-11 15:25:17 -0400785 null, null, null, null, null, null, annotations);
Yoonseon Han6c603892016-09-01 11:52:21 -0700786 ConnectPoint cp1 = new ConnectPoint(physDevice.id(), portNumber(1));
787 expect(mockVnetAdminService.createVirtualPort(networkId, deviceId, portNumber(22), cp1))
Claudine Chiufb8b8162016-04-01 23:50:51 +0000788 .andReturn(vport22);
789
790 replay(mockVnetAdminService);
791
792 WebTarget wt = target();
793 InputStream jsonStream = VirtualNetworkWebResourceTest.class
794 .getResourceAsStream("post-virtual-port.json");
795 String reqLocation = "vnets/" + networkId.toString()
796 + "/devices/" + deviceId.toString() + "/ports";
797 Response response = wt.path(reqLocation).request(MediaType.APPLICATION_JSON_TYPE)
798 .post(Entity.json(jsonStream));
799 assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
800
801 verify(mockVnetAdminService);
802 }
803
804 /**
805 * Tests adding of a null virtual port using POST via JSON stream.
806 */
807 @Test
808 public void testPostVirtualPortNullJsonStream() {
809 NetworkId networkId = networkId3;
810 DeviceId deviceId = devId2;
811 replay(mockVnetAdminService);
812
813 WebTarget wt = target();
814 try {
815 String reqLocation = "vnets/" + networkId.toString()
816 + "/devices/" + deviceId.toString() + "/ports";
Jian Li08d65cf2016-04-20 10:07:17 -0700817 wt.path(reqLocation)
Claudine Chiufb8b8162016-04-01 23:50:51 +0000818 .request(MediaType.APPLICATION_JSON_TYPE)
819 .post(Entity.json(null), String.class);
820 fail("POST of null virtual port did not throw an exception");
821 } catch (BadRequestException ex) {
822 assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
823 }
824
825 verify(mockVnetAdminService);
826 }
827
828 /**
829 * Tests removing a virtual port with DELETE request.
830 */
831 @Test
832 public void testDeleteVirtualPort() {
833 NetworkId networkId = networkId3;
834 DeviceId deviceId = devId2;
835 PortNumber portNum = portNumber(2);
836 mockVnetAdminService.removeVirtualPort(networkId, deviceId, portNum);
837 expectLastCall();
838 replay(mockVnetAdminService);
839
840 WebTarget wt = target()
841 .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
842 String reqLocation = "vnets/" + networkId.toString()
Brian Stanke9a108972016-04-11 15:25:17 -0400843 + "/devices/" + deviceId.toString() + "/ports/" + portNum.toLong();
Claudine Chiufb8b8162016-04-01 23:50:51 +0000844 Response response = wt.path(reqLocation)
845 .request(MediaType.APPLICATION_JSON_TYPE)
846 .delete();
847
Jian Lic2a542b2016-05-10 11:48:19 -0700848 assertThat(response.getStatus(), is(HttpURLConnection.HTTP_NO_CONTENT));
Claudine Chiufb8b8162016-04-01 23:50:51 +0000849
850 verify(mockVnetAdminService);
851 }
852
Claudine Chiuf6bf8d52016-04-08 01:31:54 +0000853 // Tests for Virtual Links
854
855 /**
856 * Tests the result of the REST API GET when there are no virtual links.
857 */
858 @Test
859 public void testGetVirtualLinksEmptyArray() {
860 NetworkId networkId = networkId4;
861 expect(mockVnetService.getVirtualLinks(networkId)).andReturn(ImmutableSet.of()).anyTimes();
862 replay(mockVnetService);
863
864 WebTarget wt = target();
865 String location = "vnets/" + networkId.toString() + "/links";
866 String response = wt.path(location).request().get(String.class);
867 assertThat(response, is("{\"links\":[]}"));
868
869 verify(mockVnetService);
870 }
871
872 /**
873 * Tests the result of the REST API GET when virtual links are defined.
874 */
875 @Test
876 public void testGetVirtualLinksArray() {
877 NetworkId networkId = networkId3;
878 final Set<VirtualLink> vlinkSet = ImmutableSet.of(vlink1, vlink2);
879 expect(mockVnetService.getVirtualLinks(networkId)).andReturn(vlinkSet).anyTimes();
880 replay(mockVnetService);
881
882 WebTarget wt = target();
883 String location = "vnets/" + networkId.toString() + "/links";
884 String response = wt.path(location).request().get(String.class);
885 assertThat(response, containsString("{\"links\":["));
886
887 final JsonObject result = Json.parse(response).asObject();
888 assertThat(result, notNullValue());
889
890 assertThat(result.names(), hasSize(1));
891 assertThat(result.names().get(0), is("links"));
892
893 final JsonArray vnetJsonArray = result.get("links").asArray();
894 assertThat(vnetJsonArray, notNullValue());
895 assertEquals("Virtual links array is not the correct size.",
896 vlinkSet.size(), vnetJsonArray.size());
897
898 vlinkSet.forEach(vlink -> assertThat(vnetJsonArray, hasVlink(vlink)));
899
900 verify(mockVnetService);
901 }
902
903 /**
904 * Hamcrest matcher to check that a virtual link representation in JSON matches
905 * the actual virtual link.
906 */
Claudine Chiu25f07be2016-06-27 16:21:21 +0000907 private static final class VirtualLinkJsonMatcher extends LinksResourceTest.LinkJsonMatcher {
Claudine Chiuf6bf8d52016-04-08 01:31:54 +0000908 private final VirtualLink vlink;
909 private String reason = "";
910
Claudine Chiu25f07be2016-06-27 16:21:21 +0000911 private VirtualLinkJsonMatcher(VirtualLink vlinkValue) {
Claudine Chiuf6bf8d52016-04-08 01:31:54 +0000912 super(vlinkValue);
913 vlink = vlinkValue;
914 }
915
916 @Override
917 public boolean matchesSafely(JsonObject jsonLink) {
918 if (!super.matchesSafely(jsonLink)) {
919 return false;
920 }
921 // check NetworkId
922 String jsonNetworkId = jsonLink.get(ID).asString();
923 String networkId = vlink.networkId().toString();
924 if (!jsonNetworkId.equals(networkId)) {
925 reason = ID + " was " + jsonNetworkId;
926 return false;
927 }
Claudine Chiuf6bf8d52016-04-08 01:31:54 +0000928 return true;
929 }
930
931 @Override
932 public void describeTo(Description description) {
933 description.appendText(reason);
934 }
935 }
936
937 /**
938 * Factory to allocate a virtual link matcher.
939 *
940 * @param vlink virtual link object we are looking for
941 * @return matcher
942 */
943 private static VirtualLinkJsonMatcher matchesVirtualLink(VirtualLink vlink) {
944 return new VirtualLinkJsonMatcher(vlink);
945 }
946
947 /**
948 * Hamcrest matcher to check that a virtual link is represented properly in a JSON
949 * array of links.
950 */
Claudine Chiu25f07be2016-06-27 16:21:21 +0000951 private static final class VirtualLinkJsonArrayMatcher extends TypeSafeMatcher<JsonArray> {
Claudine Chiuf6bf8d52016-04-08 01:31:54 +0000952 private final VirtualLink vlink;
953 private String reason = "";
954
Claudine Chiu25f07be2016-06-27 16:21:21 +0000955 private VirtualLinkJsonArrayMatcher(VirtualLink vlinkValue) {
Claudine Chiuf6bf8d52016-04-08 01:31:54 +0000956 vlink = vlinkValue;
957 }
958
959 @Override
960 public boolean matchesSafely(JsonArray json) {
Claudine Chiuf6bf8d52016-04-08 01:31:54 +0000961 for (int jsonLinkIndex = 0; jsonLinkIndex < json.size();
962 jsonLinkIndex++) {
963
964 JsonObject jsonLink = json.get(jsonLinkIndex).asObject();
965
966 if (matchesVirtualLink(vlink).matchesSafely(jsonLink)) {
967 return true;
968 }
969 }
970 return false;
971 }
972
973 @Override
974 public void describeTo(Description description) {
975 description.appendText(reason);
976 }
977 }
978
979 /**
980 * Factory to allocate a virtual link array matcher.
981 *
982 * @param vlink virtual link object we are looking for
983 * @return matcher
984 */
985 private VirtualLinkJsonArrayMatcher hasVlink(VirtualLink vlink) {
986 return new VirtualLinkJsonArrayMatcher(vlink);
987 }
988
989 /**
990 * Tests adding of new virtual link using POST via JSON stream.
991 */
992 @Test
993 public void testPostVirtualLink() {
994 NetworkId networkId = networkId3;
Brian Stanke9a108972016-04-11 15:25:17 -0400995 expect(mockVnetAdminService.createVirtualLink(networkId, cp22, cp11))
Claudine Chiuf6bf8d52016-04-08 01:31:54 +0000996 .andReturn(vlink1);
997 replay(mockVnetAdminService);
998
999 WebTarget wt = target();
1000 InputStream jsonStream = VirtualNetworkWebResourceTest.class
1001 .getResourceAsStream("post-virtual-link.json");
1002 String reqLocation = "vnets/" + networkId.toString() + "/links";
1003 Response response = wt.path(reqLocation).request(MediaType.APPLICATION_JSON_TYPE)
1004 .post(Entity.json(jsonStream));
1005 assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
1006
1007 String location = response.getLocation().getPath();
1008 assertThat(location, Matchers.startsWith("/" + reqLocation));
1009
1010 verify(mockVnetAdminService);
1011 }
1012
1013 /**
1014 * Tests adding of a null virtual link using POST via JSON stream.
1015 */
1016 @Test
1017 public void testPostVirtualLinkNullJsonStream() {
1018 NetworkId networkId = networkId3;
1019 replay(mockVnetAdminService);
1020
1021 WebTarget wt = target();
1022 try {
1023 String reqLocation = "vnets/" + networkId.toString() + "/links";
1024 wt.path(reqLocation)
1025 .request(MediaType.APPLICATION_JSON_TYPE)
1026 .post(Entity.json(null), String.class);
1027 fail("POST of null virtual link did not throw an exception");
1028 } catch (BadRequestException ex) {
1029 assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
1030 }
1031
1032 verify(mockVnetAdminService);
1033 }
1034
1035 /**
1036 * Tests removing a virtual link with DELETE request.
1037 */
1038 @Test
1039 public void testDeleteVirtualLink() {
1040 NetworkId networkId = networkId3;
1041 mockVnetAdminService.removeVirtualLink(networkId, cp22, cp11);
1042 expectLastCall();
1043 replay(mockVnetAdminService);
1044
1045 WebTarget wt = target()
1046 .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
1047 InputStream jsonStream = VirtualNetworkWebResourceTest.class
1048 .getResourceAsStream("post-virtual-link.json");
1049 String reqLocation = "vnets/" + networkId.toString() + "/links";
Jian Li08d65cf2016-04-20 10:07:17 -07001050 Response response = wt.path(reqLocation).request().method("DELETE", Entity.json(jsonStream));
Claudine Chiuf6bf8d52016-04-08 01:31:54 +00001051
Jian Lic2a542b2016-05-10 11:48:19 -07001052 assertThat(response.getStatus(), is(HttpURLConnection.HTTP_NO_CONTENT));
Claudine Chiuf6bf8d52016-04-08 01:31:54 +00001053 verify(mockVnetAdminService);
1054 }
Claudine Chiu25f07be2016-06-27 16:21:21 +00001055
1056 // Tests for Virtual Hosts
1057
1058 /**
1059 * Tests the result of the REST API GET when there are no virtual hosts.
1060 */
1061 @Test
1062 public void testGetVirtualHostsEmptyArray() {
1063 NetworkId networkId = networkId4;
1064 expect(mockVnetService.getVirtualHosts(networkId)).andReturn(ImmutableSet.of()).anyTimes();
1065 replay(mockVnetService);
1066
1067 WebTarget wt = target();
1068 String location = "vnets/" + networkId.toString() + "/hosts";
1069 String response = wt.path(location).request().get(String.class);
1070 assertThat(response, is("{\"hosts\":[]}"));
1071
1072 verify(mockVnetService);
1073 }
1074
1075 /**
1076 * Tests the result of the REST API GET when virtual hosts are defined.
1077 */
1078 @Test
1079 public void testGetVirtualHostsArray() {
1080 NetworkId networkId = networkId3;
1081 final Set<VirtualHost> vhostSet = ImmutableSet.of(vhost1, vhost2);
1082 expect(mockVnetService.getVirtualHosts(networkId)).andReturn(vhostSet).anyTimes();
1083 replay(mockVnetService);
1084
1085 WebTarget wt = target();
1086 String location = "vnets/" + networkId.toString() + "/hosts";
1087 String response = wt.path(location).request().get(String.class);
1088 assertThat(response, containsString("{\"hosts\":["));
1089
1090 final JsonObject result = Json.parse(response).asObject();
1091 assertThat(result, notNullValue());
1092
1093 assertThat(result.names(), hasSize(1));
1094 assertThat(result.names().get(0), is("hosts"));
1095
1096 final JsonArray vnetJsonArray = result.get("hosts").asArray();
1097 assertThat(vnetJsonArray, notNullValue());
1098 assertEquals("Virtual hosts array is not the correct size.",
1099 vhostSet.size(), vnetJsonArray.size());
1100
1101 vhostSet.forEach(vhost -> assertThat(vnetJsonArray, hasVhost(vhost)));
1102
1103 verify(mockVnetService);
1104 }
1105
1106 /**
1107 * Hamcrest matcher to check that a virtual host representation in JSON matches
1108 * the actual virtual host.
1109 */
1110 private static final class VirtualHostJsonMatcher extends HostResourceTest.HostJsonMatcher {
1111 private final VirtualHost vhost;
1112 private String reason = "";
1113
1114 private VirtualHostJsonMatcher(VirtualHost vhostValue) {
1115 super(vhostValue);
1116 vhost = vhostValue;
1117 }
1118
1119 @Override
1120 public boolean matchesSafely(JsonObject jsonHost) {
1121 if (!super.matchesSafely(jsonHost)) {
1122 return false;
1123 }
1124 // check NetworkId
1125 String jsonNetworkId = jsonHost.get(ID).asString();
1126 String networkId = vhost.networkId().toString();
1127 if (!jsonNetworkId.equals(networkId)) {
1128 reason = ID + " was " + jsonNetworkId;
1129 return false;
1130 }
1131 return true;
1132 }
1133
1134 @Override
1135 public void describeTo(Description description) {
1136 description.appendText(reason);
1137 }
1138 }
1139
1140 /**
1141 * Factory to allocate a virtual host matcher.
1142 *
1143 * @param vhost virtual host object we are looking for
1144 * @return matcher
1145 */
1146 private static VirtualHostJsonMatcher matchesVirtualHost(VirtualHost vhost) {
1147 return new VirtualHostJsonMatcher(vhost);
1148 }
1149
1150 /**
1151 * Hamcrest matcher to check that a virtual host is represented properly in a JSON
1152 * array of hosts.
1153 */
1154 private static final class VirtualHostJsonArrayMatcher extends TypeSafeMatcher<JsonArray> {
1155 private final VirtualHost vhost;
1156 private String reason = "";
1157
1158 private VirtualHostJsonArrayMatcher(VirtualHost vhostValue) {
1159 vhost = vhostValue;
1160 }
1161
1162 @Override
1163 public boolean matchesSafely(JsonArray json) {
1164 for (int jsonHostIndex = 0; jsonHostIndex < json.size();
1165 jsonHostIndex++) {
1166
1167 JsonObject jsonHost = json.get(jsonHostIndex).asObject();
1168
1169 if (matchesVirtualHost(vhost).matchesSafely(jsonHost)) {
1170 return true;
1171 }
1172 }
1173 return false;
1174 }
1175
1176 @Override
1177 public void describeTo(Description description) {
1178 description.appendText(reason);
1179 }
1180 }
1181
1182 /**
1183 * Factory to allocate a virtual host array matcher.
1184 *
1185 * @param vhost virtual host object we are looking for
1186 * @return matcher
1187 */
1188 private VirtualHostJsonArrayMatcher hasVhost(VirtualHost vhost) {
1189 return new VirtualHostJsonArrayMatcher(vhost);
1190 }
1191
1192 /**
1193 * Tests adding of new virtual host using POST via JSON stream.
1194 */
1195 @Test
1196 public void testPostVirtualHost() {
1197 NetworkId networkId = networkId3;
1198 expect(mockVnetAdminService.createVirtualHost(networkId, hId1, mac1, vlan1, loc1, ipSet1))
1199 .andReturn(vhost1);
1200 replay(mockVnetAdminService);
1201
1202 WebTarget wt = target();
1203 InputStream jsonStream = VirtualNetworkWebResourceTest.class
1204 .getResourceAsStream("post-virtual-host.json");
1205 String reqLocation = "vnets/" + networkId.toString() + "/hosts";
1206 Response response = wt.path(reqLocation).request(MediaType.APPLICATION_JSON_TYPE)
1207 .post(Entity.json(jsonStream));
1208 assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
1209
1210 String location = response.getLocation().getPath();
1211 assertThat(location, Matchers.startsWith("/" + reqLocation));
1212
1213 verify(mockVnetAdminService);
1214 }
1215
1216 /**
1217 * Tests adding of a null virtual host using POST via JSON stream.
1218 */
1219 @Test
1220 public void testPostVirtualHostNullJsonStream() {
1221 NetworkId networkId = networkId3;
1222 replay(mockVnetAdminService);
1223
1224 WebTarget wt = target();
1225 try {
1226 String reqLocation = "vnets/" + networkId.toString() + "/hosts";
1227 wt.path(reqLocation)
1228 .request(MediaType.APPLICATION_JSON_TYPE)
1229 .post(Entity.json(null), String.class);
1230 fail("POST of null virtual host did not throw an exception");
1231 } catch (BadRequestException ex) {
1232 assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
1233 }
1234
1235 verify(mockVnetAdminService);
1236 }
1237
1238 /**
1239 * Tests removing a virtual host with DELETE request.
1240 */
1241 @Test
1242 public void testDeleteVirtualHost() {
1243 NetworkId networkId = networkId3;
1244 mockVnetAdminService.removeVirtualHost(networkId, hId1);
1245 expectLastCall();
1246 replay(mockVnetAdminService);
1247
1248 WebTarget wt = target()
1249 .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
1250 InputStream jsonStream = VirtualNetworkWebResourceTest.class
1251 .getResourceAsStream("post-virtual-host.json");
1252 String reqLocation = "vnets/" + networkId.toString() + "/hosts";
1253 Response response = wt.path(reqLocation).request().method("DELETE", Entity.json(jsonStream));
1254
1255 assertThat(response.getStatus(), is(HttpURLConnection.HTTP_NO_CONTENT));
1256 verify(mockVnetAdminService);
1257 }
Claudine Chiufb8b8162016-04-01 23:50:51 +00001258}