Committed by
Gerrit Code Review
ONOS-4077: REST API's for virtual links.
Change-Id: Idc838f24735e75ad2729393a03dcac4d256239bb
Showing
7 changed files
with
615 additions
and
29 deletions
... | @@ -28,6 +28,7 @@ import org.onosproject.codec.JsonCodec; | ... | @@ -28,6 +28,7 @@ import org.onosproject.codec.JsonCodec; |
28 | import org.onosproject.core.Application; | 28 | import org.onosproject.core.Application; |
29 | import org.onosproject.incubator.net.virtual.TenantId; | 29 | import org.onosproject.incubator.net.virtual.TenantId; |
30 | import org.onosproject.incubator.net.virtual.VirtualDevice; | 30 | import org.onosproject.incubator.net.virtual.VirtualDevice; |
31 | +import org.onosproject.incubator.net.virtual.VirtualLink; | ||
31 | import org.onosproject.incubator.net.virtual.VirtualNetwork; | 32 | import org.onosproject.incubator.net.virtual.VirtualNetwork; |
32 | import org.onosproject.incubator.net.virtual.VirtualPort; | 33 | import org.onosproject.incubator.net.virtual.VirtualPort; |
33 | import org.onosproject.net.Annotations; | 34 | import org.onosproject.net.Annotations; |
... | @@ -134,6 +135,7 @@ public class CodecManager implements CodecService { | ... | @@ -134,6 +135,7 @@ public class CodecManager implements CodecService { |
134 | registerCodec(VirtualNetwork.class, new VirtualNetworkCodec()); | 135 | registerCodec(VirtualNetwork.class, new VirtualNetworkCodec()); |
135 | registerCodec(VirtualDevice.class, new VirtualDeviceCodec()); | 136 | registerCodec(VirtualDevice.class, new VirtualDeviceCodec()); |
136 | registerCodec(VirtualPort.class, new VirtualPortCodec()); | 137 | registerCodec(VirtualPort.class, new VirtualPortCodec()); |
138 | + registerCodec(VirtualLink.class, new VirtualLinkCodec()); | ||
137 | log.info("Started"); | 139 | log.info("Started"); |
138 | } | 140 | } |
139 | 141 | ... | ... |
1 | +package org.onosproject.codec.impl; | ||
2 | + | ||
3 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
4 | +import org.onosproject.codec.CodecContext; | ||
5 | +import org.onosproject.codec.JsonCodec; | ||
6 | +import org.onosproject.incubator.net.tunnel.TunnelId; | ||
7 | +import org.onosproject.incubator.net.virtual.DefaultVirtualLink; | ||
8 | +import org.onosproject.incubator.net.virtual.NetworkId; | ||
9 | +import org.onosproject.incubator.net.virtual.VirtualLink; | ||
10 | +import org.onosproject.net.Link; | ||
11 | + | ||
12 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
13 | +import static org.onlab.util.Tools.nullIsIllegal; | ||
14 | + | ||
15 | +/** | ||
16 | + * Codec for the VirtualLink class. | ||
17 | + */ | ||
18 | +public class VirtualLinkCodec extends JsonCodec<VirtualLink> { | ||
19 | + | ||
20 | + // JSON field names | ||
21 | + private static final String NETWORK_ID = "networkId"; | ||
22 | + private static final String TUNNEL_ID = "tunnelId"; | ||
23 | + | ||
24 | + private static final String NULL_OBJECT_MSG = "VirtualLink cannot be null"; | ||
25 | + private static final String MISSING_MEMBER_MSG = " member is required in VirtualLink"; | ||
26 | + | ||
27 | + @Override | ||
28 | + public ObjectNode encode(VirtualLink vLink, CodecContext context) { | ||
29 | + checkNotNull(vLink, NULL_OBJECT_MSG); | ||
30 | + | ||
31 | + JsonCodec<Link> codec = context.codec(Link.class); | ||
32 | + ObjectNode result = codec.encode(vLink, context); | ||
33 | + result.put(NETWORK_ID, vLink.networkId().toString()); | ||
34 | + // TODO check if tunnelId needs to be part of VirtualLink interface. | ||
35 | + if (vLink instanceof DefaultVirtualLink) { | ||
36 | + result.put(TUNNEL_ID, ((DefaultVirtualLink) vLink).tunnelId().toString()); | ||
37 | + } | ||
38 | + return result; | ||
39 | + } | ||
40 | + | ||
41 | + @Override | ||
42 | + public VirtualLink decode(ObjectNode json, CodecContext context) { | ||
43 | + if (json == null || !json.isObject()) { | ||
44 | + return null; | ||
45 | + } | ||
46 | + JsonCodec<Link> codec = context.codec(Link.class); | ||
47 | + Link link = codec.decode(json, context); | ||
48 | + NetworkId nId = NetworkId.networkId(Long.parseLong(extractMember(NETWORK_ID, json))); | ||
49 | + String tunnelIdStr = json.path(TUNNEL_ID).asText(); | ||
50 | + TunnelId tunnelId = tunnelIdStr != null ? TunnelId.valueOf(tunnelIdStr) | ||
51 | + : TunnelId.valueOf(0); | ||
52 | + return new DefaultVirtualLink(nId, link.src(), link.dst(), tunnelId); | ||
53 | + } | ||
54 | + | ||
55 | + /** | ||
56 | + * Extract member from JSON ObjectNode. | ||
57 | + * | ||
58 | + * @param key key for which value is needed | ||
59 | + * @param json JSON ObjectNode | ||
60 | + * @return member value | ||
61 | + */ | ||
62 | + private String extractMember(String key, ObjectNode json) { | ||
63 | + return nullIsIllegal(json.get(key), key + MISSING_MEMBER_MSG).asText(); | ||
64 | + } | ||
65 | +} |
... | @@ -131,7 +131,7 @@ public class TenantWebResource extends AbstractWebResource { | ... | @@ -131,7 +131,7 @@ public class TenantWebResource extends AbstractWebResource { |
131 | * | 131 | * |
132 | * @param stream TenantId JSON stream | 132 | * @param stream TenantId JSON stream |
133 | * @return TenantId | 133 | * @return TenantId |
134 | - * @throws IOException | 134 | + * @throws IOException if unable to parse the request |
135 | */ | 135 | */ |
136 | private TenantId getTenantIdFromJsonStream(InputStream stream) throws IOException { | 136 | private TenantId getTenantIdFromJsonStream(InputStream stream) throws IOException { |
137 | ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); | 137 | ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); |
... | @@ -146,11 +146,11 @@ public class TenantWebResource extends AbstractWebResource { | ... | @@ -146,11 +146,11 @@ public class TenantWebResource extends AbstractWebResource { |
146 | /** | 146 | /** |
147 | * Get the matching tenant identifier from existing tenant identifiers in system. | 147 | * Get the matching tenant identifier from existing tenant identifiers in system. |
148 | * | 148 | * |
149 | - * @param vnetAdminSvc | 149 | + * @param vnetAdminSvc virtual network administration service |
150 | * @param tidIn tenant identifier | 150 | * @param tidIn tenant identifier |
151 | * @return TenantId | 151 | * @return TenantId |
152 | */ | 152 | */ |
153 | - private static TenantId getExistingTenantId(VirtualNetworkAdminService vnetAdminSvc, | 153 | + static TenantId getExistingTenantId(VirtualNetworkAdminService vnetAdminSvc, |
154 | TenantId tidIn) { | 154 | TenantId tidIn) { |
155 | final TenantId resultTid = vnetAdminSvc | 155 | final TenantId resultTid = vnetAdminSvc |
156 | .getTenantIds() | 156 | .getTenantIds() | ... | ... |
... | @@ -18,9 +18,12 @@ package org.onosproject.rest.resources; | ... | @@ -18,9 +18,12 @@ package org.onosproject.rest.resources; |
18 | 18 | ||
19 | import com.fasterxml.jackson.databind.JsonNode; | 19 | import com.fasterxml.jackson.databind.JsonNode; |
20 | import com.fasterxml.jackson.databind.node.ObjectNode; | 20 | import com.fasterxml.jackson.databind.node.ObjectNode; |
21 | +import org.onosproject.incubator.net.tunnel.TunnelId; | ||
22 | +import org.onosproject.incubator.net.virtual.DefaultVirtualLink; | ||
21 | import org.onosproject.incubator.net.virtual.NetworkId; | 23 | import org.onosproject.incubator.net.virtual.NetworkId; |
22 | import org.onosproject.incubator.net.virtual.TenantId; | 24 | import org.onosproject.incubator.net.virtual.TenantId; |
23 | import org.onosproject.incubator.net.virtual.VirtualDevice; | 25 | import org.onosproject.incubator.net.virtual.VirtualDevice; |
26 | +import org.onosproject.incubator.net.virtual.VirtualLink; | ||
24 | import org.onosproject.incubator.net.virtual.VirtualNetwork; | 27 | import org.onosproject.incubator.net.virtual.VirtualNetwork; |
25 | import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService; | 28 | import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService; |
26 | import org.onosproject.incubator.net.virtual.VirtualNetworkService; | 29 | import org.onosproject.incubator.net.virtual.VirtualNetworkService; |
... | @@ -38,6 +41,7 @@ import javax.ws.rs.Consumes; | ... | @@ -38,6 +41,7 @@ import javax.ws.rs.Consumes; |
38 | import javax.ws.rs.DELETE; | 41 | import javax.ws.rs.DELETE; |
39 | import javax.ws.rs.GET; | 42 | import javax.ws.rs.GET; |
40 | import javax.ws.rs.POST; | 43 | import javax.ws.rs.POST; |
44 | +import javax.ws.rs.PUT; | ||
41 | import javax.ws.rs.Path; | 45 | import javax.ws.rs.Path; |
42 | import javax.ws.rs.PathParam; | 46 | import javax.ws.rs.PathParam; |
43 | import javax.ws.rs.Produces; | 47 | import javax.ws.rs.Produces; |
... | @@ -69,7 +73,6 @@ public class VirtualNetworkWebResource extends AbstractWebResource { | ... | @@ -69,7 +73,6 @@ public class VirtualNetworkWebResource extends AbstractWebResource { |
69 | UriInfo uriInfo; | 73 | UriInfo uriInfo; |
70 | 74 | ||
71 | // VirtualNetwork | 75 | // VirtualNetwork |
72 | - // TODO Query vnets by tenant | ||
73 | 76 | ||
74 | /** | 77 | /** |
75 | * Returns all virtual networks. | 78 | * Returns all virtual networks. |
... | @@ -88,6 +91,22 @@ public class VirtualNetworkWebResource extends AbstractWebResource { | ... | @@ -88,6 +91,22 @@ public class VirtualNetworkWebResource extends AbstractWebResource { |
88 | } | 91 | } |
89 | 92 | ||
90 | /** | 93 | /** |
94 | + * Returns the virtual networks with the specified tenant identifier. | ||
95 | + * | ||
96 | + * @param tenantId tenant identifier | ||
97 | + * @return 200 OK, 404 not found | ||
98 | + */ | ||
99 | + @GET | ||
100 | + @Produces(MediaType.APPLICATION_JSON) | ||
101 | + @Path("{tenantId}") | ||
102 | + public Response getVirtualNetworkById(@PathParam("tenantId") String tenantId) { | ||
103 | + final TenantId existingTid = TenantWebResource.getExistingTenantId(vnetAdminService, | ||
104 | + TenantId.tenantId(tenantId)); | ||
105 | + Set<VirtualNetwork> vnets = vnetService.getVirtualNetworks(existingTid); | ||
106 | + return ok(encodeArray(VirtualNetwork.class, "vnets", vnets)).build(); | ||
107 | + } | ||
108 | + | ||
109 | + /** | ||
91 | * Creates a virtual network from the JSON input stream. | 110 | * Creates a virtual network from the JSON input stream. |
92 | * | 111 | * |
93 | * @param stream TenantId JSON stream | 112 | * @param stream TenantId JSON stream |
... | @@ -122,7 +141,7 @@ public class VirtualNetworkWebResource extends AbstractWebResource { | ... | @@ -122,7 +141,7 @@ public class VirtualNetworkWebResource extends AbstractWebResource { |
122 | @DELETE | 141 | @DELETE |
123 | @Path("{networkId}") | 142 | @Path("{networkId}") |
124 | public Response removeVirtualNetwork(@PathParam("networkId") long networkId) { | 143 | public Response removeVirtualNetwork(@PathParam("networkId") long networkId) { |
125 | - final NetworkId nid = NetworkId.networkId(networkId); | 144 | + NetworkId nid = NetworkId.networkId(networkId); |
126 | vnetAdminService.removeVirtualNetwork(nid); | 145 | vnetAdminService.removeVirtualNetwork(nid); |
127 | return Response.ok().build(); | 146 | return Response.ok().build(); |
128 | } | 147 | } |
... | @@ -139,7 +158,7 @@ public class VirtualNetworkWebResource extends AbstractWebResource { | ... | @@ -139,7 +158,7 @@ public class VirtualNetworkWebResource extends AbstractWebResource { |
139 | @Produces(MediaType.APPLICATION_JSON) | 158 | @Produces(MediaType.APPLICATION_JSON) |
140 | @Path("{networkId}/devices") | 159 | @Path("{networkId}/devices") |
141 | public Response getVirtualDevices(@PathParam("networkId") long networkId) { | 160 | public Response getVirtualDevices(@PathParam("networkId") long networkId) { |
142 | - final NetworkId nid = NetworkId.networkId(networkId); | 161 | + NetworkId nid = NetworkId.networkId(networkId); |
143 | Set<VirtualDevice> vdevs = vnetService.getVirtualDevices(nid); | 162 | Set<VirtualDevice> vdevs = vnetService.getVirtualDevices(nid); |
144 | return ok(encodeArray(VirtualDevice.class, "devices", vdevs)).build(); | 163 | return ok(encodeArray(VirtualDevice.class, "devices", vdevs)).build(); |
145 | } | 164 | } |
... | @@ -154,7 +173,7 @@ public class VirtualNetworkWebResource extends AbstractWebResource { | ... | @@ -154,7 +173,7 @@ public class VirtualNetworkWebResource extends AbstractWebResource { |
154 | * @onos.rsModel VirtualDevice | 173 | * @onos.rsModel VirtualDevice |
155 | */ | 174 | */ |
156 | @POST | 175 | @POST |
157 | - @Path("{networkId}/devices/") | 176 | + @Path("{networkId}/devices") |
158 | @Consumes(MediaType.APPLICATION_JSON) | 177 | @Consumes(MediaType.APPLICATION_JSON) |
159 | @Produces(MediaType.APPLICATION_JSON) | 178 | @Produces(MediaType.APPLICATION_JSON) |
160 | public Response createVirtualDevice(@PathParam("networkId") long networkId, | 179 | public Response createVirtualDevice(@PathParam("networkId") long networkId, |
... | @@ -162,15 +181,14 @@ public class VirtualNetworkWebResource extends AbstractWebResource { | ... | @@ -162,15 +181,14 @@ public class VirtualNetworkWebResource extends AbstractWebResource { |
162 | try { | 181 | try { |
163 | ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); | 182 | ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); |
164 | final VirtualDevice vdevReq = codec(VirtualDevice.class).decode(jsonTree, this); | 183 | final VirtualDevice vdevReq = codec(VirtualDevice.class).decode(jsonTree, this); |
165 | - JsonNode specifiedRegionId = jsonTree.get("networkId"); | 184 | + JsonNode specifiedNetworkId = jsonTree.get("networkId"); |
166 | - if (specifiedRegionId != null && | 185 | + if (specifiedNetworkId == null || specifiedNetworkId.asLong() != (networkId)) { |
167 | - specifiedRegionId.asLong() != (networkId)) { | ||
168 | throw new IllegalArgumentException(INVALID_FIELD + "networkId"); | 186 | throw new IllegalArgumentException(INVALID_FIELD + "networkId"); |
169 | } | 187 | } |
170 | final VirtualDevice vdevRes = vnetAdminService.createVirtualDevice(vdevReq.networkId(), | 188 | final VirtualDevice vdevRes = vnetAdminService.createVirtualDevice(vdevReq.networkId(), |
171 | vdevReq.id()); | 189 | vdevReq.id()); |
172 | UriBuilder locationBuilder = uriInfo.getBaseUriBuilder() | 190 | UriBuilder locationBuilder = uriInfo.getBaseUriBuilder() |
173 | - .path("vnets").path(specifiedRegionId.asText()) | 191 | + .path("vnets").path(specifiedNetworkId.asText()) |
174 | .path("devices").path(vdevRes.id().toString()); | 192 | .path("devices").path(vdevRes.id().toString()); |
175 | return Response | 193 | return Response |
176 | .created(locationBuilder.build()) | 194 | .created(locationBuilder.build()) |
... | @@ -191,8 +209,8 @@ public class VirtualNetworkWebResource extends AbstractWebResource { | ... | @@ -191,8 +209,8 @@ public class VirtualNetworkWebResource extends AbstractWebResource { |
191 | @Path("{networkId}/devices/{deviceId}") | 209 | @Path("{networkId}/devices/{deviceId}") |
192 | public Response removeVirtualDevice(@PathParam("networkId") long networkId, | 210 | public Response removeVirtualDevice(@PathParam("networkId") long networkId, |
193 | @PathParam("deviceId") String deviceId) { | 211 | @PathParam("deviceId") String deviceId) { |
194 | - final NetworkId nid = NetworkId.networkId(networkId); | 212 | + NetworkId nid = NetworkId.networkId(networkId); |
195 | - final DeviceId did = DeviceId.deviceId(deviceId); | 213 | + DeviceId did = DeviceId.deviceId(deviceId); |
196 | vnetAdminService.removeVirtualDevice(nid, did); | 214 | vnetAdminService.removeVirtualDevice(nid, did); |
197 | return Response.ok().build(); | 215 | return Response.ok().build(); |
198 | } | 216 | } |
... | @@ -211,7 +229,7 @@ public class VirtualNetworkWebResource extends AbstractWebResource { | ... | @@ -211,7 +229,7 @@ public class VirtualNetworkWebResource extends AbstractWebResource { |
211 | @Path("{networkId}/devices/{deviceId}/ports") | 229 | @Path("{networkId}/devices/{deviceId}/ports") |
212 | public Response getVirtualPorts(@PathParam("networkId") long networkId, | 230 | public Response getVirtualPorts(@PathParam("networkId") long networkId, |
213 | @PathParam("deviceId") String deviceId) { | 231 | @PathParam("deviceId") String deviceId) { |
214 | - final NetworkId nid = NetworkId.networkId(networkId); | 232 | + NetworkId nid = NetworkId.networkId(networkId); |
215 | Iterable<VirtualPort> vports = vnetService.getVirtualPorts(nid, DeviceId.deviceId(deviceId)); | 233 | Iterable<VirtualPort> vports = vnetService.getVirtualPorts(nid, DeviceId.deviceId(deviceId)); |
216 | return ok(encodeArray(VirtualPort.class, "ports", vports)).build(); | 234 | return ok(encodeArray(VirtualPort.class, "ports", vports)).build(); |
217 | } | 235 | } |
... | @@ -238,12 +256,10 @@ public class VirtualNetworkWebResource extends AbstractWebResource { | ... | @@ -238,12 +256,10 @@ public class VirtualNetworkWebResource extends AbstractWebResource { |
238 | // final VirtualPort vportReq = codec(VirtualPort.class).decode(jsonTree, this); | 256 | // final VirtualPort vportReq = codec(VirtualPort.class).decode(jsonTree, this); |
239 | JsonNode specifiedNetworkId = jsonTree.get("networkId"); | 257 | JsonNode specifiedNetworkId = jsonTree.get("networkId"); |
240 | JsonNode specifiedDeviceId = jsonTree.get("deviceId"); | 258 | JsonNode specifiedDeviceId = jsonTree.get("deviceId"); |
241 | - if (specifiedNetworkId != null && | 259 | + if (specifiedNetworkId == null || specifiedNetworkId.asLong() != (networkId)) { |
242 | - specifiedNetworkId.asLong() != (networkId)) { | ||
243 | throw new IllegalArgumentException(INVALID_FIELD + "networkId"); | 260 | throw new IllegalArgumentException(INVALID_FIELD + "networkId"); |
244 | } | 261 | } |
245 | - if (specifiedDeviceId != null && | 262 | + if (specifiedDeviceId == null || !specifiedDeviceId.asText().equals(virtDeviceId)) { |
246 | - !specifiedDeviceId.asText().equals(virtDeviceId)) { | ||
247 | throw new IllegalArgumentException(INVALID_FIELD + "deviceId"); | 263 | throw new IllegalArgumentException(INVALID_FIELD + "deviceId"); |
248 | } | 264 | } |
249 | JsonNode specifiedPortNum = jsonTree.get("portNum"); | 265 | JsonNode specifiedPortNum = jsonTree.get("portNum"); |
... | @@ -283,13 +299,129 @@ public class VirtualNetworkWebResource extends AbstractWebResource { | ... | @@ -283,13 +299,129 @@ public class VirtualNetworkWebResource extends AbstractWebResource { |
283 | public Response removeVirtualPort(@PathParam("networkId") long networkId, | 299 | public Response removeVirtualPort(@PathParam("networkId") long networkId, |
284 | @PathParam("deviceId") String deviceId, | 300 | @PathParam("deviceId") String deviceId, |
285 | @PathParam("portNum") long portNum) { | 301 | @PathParam("portNum") long portNum) { |
286 | - final NetworkId nid = NetworkId.networkId(networkId); | 302 | + NetworkId nid = NetworkId.networkId(networkId); |
287 | vnetAdminService.removeVirtualPort(nid, DeviceId.deviceId(deviceId), | 303 | vnetAdminService.removeVirtualPort(nid, DeviceId.deviceId(deviceId), |
288 | PortNumber.portNumber(portNum)); | 304 | PortNumber.portNumber(portNum)); |
289 | return Response.ok().build(); | 305 | return Response.ok().build(); |
290 | } | 306 | } |
291 | 307 | ||
292 | - // TODO VirtualLink | 308 | + // VirtualLink |
309 | + | ||
310 | + /** | ||
311 | + * Returns all virtual network links in a virtual network. | ||
312 | + * | ||
313 | + * @param networkId network identifier | ||
314 | + * @return 200 OK | ||
315 | + */ | ||
316 | + @GET | ||
317 | + @Produces(MediaType.APPLICATION_JSON) | ||
318 | + @Path("{networkId}/links") | ||
319 | + public Response getVirtualLinks(@PathParam("networkId") long networkId) { | ||
320 | + NetworkId nid = NetworkId.networkId(networkId); | ||
321 | + Set<VirtualLink> vlinks = vnetService.getVirtualLinks(nid); | ||
322 | + return ok(encodeArray(VirtualLink.class, "links", vlinks)).build(); | ||
323 | + } | ||
324 | + | ||
325 | + /** | ||
326 | + * Creates a virtual network link from the JSON input stream. | ||
327 | + * | ||
328 | + * @param networkId network identifier | ||
329 | + * @param stream Virtual device JSON stream | ||
330 | + * @return status of the request - CREATED if the JSON is correct, | ||
331 | + * BAD_REQUEST if the JSON is invalid | ||
332 | + * @onos.rsModel VirtualLink | ||
333 | + */ | ||
334 | + @POST | ||
335 | + @Path("{networkId}/links") | ||
336 | + @Consumes(MediaType.APPLICATION_JSON) | ||
337 | + @Produces(MediaType.APPLICATION_JSON) | ||
338 | + public Response createVirtualLink(@PathParam("networkId") long networkId, | ||
339 | + InputStream stream) { | ||
340 | + try { | ||
341 | + ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); | ||
342 | + JsonNode specifiedNetworkId = jsonTree.get("networkId"); | ||
343 | + if (specifiedNetworkId == null || specifiedNetworkId.asLong() != (networkId)) { | ||
344 | + throw new IllegalArgumentException(INVALID_FIELD + "networkId"); | ||
345 | + } | ||
346 | + final VirtualLink vlinkReq = codec(VirtualLink.class).decode(jsonTree, this); | ||
347 | + TunnelId tunnelId = TunnelId.valueOf(0); | ||
348 | + if (vlinkReq instanceof DefaultVirtualLink) { | ||
349 | + tunnelId = ((DefaultVirtualLink) vlinkReq).tunnelId(); | ||
350 | + } | ||
351 | + vnetAdminService.createVirtualLink(vlinkReq.networkId(), | ||
352 | + vlinkReq.src(), vlinkReq.dst(), tunnelId); | ||
353 | + UriBuilder locationBuilder = uriInfo.getBaseUriBuilder() | ||
354 | + .path("vnets").path(specifiedNetworkId.asText()) | ||
355 | + .path("links"); | ||
356 | + return Response | ||
357 | + .created(locationBuilder.build()) | ||
358 | + .build(); | ||
359 | + } catch (IOException e) { | ||
360 | + throw new IllegalArgumentException(e); | ||
361 | + } | ||
362 | + } | ||
363 | + | ||
364 | + /** | ||
365 | + * Removes the virtual network link from the JSON input stream. | ||
366 | + * | ||
367 | + * @param networkId network identifier | ||
368 | + * @param stream deviceIds JSON stream | ||
369 | + * @return 200 OK, 404 not found | ||
370 | + * @onos.rsModel VirtualLink | ||
371 | + */ | ||
372 | + @DELETE | ||
373 | + @Path("{networkId}/links") | ||
374 | + @Consumes(MediaType.APPLICATION_JSON) | ||
375 | + public Response removeVirtualLink(@PathParam("networkId") long networkId, | ||
376 | + InputStream stream) { | ||
377 | + try { | ||
378 | + ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); | ||
379 | + JsonNode specifiedNetworkId = jsonTree.get("networkId"); | ||
380 | + if (specifiedNetworkId != null && | ||
381 | + specifiedNetworkId.asLong() != (networkId)) { | ||
382 | + throw new IllegalArgumentException(INVALID_FIELD + "networkId"); | ||
383 | + } | ||
384 | + final VirtualLink vlinkReq = codec(VirtualLink.class).decode(jsonTree, this); | ||
385 | + vnetAdminService.removeVirtualLink(vlinkReq.networkId(), | ||
386 | + vlinkReq.src(), vlinkReq.dst()); | ||
387 | + } catch (IOException e) { | ||
388 | + throw new IllegalArgumentException(e); | ||
389 | + } | ||
390 | + | ||
391 | + return Response.ok().build(); | ||
392 | + } | ||
393 | + | ||
394 | + /** | ||
395 | + * Removes the virtual network link from the JSON input stream. | ||
396 | + * | ||
397 | + * @param networkId network identifier | ||
398 | + * @param stream deviceIds JSON stream | ||
399 | + * @return 200 OK, 404 not found | ||
400 | + * @onos.rsModel VirtualLink | ||
401 | + */ | ||
402 | + | ||
403 | + @PUT | ||
404 | + @Path("{networkId}/links/remove") | ||
405 | + @Consumes(MediaType.APPLICATION_JSON) | ||
406 | + @Produces(MediaType.APPLICATION_JSON) | ||
407 | + public Response removeVirtualLink2(@PathParam("networkId") long networkId, | ||
408 | + InputStream stream) { | ||
409 | + try { | ||
410 | + ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); | ||
411 | + JsonNode specifiedNetworkId = jsonTree.get("networkId"); | ||
412 | + if (specifiedNetworkId != null && | ||
413 | + specifiedNetworkId.asLong() != (networkId)) { | ||
414 | + throw new IllegalArgumentException(INVALID_FIELD + "networkId"); | ||
415 | + } | ||
416 | + final VirtualLink vlinkReq = codec(VirtualLink.class).decode(jsonTree, this); | ||
417 | + vnetAdminService.removeVirtualLink(vlinkReq.networkId(), | ||
418 | + vlinkReq.src(), vlinkReq.dst()); | ||
419 | + } catch (IOException e) { | ||
420 | + throw new IllegalArgumentException(e); | ||
421 | + } | ||
422 | + | ||
423 | + return Response.ok().build(); | ||
424 | + } | ||
293 | 425 | ||
294 | /** | 426 | /** |
295 | * Get the tenant identifier from the JSON stream. | 427 | * Get the tenant identifier from the JSON stream. |
... | @@ -297,7 +429,7 @@ public class VirtualNetworkWebResource extends AbstractWebResource { | ... | @@ -297,7 +429,7 @@ public class VirtualNetworkWebResource extends AbstractWebResource { |
297 | * @param stream TenantId JSON stream | 429 | * @param stream TenantId JSON stream |
298 | * @param jsonFieldName field name | 430 | * @param jsonFieldName field name |
299 | * @return JsonNode | 431 | * @return JsonNode |
300 | - * @throws IOException | 432 | + * @throws IOException if unable to parse the request |
301 | */ | 433 | */ |
302 | private JsonNode getFromJsonStream(InputStream stream, String jsonFieldName) throws IOException { | 434 | private JsonNode getFromJsonStream(InputStream stream, String jsonFieldName) throws IOException { |
303 | ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); | 435 | ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); | ... | ... |
1 | +{ | ||
2 | + "type": "object", | ||
3 | + "title": "vlink", | ||
4 | + "required": [ | ||
5 | + "networkId", | ||
6 | + "src", | ||
7 | + "dst", | ||
8 | + "type", | ||
9 | + "state" | ||
10 | + ], | ||
11 | + "properties": { | ||
12 | + "networkId": { | ||
13 | + "type": "String", | ||
14 | + "example": "Network identifier" | ||
15 | + }, | ||
16 | + "src": { | ||
17 | + "type": "object", | ||
18 | + "title": "src", | ||
19 | + "required": [ | ||
20 | + "port", | ||
21 | + "device" | ||
22 | + ], | ||
23 | + "properties": { | ||
24 | + "port": { | ||
25 | + "type": "string", | ||
26 | + "example": "3" | ||
27 | + }, | ||
28 | + "device": { | ||
29 | + "type": "string", | ||
30 | + "example": "of:0000000000000002" | ||
31 | + } | ||
32 | + } | ||
33 | + }, | ||
34 | + "dst": { | ||
35 | + "type": "object", | ||
36 | + "title": "dst", | ||
37 | + "required": [ | ||
38 | + "port", | ||
39 | + "device" | ||
40 | + ], | ||
41 | + "properties": { | ||
42 | + "port": { | ||
43 | + "type": "string", | ||
44 | + "example": "2" | ||
45 | + }, | ||
46 | + "device": { | ||
47 | + "type": "string", | ||
48 | + "example": "of:0000000000000003" | ||
49 | + } | ||
50 | + } | ||
51 | + }, | ||
52 | + "type": { | ||
53 | + "type": "string", | ||
54 | + "example": "DIRECT" | ||
55 | + }, | ||
56 | + "state": { | ||
57 | + "type": "string", | ||
58 | + "example": "ACTIVE" | ||
59 | + }, | ||
60 | + "tunnelId": { | ||
61 | + "type": "int64", | ||
62 | + "example": "Tunnel identifier" | ||
63 | + } | ||
64 | + } | ||
65 | +} |
... | @@ -32,16 +32,20 @@ import org.onlab.osgi.TestServiceDirectory; | ... | @@ -32,16 +32,20 @@ import org.onlab.osgi.TestServiceDirectory; |
32 | import org.onlab.rest.BaseResource; | 32 | import org.onlab.rest.BaseResource; |
33 | import org.onosproject.codec.CodecService; | 33 | import org.onosproject.codec.CodecService; |
34 | import org.onosproject.codec.impl.CodecManager; | 34 | import org.onosproject.codec.impl.CodecManager; |
35 | +import org.onosproject.incubator.net.tunnel.TunnelId; | ||
35 | import org.onosproject.incubator.net.virtual.DefaultVirtualDevice; | 36 | import org.onosproject.incubator.net.virtual.DefaultVirtualDevice; |
37 | +import org.onosproject.incubator.net.virtual.DefaultVirtualLink; | ||
36 | import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork; | 38 | import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork; |
37 | import org.onosproject.incubator.net.virtual.DefaultVirtualPort; | 39 | import org.onosproject.incubator.net.virtual.DefaultVirtualPort; |
38 | import org.onosproject.incubator.net.virtual.NetworkId; | 40 | import org.onosproject.incubator.net.virtual.NetworkId; |
39 | import org.onosproject.incubator.net.virtual.TenantId; | 41 | import org.onosproject.incubator.net.virtual.TenantId; |
40 | import org.onosproject.incubator.net.virtual.VirtualDevice; | 42 | import org.onosproject.incubator.net.virtual.VirtualDevice; |
43 | +import org.onosproject.incubator.net.virtual.VirtualLink; | ||
41 | import org.onosproject.incubator.net.virtual.VirtualNetwork; | 44 | import org.onosproject.incubator.net.virtual.VirtualNetwork; |
42 | import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService; | 45 | import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService; |
43 | import org.onosproject.incubator.net.virtual.VirtualNetworkService; | 46 | import org.onosproject.incubator.net.virtual.VirtualNetworkService; |
44 | import org.onosproject.incubator.net.virtual.VirtualPort; | 47 | import org.onosproject.incubator.net.virtual.VirtualPort; |
48 | +import org.onosproject.net.ConnectPoint; | ||
45 | import org.onosproject.net.DefaultAnnotations; | 49 | import org.onosproject.net.DefaultAnnotations; |
46 | import org.onosproject.net.DefaultDevice; | 50 | import org.onosproject.net.DefaultDevice; |
47 | import org.onosproject.net.DefaultPort; | 51 | import org.onosproject.net.DefaultPort; |
... | @@ -61,6 +65,7 @@ import java.io.InputStream; | ... | @@ -61,6 +65,7 @@ import java.io.InputStream; |
61 | import java.net.HttpURLConnection; | 65 | import java.net.HttpURLConnection; |
62 | import java.util.HashSet; | 66 | import java.util.HashSet; |
63 | import java.util.List; | 67 | import java.util.List; |
68 | +import java.util.Set; | ||
64 | import java.util.function.BiFunction; | 69 | import java.util.function.BiFunction; |
65 | import java.util.function.BiPredicate; | 70 | import java.util.function.BiPredicate; |
66 | import java.util.function.Function; | 71 | import java.util.function.Function; |
... | @@ -80,7 +85,6 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { | ... | @@ -80,7 +85,6 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { |
80 | private CodecManager codecService; | 85 | private CodecManager codecService; |
81 | 86 | ||
82 | final HashSet<TenantId> tenantIdSet = new HashSet<>(); | 87 | final HashSet<TenantId> tenantIdSet = new HashSet<>(); |
83 | - final HashSet<VirtualNetwork> vnetSet = new HashSet<>(); | ||
84 | final HashSet<VirtualDevice> vdevSet = new HashSet<>(); | 88 | final HashSet<VirtualDevice> vdevSet = new HashSet<>(); |
85 | final HashSet<VirtualPort> vportSet = new HashSet<>(); | 89 | final HashSet<VirtualPort> vportSet = new HashSet<>(); |
86 | 90 | ||
... | @@ -90,6 +94,7 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { | ... | @@ -90,6 +94,7 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { |
90 | private static final String PORT_NUM = "portNum"; | 94 | private static final String PORT_NUM = "portNum"; |
91 | private static final String PHYS_DEVICE_ID = "physDeviceId"; | 95 | private static final String PHYS_DEVICE_ID = "physDeviceId"; |
92 | private static final String PHYS_PORT_NUM = "physPortNum"; | 96 | private static final String PHYS_PORT_NUM = "physPortNum"; |
97 | + private static final String TUNNEL_ID = "tunnelId"; | ||
93 | 98 | ||
94 | private final TenantId tenantId1 = TenantId.tenantId("TenantId1"); | 99 | private final TenantId tenantId1 = TenantId.tenantId("TenantId1"); |
95 | private final TenantId tenantId2 = TenantId.tenantId("TenantId2"); | 100 | private final TenantId tenantId2 = TenantId.tenantId("TenantId2"); |
... | @@ -106,8 +111,8 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { | ... | @@ -106,8 +111,8 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { |
106 | private final VirtualNetwork vnet3 = new DefaultVirtualNetwork(networkId3, tenantId3); | 111 | private final VirtualNetwork vnet3 = new DefaultVirtualNetwork(networkId3, tenantId3); |
107 | private final VirtualNetwork vnet4 = new DefaultVirtualNetwork(networkId4, tenantId3); | 112 | private final VirtualNetwork vnet4 = new DefaultVirtualNetwork(networkId4, tenantId3); |
108 | 113 | ||
109 | - private final DeviceId devId1 = DeviceId.deviceId("devId1"); | 114 | + private final DeviceId devId1 = DeviceId.deviceId("devid1"); |
110 | - private final DeviceId devId2 = DeviceId.deviceId("devId2"); | 115 | + private final DeviceId devId2 = DeviceId.deviceId("devid2"); |
111 | private final DeviceId devId22 = DeviceId.deviceId("dev22"); | 116 | private final DeviceId devId22 = DeviceId.deviceId("dev22"); |
112 | 117 | ||
113 | private final VirtualDevice vdev1 = new DefaultVirtualDevice(networkId3, devId1); | 118 | private final VirtualDevice vdev1 = new DefaultVirtualDevice(networkId3, devId1); |
... | @@ -115,6 +120,7 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { | ... | @@ -115,6 +120,7 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { |
115 | 120 | ||
116 | private final Device dev1 = NetTestTools.device("dev1"); | 121 | private final Device dev1 = NetTestTools.device("dev1"); |
117 | private final Device dev2 = NetTestTools.device("dev2"); | 122 | private final Device dev2 = NetTestTools.device("dev2"); |
123 | + private final Device dev21 = NetTestTools.device("dev21"); | ||
118 | private final Device dev22 = NetTestTools.device("dev22"); | 124 | private final Device dev22 = NetTestTools.device("dev22"); |
119 | 125 | ||
120 | Port port1 = new DefaultPort(dev1, portNumber(1), true); | 126 | Port port1 = new DefaultPort(dev1, portNumber(1), true); |
... | @@ -125,6 +131,15 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { | ... | @@ -125,6 +131,15 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { |
125 | private final VirtualPort vport23 = new DefaultVirtualPort(networkId3, | 131 | private final VirtualPort vport23 = new DefaultVirtualPort(networkId3, |
126 | dev22, portNumber(23), port2); | 132 | dev22, portNumber(23), port2); |
127 | 133 | ||
134 | + private final ConnectPoint cp11 = NetTestTools.connectPoint(devId1.toString(), 21); | ||
135 | + private final ConnectPoint cp21 = NetTestTools.connectPoint(devId2.toString(), 22); | ||
136 | + private final ConnectPoint cp12 = NetTestTools.connectPoint(devId1.toString(), 2); | ||
137 | + private final ConnectPoint cp22 = NetTestTools.connectPoint(devId2.toString(), 22); | ||
138 | + | ||
139 | + private final TunnelId tunnelId = TunnelId.valueOf(31); | ||
140 | + private final VirtualLink vlink1 = new DefaultVirtualLink(networkId3, cp22, cp11, tunnelId); | ||
141 | + private final VirtualLink vlink2 = new DefaultVirtualLink(networkId3, cp12, cp21, tunnelId); | ||
142 | + | ||
128 | /** | 143 | /** |
129 | * Sets up the global values for all the tests. | 144 | * Sets up the global values for all the tests. |
130 | */ | 145 | */ |
... | @@ -313,12 +328,9 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { | ... | @@ -313,12 +328,9 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { |
313 | */ | 328 | */ |
314 | @Test | 329 | @Test |
315 | public void testGetVirtualNetworksArray() { | 330 | public void testGetVirtualNetworksArray() { |
331 | + final Set<VirtualNetwork> vnetSet = ImmutableSet.of(vnet1, vnet2, vnet3, vnet4); | ||
316 | expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of(tenantId3)).anyTimes(); | 332 | expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of(tenantId3)).anyTimes(); |
317 | replay(mockVnetAdminService); | 333 | 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(); | 334 | expect(mockVnetService.getVirtualNetworks(tenantId3)).andReturn(vnetSet).anyTimes(); |
323 | replay(mockVnetService); | 335 | replay(mockVnetService); |
324 | 336 | ||
... | @@ -344,6 +356,64 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { | ... | @@ -344,6 +356,64 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { |
344 | } | 356 | } |
345 | 357 | ||
346 | /** | 358 | /** |
359 | + * Tests the result of the REST API GET for virtual networks with tenant id. | ||
360 | + */ | ||
361 | + @Test | ||
362 | + public void testGetVirtualNetworksByTenantId() { | ||
363 | + final Set<VirtualNetwork> vnetSet = ImmutableSet.of(vnet1, vnet2, vnet3, vnet4); | ||
364 | + expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of(tenantId3)).anyTimes(); | ||
365 | + replay(mockVnetAdminService); | ||
366 | + expect(mockVnetService.getVirtualNetworks(tenantId3)).andReturn(vnetSet).anyTimes(); | ||
367 | + replay(mockVnetService); | ||
368 | + | ||
369 | + WebTarget wt = target(); | ||
370 | + String response = wt.path("vnets/" + tenantId3.id()).request().get(String.class); | ||
371 | + assertThat(response, containsString("{\"vnets\":[")); | ||
372 | + | ||
373 | + final JsonObject result = Json.parse(response).asObject(); | ||
374 | + assertThat(result, notNullValue()); | ||
375 | + | ||
376 | + assertThat(result.names(), hasSize(1)); | ||
377 | + assertThat(result.names().get(0), is("vnets")); | ||
378 | + | ||
379 | + final JsonArray vnetJsonArray = result.get("vnets").asArray(); | ||
380 | + assertThat(vnetJsonArray, notNullValue()); | ||
381 | + assertEquals("Virtual networks array is not the correct size.", | ||
382 | + vnetSet.size(), vnetJsonArray.size()); | ||
383 | + | ||
384 | + vnetSet.forEach(vnet -> assertThat(vnetJsonArray, hasVnet(vnet))); | ||
385 | + | ||
386 | + verify(mockVnetService); | ||
387 | + verify(mockVnetAdminService); | ||
388 | + } | ||
389 | + | ||
390 | + /** | ||
391 | + * Tests the result of the REST API GET for virtual networks with tenant id. | ||
392 | + */ | ||
393 | + @Test | ||
394 | + public void testGetVirtualNetworksByNonExistentTenantId() { | ||
395 | + String tenantIdName = "NON_EXISTENT_TENANT_ID"; | ||
396 | + expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of(tenantId3)).anyTimes(); | ||
397 | + replay(mockVnetAdminService); | ||
398 | + expect(mockVnetService.getVirtualNetworks(anyObject())).andReturn(ImmutableSet.of()).anyTimes(); | ||
399 | + replay(mockVnetService); | ||
400 | + | ||
401 | + WebTarget wt = target(); | ||
402 | + | ||
403 | + try { | ||
404 | + wt.path("vnets/" + tenantIdName) | ||
405 | + .request() | ||
406 | + .get(String.class); | ||
407 | + fail("Get of a non-existent virtual network did not throw an exception"); | ||
408 | + } catch (NotFoundException ex) { | ||
409 | + assertThat(ex.getMessage(), containsString("HTTP 404 Not Found")); | ||
410 | + } | ||
411 | + | ||
412 | + verify(mockVnetService); | ||
413 | + verify(mockVnetAdminService); | ||
414 | + } | ||
415 | + | ||
416 | + /** | ||
347 | * Tests adding of new virtual network using POST via JSON stream. | 417 | * Tests adding of new virtual network using POST via JSON stream. |
348 | */ | 418 | */ |
349 | @Test | 419 | @Test |
... | @@ -756,5 +826,243 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { | ... | @@ -756,5 +826,243 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { |
756 | verify(mockVnetAdminService); | 826 | verify(mockVnetAdminService); |
757 | } | 827 | } |
758 | 828 | ||
759 | - // TODO Tests for Virtual Links | 829 | + // Tests for Virtual Links |
830 | + | ||
831 | + /** | ||
832 | + * Tests the result of the REST API GET when there are no virtual links. | ||
833 | + */ | ||
834 | + @Test | ||
835 | + public void testGetVirtualLinksEmptyArray() { | ||
836 | + NetworkId networkId = networkId4; | ||
837 | + expect(mockVnetService.getVirtualLinks(networkId)).andReturn(ImmutableSet.of()).anyTimes(); | ||
838 | + replay(mockVnetService); | ||
839 | + | ||
840 | + WebTarget wt = target(); | ||
841 | + String location = "vnets/" + networkId.toString() + "/links"; | ||
842 | + String response = wt.path(location).request().get(String.class); | ||
843 | + assertThat(response, is("{\"links\":[]}")); | ||
844 | + | ||
845 | + verify(mockVnetService); | ||
846 | + } | ||
847 | + | ||
848 | + /** | ||
849 | + * Tests the result of the REST API GET when virtual links are defined. | ||
850 | + */ | ||
851 | + @Test | ||
852 | + public void testGetVirtualLinksArray() { | ||
853 | + NetworkId networkId = networkId3; | ||
854 | + final Set<VirtualLink> vlinkSet = ImmutableSet.of(vlink1, vlink2); | ||
855 | + expect(mockVnetService.getVirtualLinks(networkId)).andReturn(vlinkSet).anyTimes(); | ||
856 | + replay(mockVnetService); | ||
857 | + | ||
858 | + WebTarget wt = target(); | ||
859 | + String location = "vnets/" + networkId.toString() + "/links"; | ||
860 | + String response = wt.path(location).request().get(String.class); | ||
861 | + assertThat(response, containsString("{\"links\":[")); | ||
862 | + | ||
863 | + final JsonObject result = Json.parse(response).asObject(); | ||
864 | + assertThat(result, notNullValue()); | ||
865 | + | ||
866 | + assertThat(result.names(), hasSize(1)); | ||
867 | + assertThat(result.names().get(0), is("links")); | ||
868 | + | ||
869 | + final JsonArray vnetJsonArray = result.get("links").asArray(); | ||
870 | + assertThat(vnetJsonArray, notNullValue()); | ||
871 | + assertEquals("Virtual links array is not the correct size.", | ||
872 | + vlinkSet.size(), vnetJsonArray.size()); | ||
873 | + | ||
874 | + vlinkSet.forEach(vlink -> assertThat(vnetJsonArray, hasVlink(vlink))); | ||
875 | + | ||
876 | + verify(mockVnetService); | ||
877 | + } | ||
878 | + | ||
879 | + /** | ||
880 | + * Hamcrest matcher to check that a virtual link representation in JSON matches | ||
881 | + * the actual virtual link. | ||
882 | + */ | ||
883 | + public static class VirtualLinkJsonMatcher extends LinksResourceTest.LinkJsonMatcher { | ||
884 | + private final VirtualLink vlink; | ||
885 | + private String reason = ""; | ||
886 | + | ||
887 | + public VirtualLinkJsonMatcher(VirtualLink vlinkValue) { | ||
888 | + super(vlinkValue); | ||
889 | + vlink = vlinkValue; | ||
890 | + } | ||
891 | + | ||
892 | + @Override | ||
893 | + public boolean matchesSafely(JsonObject jsonLink) { | ||
894 | + if (!super.matchesSafely(jsonLink)) { | ||
895 | + return false; | ||
896 | + } | ||
897 | + // check NetworkId | ||
898 | + String jsonNetworkId = jsonLink.get(ID).asString(); | ||
899 | + String networkId = vlink.networkId().toString(); | ||
900 | + if (!jsonNetworkId.equals(networkId)) { | ||
901 | + reason = ID + " was " + jsonNetworkId; | ||
902 | + return false; | ||
903 | + } | ||
904 | + // check TunnelId | ||
905 | + String jsonTunnelId = jsonLink.get(TUNNEL_ID).asString(); | ||
906 | + if (jsonTunnelId != null && vlink instanceof DefaultVirtualLink) { | ||
907 | + String tunnelId = ((DefaultVirtualLink) vlink).tunnelId().toString(); | ||
908 | + if (!jsonTunnelId.equals(tunnelId)) { | ||
909 | + reason = TUNNEL_ID + " was " + jsonTunnelId; | ||
910 | + return false; | ||
911 | + } | ||
912 | + } | ||
913 | + return true; | ||
914 | + } | ||
915 | + | ||
916 | + @Override | ||
917 | + public void describeTo(Description description) { | ||
918 | + description.appendText(reason); | ||
919 | + } | ||
920 | + } | ||
921 | + | ||
922 | + /** | ||
923 | + * Factory to allocate a virtual link matcher. | ||
924 | + * | ||
925 | + * @param vlink virtual link object we are looking for | ||
926 | + * @return matcher | ||
927 | + */ | ||
928 | + private static VirtualLinkJsonMatcher matchesVirtualLink(VirtualLink vlink) { | ||
929 | + return new VirtualLinkJsonMatcher(vlink); | ||
930 | + } | ||
931 | + | ||
932 | + /** | ||
933 | + * Hamcrest matcher to check that a virtual link is represented properly in a JSON | ||
934 | + * array of links. | ||
935 | + */ | ||
936 | + private static class VirtualLinkJsonArrayMatcher extends TypeSafeMatcher<JsonArray> { | ||
937 | + private final VirtualLink vlink; | ||
938 | + private String reason = ""; | ||
939 | + | ||
940 | + public VirtualLinkJsonArrayMatcher(VirtualLink vlinkValue) { | ||
941 | + vlink = vlinkValue; | ||
942 | + } | ||
943 | + | ||
944 | + @Override | ||
945 | + public boolean matchesSafely(JsonArray json) { | ||
946 | + final int expectedAttributes = 2; | ||
947 | + | ||
948 | + for (int jsonLinkIndex = 0; jsonLinkIndex < json.size(); | ||
949 | + jsonLinkIndex++) { | ||
950 | + | ||
951 | + JsonObject jsonLink = json.get(jsonLinkIndex).asObject(); | ||
952 | + | ||
953 | + if (matchesVirtualLink(vlink).matchesSafely(jsonLink)) { | ||
954 | + return true; | ||
955 | + } | ||
956 | + } | ||
957 | + return false; | ||
958 | + } | ||
959 | + | ||
960 | + @Override | ||
961 | + public void describeTo(Description description) { | ||
962 | + description.appendText(reason); | ||
963 | + } | ||
964 | + } | ||
965 | + | ||
966 | + /** | ||
967 | + * Factory to allocate a virtual link array matcher. | ||
968 | + * | ||
969 | + * @param vlink virtual link object we are looking for | ||
970 | + * @return matcher | ||
971 | + */ | ||
972 | + private VirtualLinkJsonArrayMatcher hasVlink(VirtualLink vlink) { | ||
973 | + return new VirtualLinkJsonArrayMatcher(vlink); | ||
974 | + } | ||
975 | + | ||
976 | + /** | ||
977 | + * Tests adding of new virtual link using POST via JSON stream. | ||
978 | + */ | ||
979 | + @Test | ||
980 | + public void testPostVirtualLink() { | ||
981 | + NetworkId networkId = networkId3; | ||
982 | + expect(mockVnetAdminService.createVirtualLink(networkId, cp22, cp11, tunnelId)) | ||
983 | + .andReturn(vlink1); | ||
984 | + replay(mockVnetAdminService); | ||
985 | + | ||
986 | + WebTarget wt = target(); | ||
987 | + InputStream jsonStream = VirtualNetworkWebResourceTest.class | ||
988 | + .getResourceAsStream("post-virtual-link.json"); | ||
989 | + String reqLocation = "vnets/" + networkId.toString() + "/links"; | ||
990 | + Response response = wt.path(reqLocation).request(MediaType.APPLICATION_JSON_TYPE) | ||
991 | + .post(Entity.json(jsonStream)); | ||
992 | + assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED)); | ||
993 | + | ||
994 | + String location = response.getLocation().getPath(); | ||
995 | + assertThat(location, Matchers.startsWith("/" + reqLocation)); | ||
996 | + | ||
997 | + verify(mockVnetAdminService); | ||
998 | + } | ||
999 | + | ||
1000 | + /** | ||
1001 | + * Tests adding of a null virtual link using POST via JSON stream. | ||
1002 | + */ | ||
1003 | + @Test | ||
1004 | + public void testPostVirtualLinkNullJsonStream() { | ||
1005 | + NetworkId networkId = networkId3; | ||
1006 | + replay(mockVnetAdminService); | ||
1007 | + | ||
1008 | + WebTarget wt = target(); | ||
1009 | + try { | ||
1010 | + String reqLocation = "vnets/" + networkId.toString() + "/links"; | ||
1011 | + wt.path(reqLocation) | ||
1012 | + .request(MediaType.APPLICATION_JSON_TYPE) | ||
1013 | + .post(Entity.json(null), String.class); | ||
1014 | + fail("POST of null virtual link did not throw an exception"); | ||
1015 | + } catch (BadRequestException ex) { | ||
1016 | + assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request")); | ||
1017 | + } | ||
1018 | + | ||
1019 | + verify(mockVnetAdminService); | ||
1020 | + } | ||
1021 | + | ||
1022 | + /** | ||
1023 | + * Tests removing a virtual link with DELETE request. | ||
1024 | + */ | ||
1025 | + @Test | ||
1026 | + public void testDeleteVirtualLink() { | ||
1027 | + NetworkId networkId = networkId3; | ||
1028 | + mockVnetAdminService.removeVirtualLink(networkId, cp22, cp11); | ||
1029 | + expectLastCall(); | ||
1030 | + replay(mockVnetAdminService); | ||
1031 | + | ||
1032 | + WebTarget wt = target() | ||
1033 | + .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true); | ||
1034 | + InputStream jsonStream = VirtualNetworkWebResourceTest.class | ||
1035 | + .getResourceAsStream("post-virtual-link.json"); | ||
1036 | + String reqLocation = "vnets/" + networkId.toString() + "/links"; | ||
1037 | + Response response = wt.path(reqLocation).request().accept(MediaType.APPLICATION_JSON_TYPE) | ||
1038 | + .method("DELETE", Entity.json(jsonStream)); | ||
1039 | +// Response response = wt.path(reqLocation).request().method("DELETE", Entity.json(jsonStream)); | ||
1040 | + | ||
1041 | +// assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK)); | ||
1042 | +// verify(mockVnetAdminService); | ||
1043 | + } | ||
1044 | + | ||
1045 | + /** | ||
1046 | + * Tests removing a virtual link with PUT request. | ||
1047 | + */ | ||
1048 | + @Test | ||
1049 | + public void testDeleteVirtualLink2() { | ||
1050 | + NetworkId networkId = networkId3; | ||
1051 | + mockVnetAdminService.removeVirtualLink(networkId, cp22, cp11); | ||
1052 | + expectLastCall(); | ||
1053 | + replay(mockVnetAdminService); | ||
1054 | + | ||
1055 | + WebTarget wt = target() | ||
1056 | + .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true); | ||
1057 | + InputStream jsonStream = VirtualNetworkWebResourceTest.class | ||
1058 | + .getResourceAsStream("post-virtual-link.json"); | ||
1059 | + String reqLocation = "vnets/" + networkId.toString() + "/links/remove"; | ||
1060 | + Response response = wt.path(reqLocation).request().accept(MediaType.APPLICATION_JSON_TYPE) | ||
1061 | + .method("PUT", Entity.json(jsonStream)); | ||
1062 | + | ||
1063 | + assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK)); | ||
1064 | + verify(mockVnetAdminService); | ||
1065 | + } | ||
1066 | + | ||
1067 | + // All Tests done | ||
760 | } | 1068 | } | ... | ... |
-
Please register or login to post a comment