Committed by
Gerrit Code Review
ONOS-2184 VirtualHost CLI and REST api's
Change-Id: If0ebe4268f3161a34223eca58e3f1bdbb8d0c9be
Showing
12 changed files
with
874 additions
and
28 deletions
1 | +/* | ||
2 | + * Copyright 2016-present Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onosproject.cli.net.vnet; | ||
18 | + | ||
19 | +import org.apache.karaf.shell.commands.Argument; | ||
20 | +import org.apache.karaf.shell.commands.Command; | ||
21 | +import org.apache.karaf.shell.commands.Option; | ||
22 | +import org.onlab.packet.IpAddress; | ||
23 | +import org.onlab.packet.MacAddress; | ||
24 | +import org.onlab.packet.VlanId; | ||
25 | +import org.onosproject.cli.AbstractShellCommand; | ||
26 | +import org.onosproject.incubator.net.virtual.NetworkId; | ||
27 | +import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService; | ||
28 | +import org.onosproject.net.DeviceId; | ||
29 | +import org.onosproject.net.HostId; | ||
30 | +import org.onosproject.net.HostLocation; | ||
31 | +import org.onosproject.net.PortNumber; | ||
32 | + | ||
33 | +import java.util.Arrays; | ||
34 | +import java.util.HashSet; | ||
35 | +import java.util.Set; | ||
36 | + | ||
37 | +/** | ||
38 | + * Creates a new virtual host. | ||
39 | + */ | ||
40 | +@Command(scope = "onos", name = "vnet-create-host", | ||
41 | + description = "Creates a new virtual host in a network.") | ||
42 | +public class VirtualHostCreateCommand extends AbstractShellCommand { | ||
43 | + | ||
44 | + @Argument(index = 0, name = "networkId", description = "Network ID", | ||
45 | + required = true, multiValued = false) | ||
46 | + Long networkId = null; | ||
47 | + | ||
48 | + @Argument(index = 1, name = "mac", description = "Mac address", | ||
49 | + required = true, multiValued = false) | ||
50 | + String mac = null; | ||
51 | + | ||
52 | + @Argument(index = 2, name = "vlan", description = "Vlan", | ||
53 | + required = true, multiValued = false) | ||
54 | + short vlan; | ||
55 | + | ||
56 | + @Argument(index = 3, name = "hostLocationDeviceId", description = "Host location device ID", | ||
57 | + required = true, multiValued = false) | ||
58 | + String hostLocationDeviceId; | ||
59 | + | ||
60 | + @Argument(index = 4, name = "hostLocationPortNumber", description = "Host location port number", | ||
61 | + required = true, multiValued = false) | ||
62 | + long hostLocationPortNumber; | ||
63 | + | ||
64 | + // ip addresses | ||
65 | + @Option(name = "--hostIp", description = "Host IP addresses. Can be specified multiple times.", | ||
66 | + required = false, multiValued = true) | ||
67 | + protected String[] hostIpStrings; | ||
68 | + | ||
69 | + @Override | ||
70 | + protected void execute() { | ||
71 | + VirtualNetworkAdminService service = get(VirtualNetworkAdminService.class); | ||
72 | + | ||
73 | + Set<IpAddress> hostIps = new HashSet<>(); | ||
74 | + if (hostIpStrings != null) { | ||
75 | + Arrays.asList(hostIpStrings).stream().forEach(s -> hostIps.add(IpAddress.valueOf(s))); | ||
76 | + } | ||
77 | + HostLocation hostLocation = new HostLocation(DeviceId.deviceId(hostLocationDeviceId), | ||
78 | + PortNumber.portNumber(hostLocationPortNumber), | ||
79 | + System.currentTimeMillis()); | ||
80 | + MacAddress macAddress = MacAddress.valueOf(mac); | ||
81 | + VlanId vlanId = VlanId.vlanId(vlan); | ||
82 | + service.createVirtualHost(NetworkId.networkId(networkId), | ||
83 | + HostId.hostId(macAddress, vlanId), macAddress, vlanId, | ||
84 | + hostLocation, hostIps); | ||
85 | + print("Virtual host successfully created."); | ||
86 | + } | ||
87 | +} |
1 | +/* | ||
2 | + * Copyright 2016-present Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onosproject.cli.net.vnet; | ||
18 | + | ||
19 | +import org.apache.karaf.shell.commands.Argument; | ||
20 | +import org.apache.karaf.shell.commands.Command; | ||
21 | +import org.onosproject.cli.AbstractShellCommand; | ||
22 | +import org.onosproject.incubator.net.virtual.NetworkId; | ||
23 | +import org.onosproject.incubator.net.virtual.VirtualHost; | ||
24 | +import org.onosproject.incubator.net.virtual.VirtualNetworkService; | ||
25 | + | ||
26 | +import java.util.ArrayList; | ||
27 | +import java.util.List; | ||
28 | + | ||
29 | +/** | ||
30 | + * Lists all virtual hosts for the network ID. | ||
31 | + */ | ||
32 | +@Command(scope = "onos", name = "vnet-hosts", | ||
33 | + description = "Lists all virtual hosts in a virtual network.") | ||
34 | +public class VirtualHostListCommand extends AbstractShellCommand { | ||
35 | + | ||
36 | + private static final String FMT_VIRTUAL_HOST = | ||
37 | + "id=%s, mac=%s, vlan=%s, location=%s, ips=%s"; | ||
38 | + | ||
39 | + @Argument(index = 0, name = "networkId", description = "Network ID", | ||
40 | + required = true, multiValued = false) | ||
41 | + Long networkId = null; | ||
42 | + | ||
43 | + @Override | ||
44 | + protected void execute() { | ||
45 | + getSortedVirtualHosts().forEach(this::printVirtualHost); | ||
46 | + } | ||
47 | + | ||
48 | + /** | ||
49 | + * Returns the list of virtual hosts sorted using the device identifier. | ||
50 | + * | ||
51 | + * @return virtual host list | ||
52 | + */ | ||
53 | + private List<VirtualHost> getSortedVirtualHosts() { | ||
54 | + VirtualNetworkService service = get(VirtualNetworkService.class); | ||
55 | + | ||
56 | + List<VirtualHost> virtualHosts = new ArrayList<>(); | ||
57 | + virtualHosts.addAll(service.getVirtualHosts(NetworkId.networkId(networkId))); | ||
58 | + return virtualHosts; | ||
59 | + } | ||
60 | + | ||
61 | + /** | ||
62 | + * Prints out each virtual host. | ||
63 | + * | ||
64 | + * @param virtualHost virtual host | ||
65 | + */ | ||
66 | + private void printVirtualHost(VirtualHost virtualHost) { | ||
67 | + print(FMT_VIRTUAL_HOST, virtualHost.id().toString(), virtualHost.mac().toString(), | ||
68 | + virtualHost.vlan().toString(), virtualHost.location().toString(), | ||
69 | + virtualHost.ipAddresses().toString()); | ||
70 | + } | ||
71 | +} |
1 | +/* | ||
2 | + * Copyright 2016-present Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.onosproject.cli.net.vnet; | ||
18 | + | ||
19 | +import org.apache.karaf.shell.commands.Argument; | ||
20 | +import org.apache.karaf.shell.commands.Command; | ||
21 | +import org.onosproject.cli.AbstractShellCommand; | ||
22 | +import org.onosproject.incubator.net.virtual.NetworkId; | ||
23 | +import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService; | ||
24 | +import org.onosproject.net.HostId; | ||
25 | +//import org.onosproject.net.HostId; | ||
26 | + | ||
27 | +/** | ||
28 | + * Removes a virtual host. | ||
29 | + */ | ||
30 | + | ||
31 | +@Command(scope = "onos", name = "vnet-remove-host", | ||
32 | + description = "Removes a virtual host.") | ||
33 | +public class VirtualHostRemoveCommand extends AbstractShellCommand { | ||
34 | + | ||
35 | + @Argument(index = 0, name = "networkId", description = "Network ID", | ||
36 | + required = true, multiValued = false) | ||
37 | + Long networkId = null; | ||
38 | + | ||
39 | + @Argument(index = 1, name = "id", description = "Host ID", | ||
40 | + required = true, multiValued = false) | ||
41 | + String id = null; | ||
42 | + | ||
43 | + @Override | ||
44 | + protected void execute() { | ||
45 | + VirtualNetworkAdminService service = get(VirtualNetworkAdminService.class); | ||
46 | + service.removeVirtualHost(NetworkId.networkId(networkId), HostId.hostId(id)); | ||
47 | + print("Virtual host successfully removed."); | ||
48 | + } | ||
49 | +} |
... | @@ -674,6 +674,15 @@ | ... | @@ -674,6 +674,15 @@ |
674 | <command> | 674 | <command> |
675 | <action class="org.onosproject.cli.net.vnet.VirtualPortRemoveCommand"/> | 675 | <action class="org.onosproject.cli.net.vnet.VirtualPortRemoveCommand"/> |
676 | </command> | 676 | </command> |
677 | + <command> | ||
678 | + <action class="org.onosproject.cli.net.vnet.VirtualHostListCommand"/> | ||
679 | + </command> | ||
680 | + <command> | ||
681 | + <action class="org.onosproject.cli.net.vnet.VirtualHostCreateCommand"/> | ||
682 | + </command> | ||
683 | + <command> | ||
684 | + <action class="org.onosproject.cli.net.vnet.VirtualHostRemoveCommand"/> | ||
685 | + </command> | ||
677 | </command-bundle> | 686 | </command-bundle> |
678 | 687 | ||
679 | <bean id="reviewAppNameCompleter" class="org.onosproject.cli.security.ReviewApplicationNameCompleter"/> | 688 | <bean id="reviewAppNameCompleter" class="org.onosproject.cli.security.ReviewApplicationNameCompleter"/> | ... | ... |
... | @@ -30,6 +30,7 @@ import org.onosproject.core.Application; | ... | @@ -30,6 +30,7 @@ import org.onosproject.core.Application; |
30 | import org.onosproject.core.ApplicationId; | 30 | import org.onosproject.core.ApplicationId; |
31 | import org.onosproject.incubator.net.virtual.TenantId; | 31 | import org.onosproject.incubator.net.virtual.TenantId; |
32 | import org.onosproject.incubator.net.virtual.VirtualDevice; | 32 | import org.onosproject.incubator.net.virtual.VirtualDevice; |
33 | +import org.onosproject.incubator.net.virtual.VirtualHost; | ||
33 | import org.onosproject.incubator.net.virtual.VirtualLink; | 34 | import org.onosproject.incubator.net.virtual.VirtualLink; |
34 | import org.onosproject.incubator.net.virtual.VirtualNetwork; | 35 | import org.onosproject.incubator.net.virtual.VirtualNetwork; |
35 | import org.onosproject.incubator.net.virtual.VirtualPort; | 36 | import org.onosproject.incubator.net.virtual.VirtualPort; |
... | @@ -141,6 +142,7 @@ public class CodecManager implements CodecService { | ... | @@ -141,6 +142,7 @@ public class CodecManager implements CodecService { |
141 | registerCodec(VirtualDevice.class, new VirtualDeviceCodec()); | 142 | registerCodec(VirtualDevice.class, new VirtualDeviceCodec()); |
142 | registerCodec(VirtualPort.class, new VirtualPortCodec()); | 143 | registerCodec(VirtualPort.class, new VirtualPortCodec()); |
143 | registerCodec(VirtualLink.class, new VirtualLinkCodec()); | 144 | registerCodec(VirtualLink.class, new VirtualLinkCodec()); |
145 | + registerCodec(VirtualHost.class, new VirtualHostCodec()); | ||
144 | registerCodec(MastershipTerm.class, new MastershipTermCodec()); | 146 | registerCodec(MastershipTerm.class, new MastershipTermCodec()); |
145 | registerCodec(MastershipRole.class, new MastershipRoleCodec()); | 147 | registerCodec(MastershipRole.class, new MastershipRoleCodec()); |
146 | registerCodec(RoleInfo.class, new RoleInfoCodec()); | 148 | registerCodec(RoleInfo.class, new RoleInfoCodec()); | ... | ... |
1 | +/* | ||
2 | + * Copyright 2016-present Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onosproject.codec.impl; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.JsonNode; | ||
19 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
20 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
21 | +import org.onlab.packet.IpAddress; | ||
22 | +import org.onlab.packet.MacAddress; | ||
23 | +import org.onlab.packet.VlanId; | ||
24 | +import org.onosproject.codec.CodecContext; | ||
25 | +import org.onosproject.codec.JsonCodec; | ||
26 | +import org.onosproject.incubator.net.virtual.DefaultVirtualHost; | ||
27 | +import org.onosproject.incubator.net.virtual.NetworkId; | ||
28 | +import org.onosproject.incubator.net.virtual.VirtualHost; | ||
29 | +import org.onosproject.net.DeviceId; | ||
30 | +import org.onosproject.net.HostId; | ||
31 | +import org.onosproject.net.HostLocation; | ||
32 | +import org.onosproject.net.PortNumber; | ||
33 | + | ||
34 | +import java.util.HashSet; | ||
35 | +import java.util.Iterator; | ||
36 | +import java.util.Set; | ||
37 | + | ||
38 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
39 | +import static org.onlab.util.Tools.nullIsIllegal; | ||
40 | + | ||
41 | +/** | ||
42 | + * Codec for the VirtualHost class. | ||
43 | + */ | ||
44 | +public class VirtualHostCodec extends JsonCodec<VirtualHost> { | ||
45 | + | ||
46 | + // JSON field names | ||
47 | + private static final String NETWORK_ID = "networkId"; | ||
48 | + private static final String HOST_ID = "id"; | ||
49 | + private static final String MAC_ADDRESS = "mac"; | ||
50 | + private static final String VLAN = "vlan"; | ||
51 | + private static final String IP_ADDRESSES = "ipAddresses"; | ||
52 | + private static final String HOST_LOCATION = "location"; | ||
53 | + | ||
54 | + private static final String NULL_OBJECT_MSG = "VirtualHost cannot be null"; | ||
55 | + private static final String MISSING_MEMBER_MSG = " member is required in VirtualHost"; | ||
56 | + | ||
57 | + @Override | ||
58 | + public ObjectNode encode(VirtualHost vHost, CodecContext context) { | ||
59 | + checkNotNull(vHost, NULL_OBJECT_MSG); | ||
60 | + | ||
61 | + final JsonCodec<HostLocation> locationCodec = | ||
62 | + context.codec(HostLocation.class); | ||
63 | + final ObjectNode result = context.mapper().createObjectNode() | ||
64 | + .put(NETWORK_ID, vHost.networkId().toString()) | ||
65 | + .put(HOST_ID, vHost.id().toString()) | ||
66 | + .put(MAC_ADDRESS, vHost.mac().toString()) | ||
67 | + .put(VLAN, vHost.vlan().toString()); | ||
68 | + | ||
69 | + final ArrayNode jsonIpAddresses = result.putArray(IP_ADDRESSES); | ||
70 | + for (final IpAddress ipAddress : vHost.ipAddresses()) { | ||
71 | + jsonIpAddresses.add(ipAddress.toString()); | ||
72 | + } | ||
73 | + result.set(IP_ADDRESSES, jsonIpAddresses); | ||
74 | + result.set(HOST_LOCATION, locationCodec.encode(vHost.location(), context)); | ||
75 | + | ||
76 | + return result; | ||
77 | + } | ||
78 | + | ||
79 | + @Override | ||
80 | + public VirtualHost decode(ObjectNode json, CodecContext context) { | ||
81 | + if (json == null || !json.isObject()) { | ||
82 | + return null; | ||
83 | + } | ||
84 | + | ||
85 | + NetworkId nId = NetworkId.networkId(Long.parseLong(extractMember(NETWORK_ID, json))); | ||
86 | + MacAddress mac = MacAddress.valueOf(json.get("mac").asText()); | ||
87 | + VlanId vlanId = VlanId.vlanId((short) json.get("vlan").asInt(VlanId.UNTAGGED)); | ||
88 | + JsonNode locationNode = json.get("location"); | ||
89 | + PortNumber portNumber = PortNumber.portNumber(locationNode.get("port").asText()); | ||
90 | + DeviceId deviceId = DeviceId.deviceId(locationNode.get("elementId").asText()); | ||
91 | + HostLocation hostLocation = new HostLocation(deviceId, portNumber, 0); | ||
92 | + HostId id = HostId.hostId(mac, vlanId); | ||
93 | + | ||
94 | + Iterator<JsonNode> ipStrings = json.get("ipAddresses").elements(); | ||
95 | + Set<IpAddress> ips = new HashSet<>(); | ||
96 | + while (ipStrings.hasNext()) { | ||
97 | + ips.add(IpAddress.valueOf(ipStrings.next().asText())); | ||
98 | + } | ||
99 | + | ||
100 | + return new DefaultVirtualHost(nId, id, mac, vlanId, hostLocation, ips); | ||
101 | + } | ||
102 | + | ||
103 | + /** | ||
104 | + * Extract member from JSON ObjectNode. | ||
105 | + * | ||
106 | + * @param key key for which value is needed | ||
107 | + * @param json JSON ObjectNode | ||
108 | + * @return member value | ||
109 | + */ | ||
110 | + private String extractMember(String key, ObjectNode json) { | ||
111 | + return nullIsIllegal(json.get(key), key + MISSING_MEMBER_MSG).asText(); | ||
112 | + } | ||
113 | +} |
... | @@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; | ... | @@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; |
21 | import org.onosproject.incubator.net.virtual.NetworkId; | 21 | import org.onosproject.incubator.net.virtual.NetworkId; |
22 | import org.onosproject.incubator.net.virtual.TenantId; | 22 | import org.onosproject.incubator.net.virtual.TenantId; |
23 | import org.onosproject.incubator.net.virtual.VirtualDevice; | 23 | import org.onosproject.incubator.net.virtual.VirtualDevice; |
24 | +import org.onosproject.incubator.net.virtual.VirtualHost; | ||
24 | import org.onosproject.incubator.net.virtual.VirtualLink; | 25 | import org.onosproject.incubator.net.virtual.VirtualLink; |
25 | import org.onosproject.incubator.net.virtual.VirtualNetwork; | 26 | import org.onosproject.incubator.net.virtual.VirtualNetwork; |
26 | import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService; | 27 | import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService; |
... | @@ -390,6 +391,87 @@ public class VirtualNetworkWebResource extends AbstractWebResource { | ... | @@ -390,6 +391,87 @@ public class VirtualNetworkWebResource extends AbstractWebResource { |
390 | } | 391 | } |
391 | 392 | ||
392 | /** | 393 | /** |
394 | + * Returns all virtual network hosts in a virtual network. | ||
395 | + * | ||
396 | + * @param networkId network identifier | ||
397 | + * @return 200 OK with set of virtual network hosts | ||
398 | + * @onos.rsModel VirtualHosts | ||
399 | + */ | ||
400 | + @GET | ||
401 | + @Produces(MediaType.APPLICATION_JSON) | ||
402 | + @Path("{networkId}/hosts") | ||
403 | + public Response getVirtualHosts(@PathParam("networkId") long networkId) { | ||
404 | + NetworkId nid = NetworkId.networkId(networkId); | ||
405 | + Set<VirtualHost> vhosts = vnetService.getVirtualHosts(nid); | ||
406 | + return ok(encodeArray(VirtualHost.class, "hosts", vhosts)).build(); | ||
407 | + } | ||
408 | + | ||
409 | + /** | ||
410 | + * Creates a virtual network host from the JSON input stream. | ||
411 | + * | ||
412 | + * @param networkId network identifier | ||
413 | + * @param stream virtual host JSON stream | ||
414 | + * @return status of the request - CREATED if the JSON is correct, | ||
415 | + * BAD_REQUEST if the JSON is invalid | ||
416 | + * @onos.rsModel VirtualHostPut | ||
417 | + */ | ||
418 | + @POST | ||
419 | + @Path("{networkId}/hosts") | ||
420 | + @Consumes(MediaType.APPLICATION_JSON) | ||
421 | + @Produces(MediaType.APPLICATION_JSON) | ||
422 | + public Response createVirtualHost(@PathParam("networkId") long networkId, | ||
423 | + InputStream stream) { | ||
424 | + try { | ||
425 | + ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); | ||
426 | + JsonNode specifiedNetworkId = jsonTree.get("networkId"); | ||
427 | + if (specifiedNetworkId == null || specifiedNetworkId.asLong() != (networkId)) { | ||
428 | + throw new IllegalArgumentException(INVALID_FIELD + "networkId"); | ||
429 | + } | ||
430 | + final VirtualHost vhostReq = codec(VirtualHost.class).decode(jsonTree, this); | ||
431 | + vnetAdminService.createVirtualHost(vhostReq.networkId(), vhostReq.id(), | ||
432 | + vhostReq.mac(), vhostReq.vlan(), | ||
433 | + vhostReq.location(), vhostReq.ipAddresses()); | ||
434 | + UriBuilder locationBuilder = uriInfo.getBaseUriBuilder() | ||
435 | + .path("vnets").path(specifiedNetworkId.asText()) | ||
436 | + .path("hosts"); | ||
437 | + return Response | ||
438 | + .created(locationBuilder.build()) | ||
439 | + .build(); | ||
440 | + } catch (IOException e) { | ||
441 | + throw new IllegalArgumentException(e); | ||
442 | + } | ||
443 | + } | ||
444 | + | ||
445 | + /** | ||
446 | + * Removes the virtual network host from the JSON input stream. | ||
447 | + * | ||
448 | + * @param networkId network identifier | ||
449 | + * @param stream virtual host JSON stream | ||
450 | + * @return 204 NO CONTENT | ||
451 | + * @onos.rsModel VirtualHost | ||
452 | + */ | ||
453 | + @DELETE | ||
454 | + @Path("{networkId}/hosts") | ||
455 | + @Consumes(MediaType.APPLICATION_JSON) | ||
456 | + public Response removeVirtualHost(@PathParam("networkId") long networkId, | ||
457 | + InputStream stream) { | ||
458 | + try { | ||
459 | + ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); | ||
460 | + JsonNode specifiedNetworkId = jsonTree.get("networkId"); | ||
461 | + if (specifiedNetworkId != null && | ||
462 | + specifiedNetworkId.asLong() != (networkId)) { | ||
463 | + throw new IllegalArgumentException(INVALID_FIELD + "networkId"); | ||
464 | + } | ||
465 | + final VirtualHost vhostReq = codec(VirtualHost.class).decode(jsonTree, this); | ||
466 | + vnetAdminService.removeVirtualHost(vhostReq.networkId(), vhostReq.id()); | ||
467 | + } catch (IOException e) { | ||
468 | + throw new IllegalArgumentException(e); | ||
469 | + } | ||
470 | + | ||
471 | + return Response.noContent().build(); | ||
472 | + } | ||
473 | + | ||
474 | + /** | ||
393 | * Get the tenant identifier from the JSON stream. | 475 | * Get the tenant identifier from the JSON stream. |
394 | * | 476 | * |
395 | * @param stream TenantId JSON stream | 477 | * @param stream TenantId JSON stream | ... | ... |
1 | +{ | ||
2 | + "type": "object", | ||
3 | + "title": "host", | ||
4 | + "required": [ | ||
5 | + "networkId", | ||
6 | + "id", | ||
7 | + "mac", | ||
8 | + "vlan", | ||
9 | + "ipAddresses", | ||
10 | + "location" | ||
11 | + ], | ||
12 | + "properties": { | ||
13 | + "networkId": { | ||
14 | + "type": "int64", | ||
15 | + "description": "Network identifier", | ||
16 | + "example": 3 | ||
17 | + }, | ||
18 | + "id": { | ||
19 | + "type": "string", | ||
20 | + "example": "46:E4:3C:A4:17:C8/-1" | ||
21 | + }, | ||
22 | + "mac": { | ||
23 | + "type": "string", | ||
24 | + "example": "46:E4:3C:A4:17:C8" | ||
25 | + }, | ||
26 | + "vlan": { | ||
27 | + "type": "string", | ||
28 | + "example": "-1" | ||
29 | + }, | ||
30 | + "ipAddresses": { | ||
31 | + "type": "array", | ||
32 | + "xml": { | ||
33 | + "name": "hosts", | ||
34 | + "wrapped": true | ||
35 | + }, | ||
36 | + "items": { | ||
37 | + "type": "string", | ||
38 | + "example": "127.0.0.1" | ||
39 | + } | ||
40 | + }, | ||
41 | + "location": { | ||
42 | + "type": "object", | ||
43 | + "title": "location", | ||
44 | + "required": [ | ||
45 | + "elementId", | ||
46 | + "port" | ||
47 | + ], | ||
48 | + "properties": { | ||
49 | + "elementId": { | ||
50 | + "type": "string", | ||
51 | + "example": "of:0000000000000002" | ||
52 | + }, | ||
53 | + "port": { | ||
54 | + "type": "string", | ||
55 | + "example": "3" | ||
56 | + } | ||
57 | + } | ||
58 | + } | ||
59 | + } | ||
60 | +} |
1 | +{ | ||
2 | + "type": "object", | ||
3 | + "title": "host", | ||
4 | + "required": [ | ||
5 | + "networkId", | ||
6 | + "mac", | ||
7 | + "vlan", | ||
8 | + "ipAddresses", | ||
9 | + "location" | ||
10 | + ], | ||
11 | + "properties": { | ||
12 | + "networkId": { | ||
13 | + "type": "int64", | ||
14 | + "description": "Network identifier", | ||
15 | + "example": 3 | ||
16 | + }, | ||
17 | + "mac": { | ||
18 | + "type": "string", | ||
19 | + "example": "46:E4:3C:A4:17:C8" | ||
20 | + }, | ||
21 | + "vlan": { | ||
22 | + "type": "string", | ||
23 | + "example": "-1" | ||
24 | + }, | ||
25 | + "ipAddresses": { | ||
26 | + "type": "array", | ||
27 | + "xml": { | ||
28 | + "name": "hosts", | ||
29 | + "wrapped": true | ||
30 | + }, | ||
31 | + "items": { | ||
32 | + "type": "string", | ||
33 | + "example": "127.0.0.1" | ||
34 | + } | ||
35 | + }, | ||
36 | + "location": { | ||
37 | + "type": "object", | ||
38 | + "title": "location", | ||
39 | + "required": [ | ||
40 | + "elementId", | ||
41 | + "port" | ||
42 | + ], | ||
43 | + "properties": { | ||
44 | + "elementId": { | ||
45 | + "type": "string", | ||
46 | + "example": "of:0000000000000002" | ||
47 | + }, | ||
48 | + "port": { | ||
49 | + "type": "string", | ||
50 | + "example": "3" | ||
51 | + } | ||
52 | + } | ||
53 | + } | ||
54 | + } | ||
55 | +} |
1 | +{ | ||
2 | + "type": "object", | ||
3 | + "title": "hosts", | ||
4 | + "required": [ | ||
5 | + "hosts" | ||
6 | + ], | ||
7 | + "properties": { | ||
8 | + "hosts": { | ||
9 | + "type": "array", | ||
10 | + "xml": { | ||
11 | + "name": "hosts", | ||
12 | + "wrapped": true | ||
13 | + }, | ||
14 | + "items": { | ||
15 | + "type": "object", | ||
16 | + "title": "host", | ||
17 | + "required": [ | ||
18 | + "networkId", | ||
19 | + "id", | ||
20 | + "mac", | ||
21 | + "vlan", | ||
22 | + "ipAddresses", | ||
23 | + "location" | ||
24 | + ], | ||
25 | + "properties": { | ||
26 | + "networkId": { | ||
27 | + "type": "int64", | ||
28 | + "description": "Network identifier", | ||
29 | + "example": 3 | ||
30 | + }, | ||
31 | + "id": { | ||
32 | + "type": "string", | ||
33 | + "example": "46:E4:3C:A4:17:C8/-1" | ||
34 | + }, | ||
35 | + "mac": { | ||
36 | + "type": "string", | ||
37 | + "example": "46:E4:3C:A4:17:C8" | ||
38 | + }, | ||
39 | + "vlan": { | ||
40 | + "type": "string", | ||
41 | + "example": "-1" | ||
42 | + }, | ||
43 | + "ipAddresses": { | ||
44 | + "type": "array", | ||
45 | + "xml": { | ||
46 | + "name": "hosts", | ||
47 | + "wrapped": true | ||
48 | + }, | ||
49 | + "items": { | ||
50 | + "type": "string", | ||
51 | + "example": "127.0.0.1" | ||
52 | + } | ||
53 | + }, | ||
54 | + "location": { | ||
55 | + "type": "object", | ||
56 | + "title": "location", | ||
57 | + "required": [ | ||
58 | + "elementId", | ||
59 | + "port" | ||
60 | + ], | ||
61 | + "properties": { | ||
62 | + "elementId": { | ||
63 | + "type": "string", | ||
64 | + "example": "of:0000000000000002" | ||
65 | + }, | ||
66 | + "port": { | ||
67 | + "type": "string", | ||
68 | + "example": "3" | ||
69 | + } | ||
70 | + } | ||
71 | + } | ||
72 | + } | ||
73 | + } | ||
74 | + } | ||
75 | + } | ||
76 | +} |
... | @@ -21,6 +21,7 @@ import com.eclipsesource.json.JsonArray; | ... | @@ -21,6 +21,7 @@ import com.eclipsesource.json.JsonArray; |
21 | import com.eclipsesource.json.JsonObject; | 21 | import com.eclipsesource.json.JsonObject; |
22 | import com.google.common.collect.ImmutableList; | 22 | import com.google.common.collect.ImmutableList; |
23 | import com.google.common.collect.ImmutableSet; | 23 | import com.google.common.collect.ImmutableSet; |
24 | +import com.google.common.collect.Sets; | ||
24 | import org.glassfish.jersey.client.ClientProperties; | 25 | import org.glassfish.jersey.client.ClientProperties; |
25 | import org.hamcrest.Description; | 26 | import org.hamcrest.Description; |
26 | import org.hamcrest.Matchers; | 27 | import org.hamcrest.Matchers; |
... | @@ -29,16 +30,21 @@ import org.junit.Before; | ... | @@ -29,16 +30,21 @@ import org.junit.Before; |
29 | import org.junit.Test; | 30 | import org.junit.Test; |
30 | import org.onlab.osgi.ServiceDirectory; | 31 | import org.onlab.osgi.ServiceDirectory; |
31 | import org.onlab.osgi.TestServiceDirectory; | 32 | import org.onlab.osgi.TestServiceDirectory; |
33 | +import org.onlab.packet.IpAddress; | ||
34 | +import org.onlab.packet.MacAddress; | ||
35 | +import org.onlab.packet.VlanId; | ||
32 | import org.onlab.rest.BaseResource; | 36 | import org.onlab.rest.BaseResource; |
33 | import org.onosproject.codec.CodecService; | 37 | import org.onosproject.codec.CodecService; |
34 | import org.onosproject.codec.impl.CodecManager; | 38 | import org.onosproject.codec.impl.CodecManager; |
35 | import org.onosproject.incubator.net.virtual.DefaultVirtualDevice; | 39 | import org.onosproject.incubator.net.virtual.DefaultVirtualDevice; |
40 | +import org.onosproject.incubator.net.virtual.DefaultVirtualHost; | ||
36 | import org.onosproject.incubator.net.virtual.DefaultVirtualLink; | 41 | import org.onosproject.incubator.net.virtual.DefaultVirtualLink; |
37 | import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork; | 42 | import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork; |
38 | import org.onosproject.incubator.net.virtual.DefaultVirtualPort; | 43 | import org.onosproject.incubator.net.virtual.DefaultVirtualPort; |
39 | import org.onosproject.incubator.net.virtual.NetworkId; | 44 | import org.onosproject.incubator.net.virtual.NetworkId; |
40 | import org.onosproject.incubator.net.virtual.TenantId; | 45 | import org.onosproject.incubator.net.virtual.TenantId; |
41 | import org.onosproject.incubator.net.virtual.VirtualDevice; | 46 | import org.onosproject.incubator.net.virtual.VirtualDevice; |
47 | +import org.onosproject.incubator.net.virtual.VirtualHost; | ||
42 | import org.onosproject.incubator.net.virtual.VirtualLink; | 48 | import org.onosproject.incubator.net.virtual.VirtualLink; |
43 | import org.onosproject.incubator.net.virtual.VirtualNetwork; | 49 | import org.onosproject.incubator.net.virtual.VirtualNetwork; |
44 | import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService; | 50 | import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService; |
... | @@ -50,6 +56,8 @@ import org.onosproject.net.DefaultDevice; | ... | @@ -50,6 +56,8 @@ import org.onosproject.net.DefaultDevice; |
50 | import org.onosproject.net.DefaultPort; | 56 | import org.onosproject.net.DefaultPort; |
51 | import org.onosproject.net.Device; | 57 | import org.onosproject.net.Device; |
52 | import org.onosproject.net.DeviceId; | 58 | import org.onosproject.net.DeviceId; |
59 | +import org.onosproject.net.HostId; | ||
60 | +import org.onosproject.net.HostLocation; | ||
53 | import org.onosproject.net.NetTestTools; | 61 | import org.onosproject.net.NetTestTools; |
54 | import org.onosproject.net.Port; | 62 | import org.onosproject.net.Port; |
55 | import org.onosproject.net.PortNumber; | 63 | import org.onosproject.net.PortNumber; |
... | @@ -93,9 +101,8 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { | ... | @@ -93,9 +101,8 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { |
93 | private final VirtualNetworkService mockVnetService = createMock(VirtualNetworkService.class); | 101 | private final VirtualNetworkService mockVnetService = createMock(VirtualNetworkService.class); |
94 | private CodecManager codecService; | 102 | private CodecManager codecService; |
95 | 103 | ||
96 | - final HashSet<TenantId> tenantIdSet = new HashSet<>(); | 104 | + private final HashSet<VirtualDevice> vdevSet = new HashSet<>(); |
97 | - final HashSet<VirtualDevice> vdevSet = new HashSet<>(); | 105 | + private final HashSet<VirtualPort> vportSet = new HashSet<>(); |
98 | - final HashSet<VirtualPort> vportSet = new HashSet<>(); | ||
99 | 106 | ||
100 | private static final String ID = "networkId"; | 107 | private static final String ID = "networkId"; |
101 | private static final String TENANT_ID = "tenantId"; | 108 | private static final String TENANT_ID = "tenantId"; |
... | @@ -104,7 +111,6 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { | ... | @@ -104,7 +111,6 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { |
104 | private static final String PHYS_DEVICE_ID = "physDeviceId"; | 111 | private static final String PHYS_DEVICE_ID = "physDeviceId"; |
105 | private static final String PHYS_PORT_NUM = "physPortNum"; | 112 | private static final String PHYS_PORT_NUM = "physPortNum"; |
106 | 113 | ||
107 | - private final TenantId tenantId1 = TenantId.tenantId("TenantId1"); | ||
108 | private final TenantId tenantId2 = TenantId.tenantId("TenantId2"); | 114 | private final TenantId tenantId2 = TenantId.tenantId("TenantId2"); |
109 | private final TenantId tenantId3 = TenantId.tenantId("TenantId3"); | 115 | private final TenantId tenantId3 = TenantId.tenantId("TenantId3"); |
110 | private final TenantId tenantId4 = TenantId.tenantId("TenantId4"); | 116 | private final TenantId tenantId4 = TenantId.tenantId("TenantId4"); |
... | @@ -128,11 +134,10 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { | ... | @@ -128,11 +134,10 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { |
128 | 134 | ||
129 | private final Device dev1 = NetTestTools.device("dev1"); | 135 | private final Device dev1 = NetTestTools.device("dev1"); |
130 | private final Device dev2 = NetTestTools.device("dev2"); | 136 | private final Device dev2 = NetTestTools.device("dev2"); |
131 | - private final Device dev21 = NetTestTools.device("dev21"); | ||
132 | private final Device dev22 = NetTestTools.device("dev22"); | 137 | private final Device dev22 = NetTestTools.device("dev22"); |
133 | 138 | ||
134 | - Port port1 = new DefaultPort(dev1, portNumber(1), true); | 139 | + private final Port port1 = new DefaultPort(dev1, portNumber(1), true); |
135 | - Port port2 = new DefaultPort(dev2, portNumber(2), true); | 140 | + private final Port port2 = new DefaultPort(dev2, portNumber(2), true); |
136 | 141 | ||
137 | private final VirtualPort vport22 = new DefaultVirtualPort(networkId3, | 142 | private final VirtualPort vport22 = new DefaultVirtualPort(networkId3, |
138 | dev22, portNumber(22), port1); | 143 | dev22, portNumber(22), port1); |
... | @@ -156,6 +161,28 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { | ... | @@ -156,6 +161,28 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { |
156 | .dst(cp21) | 161 | .dst(cp21) |
157 | .build(); | 162 | .build(); |
158 | 163 | ||
164 | + private final MacAddress mac1 = MacAddress.valueOf("00:11:00:00:00:01"); | ||
165 | + private final MacAddress mac2 = MacAddress.valueOf("00:22:00:00:00:02"); | ||
166 | + private final VlanId vlan1 = VlanId.vlanId((short) 11); | ||
167 | + private final VlanId vlan2 = VlanId.vlanId((short) 22); | ||
168 | + private final IpAddress ip1 = IpAddress.valueOf("10.0.0.1"); | ||
169 | + private final IpAddress ip2 = IpAddress.valueOf("10.0.0.2"); | ||
170 | + private final IpAddress ip3 = IpAddress.valueOf("10.0.0.3"); | ||
171 | + | ||
172 | + private final HostId hId1 = HostId.hostId(mac1, vlan1); | ||
173 | + private final HostId hId2 = HostId.hostId(mac2, vlan2); | ||
174 | + private final HostLocation loc1 = new HostLocation(devId1, portNumber(100), 123L); | ||
175 | + private final HostLocation loc2 = new HostLocation(devId2, portNumber(200), 123L); | ||
176 | + private final Set<IpAddress> ipSet1 = Sets.newHashSet(ip1, ip2); | ||
177 | + private final Set<IpAddress> ipSet2 = Sets.newHashSet(ip1, ip3); | ||
178 | + private final VirtualHost vhost1 = new DefaultVirtualHost(networkId1, hId1, | ||
179 | + mac1, vlan1, loc1, ipSet1); | ||
180 | + private final VirtualHost vhost2 = new DefaultVirtualHost(networkId2, hId2, | ||
181 | + mac2, vlan2, loc2, ipSet2); | ||
182 | + | ||
183 | + | ||
184 | + | ||
185 | + | ||
159 | /** | 186 | /** |
160 | * Sets up the global values for all the tests. | 187 | * Sets up the global values for all the tests. |
161 | */ | 188 | */ |
... | @@ -177,15 +204,15 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { | ... | @@ -177,15 +204,15 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { |
177 | * Hamcrest matcher to check that a virtual network entity representation in JSON matches | 204 | * Hamcrest matcher to check that a virtual network entity representation in JSON matches |
178 | * the actual virtual network entity. | 205 | * the actual virtual network entity. |
179 | */ | 206 | */ |
180 | - public static class JsonObjectMatcher<T> extends TypeSafeMatcher<JsonObject> { | 207 | + private static final class JsonObjectMatcher<T> extends TypeSafeMatcher<JsonObject> { |
181 | private final T vnetEntity; | 208 | private final T vnetEntity; |
182 | private List<String> jsonFieldNames; | 209 | private List<String> jsonFieldNames; |
183 | private String reason = ""; | 210 | private String reason = ""; |
184 | private BiFunction<T, String, String> getValue; // get vnetEntity's value | 211 | private BiFunction<T, String, String> getValue; // get vnetEntity's value |
185 | 212 | ||
186 | - public JsonObjectMatcher(T vnetEntityValue, | 213 | + private JsonObjectMatcher(T vnetEntityValue, |
187 | - List<String> jsonFieldNames1, | 214 | + List<String> jsonFieldNames1, |
188 | - BiFunction<T, String, String> getValue1) { | 215 | + BiFunction<T, String, String> getValue1) { |
189 | vnetEntity = vnetEntityValue; | 216 | vnetEntity = vnetEntityValue; |
190 | jsonFieldNames = jsonFieldNames1; | 217 | jsonFieldNames = jsonFieldNames1; |
191 | getValue = getValue1; | 218 | getValue = getValue1; |
... | @@ -238,7 +265,7 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { | ... | @@ -238,7 +265,7 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { |
238 | * Hamcrest matcher to check that a virtual network entity is represented properly in a JSON | 265 | * Hamcrest matcher to check that a virtual network entity is represented properly in a JSON |
239 | * array of virtual network entities. | 266 | * array of virtual network entities. |
240 | */ | 267 | */ |
241 | - public static class JsonArrayMatcher<T> extends TypeSafeMatcher<JsonArray> { | 268 | + protected static class JsonArrayMatcher<T> extends TypeSafeMatcher<JsonArray> { |
242 | private final T vnetEntity; | 269 | private final T vnetEntity; |
243 | private String reason = ""; | 270 | private String reason = ""; |
244 | private Function<T, String> getKey; // gets vnetEntity's key | 271 | private Function<T, String> getKey; // gets vnetEntity's key |
... | @@ -246,10 +273,10 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { | ... | @@ -246,10 +273,10 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { |
246 | private List<String> jsonFieldNames; // field/property names | 273 | private List<String> jsonFieldNames; // field/property names |
247 | private BiFunction<T, String, String> getValue; // get vnetEntity's value | 274 | private BiFunction<T, String, String> getValue; // get vnetEntity's value |
248 | 275 | ||
249 | - public JsonArrayMatcher(T vnetEntityValue, Function<T, String> getKey1, | 276 | + protected JsonArrayMatcher(T vnetEntityValue, Function<T, String> getKey1, |
250 | - BiPredicate<T, JsonObject> checkKey1, | 277 | + BiPredicate<T, JsonObject> checkKey1, |
251 | - List<String> jsonFieldNames1, | 278 | + List<String> jsonFieldNames1, |
252 | - BiFunction<T, String, String> getValue1) { | 279 | + BiFunction<T, String, String> getValue1) { |
253 | vnetEntity = vnetEntityValue; | 280 | vnetEntity = vnetEntityValue; |
254 | getKey = getKey1; | 281 | getKey = getKey1; |
255 | checkKey = checkKey1; | 282 | checkKey = checkKey1; |
... | @@ -292,9 +319,9 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { | ... | @@ -292,9 +319,9 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { |
292 | /** | 319 | /** |
293 | * Array matcher for VirtualNetwork. | 320 | * Array matcher for VirtualNetwork. |
294 | */ | 321 | */ |
295 | - public static class VnetJsonArrayMatcher extends JsonArrayMatcher<VirtualNetwork> { | 322 | + private static final class VnetJsonArrayMatcher extends JsonArrayMatcher<VirtualNetwork> { |
296 | 323 | ||
297 | - public VnetJsonArrayMatcher(VirtualNetwork vnetIn) { | 324 | + private VnetJsonArrayMatcher(VirtualNetwork vnetIn) { |
298 | super(vnetIn, | 325 | super(vnetIn, |
299 | vnet -> "Virtual network " + vnet.id().toString(), | 326 | vnet -> "Virtual network " + vnet.id().toString(), |
300 | (vnet, jsonObject) -> jsonObject.get(ID).asString().equals(vnet.id().toString()), | 327 | (vnet, jsonObject) -> jsonObject.get(ID).asString().equals(vnet.id().toString()), |
... | @@ -571,9 +598,9 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { | ... | @@ -571,9 +598,9 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { |
571 | /** | 598 | /** |
572 | * Array matcher for VirtualDevice. | 599 | * Array matcher for VirtualDevice. |
573 | */ | 600 | */ |
574 | - public static class VdevJsonArrayMatcher extends JsonArrayMatcher<VirtualDevice> { | 601 | + private static final class VdevJsonArrayMatcher extends JsonArrayMatcher<VirtualDevice> { |
575 | 602 | ||
576 | - public VdevJsonArrayMatcher(VirtualDevice vdevIn) { | 603 | + private VdevJsonArrayMatcher(VirtualDevice vdevIn) { |
577 | super(vdevIn, | 604 | super(vdevIn, |
578 | vdev -> "Virtual device " + vdev.networkId().toString() | 605 | vdev -> "Virtual device " + vdev.networkId().toString() |
579 | + " " + vdev.id().toString(), | 606 | + " " + vdev.id().toString(), |
... | @@ -726,9 +753,9 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { | ... | @@ -726,9 +753,9 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { |
726 | /** | 753 | /** |
727 | * Array matcher for VirtualPort. | 754 | * Array matcher for VirtualPort. |
728 | */ | 755 | */ |
729 | - public static class VportJsonArrayMatcher extends JsonArrayMatcher<VirtualPort> { | 756 | + private static final class VportJsonArrayMatcher extends JsonArrayMatcher<VirtualPort> { |
730 | 757 | ||
731 | - public VportJsonArrayMatcher(VirtualPort vportIn) { | 758 | + private VportJsonArrayMatcher(VirtualPort vportIn) { |
732 | super(vportIn, | 759 | super(vportIn, |
733 | vport -> "Virtual port " + vport.networkId().toString() + " " | 760 | vport -> "Virtual port " + vport.networkId().toString() + " " |
734 | + vport.element().id().toString() + " " + vport.number().toString(), | 761 | + vport.element().id().toString() + " " + vport.number().toString(), |
... | @@ -887,11 +914,11 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { | ... | @@ -887,11 +914,11 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { |
887 | * Hamcrest matcher to check that a virtual link representation in JSON matches | 914 | * Hamcrest matcher to check that a virtual link representation in JSON matches |
888 | * the actual virtual link. | 915 | * the actual virtual link. |
889 | */ | 916 | */ |
890 | - public static class VirtualLinkJsonMatcher extends LinksResourceTest.LinkJsonMatcher { | 917 | + private static final class VirtualLinkJsonMatcher extends LinksResourceTest.LinkJsonMatcher { |
891 | private final VirtualLink vlink; | 918 | private final VirtualLink vlink; |
892 | private String reason = ""; | 919 | private String reason = ""; |
893 | 920 | ||
894 | - public VirtualLinkJsonMatcher(VirtualLink vlinkValue) { | 921 | + private VirtualLinkJsonMatcher(VirtualLink vlinkValue) { |
895 | super(vlinkValue); | 922 | super(vlinkValue); |
896 | vlink = vlinkValue; | 923 | vlink = vlinkValue; |
897 | } | 924 | } |
... | @@ -931,18 +958,16 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { | ... | @@ -931,18 +958,16 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { |
931 | * Hamcrest matcher to check that a virtual link is represented properly in a JSON | 958 | * Hamcrest matcher to check that a virtual link is represented properly in a JSON |
932 | * array of links. | 959 | * array of links. |
933 | */ | 960 | */ |
934 | - private static class VirtualLinkJsonArrayMatcher extends TypeSafeMatcher<JsonArray> { | 961 | + private static final class VirtualLinkJsonArrayMatcher extends TypeSafeMatcher<JsonArray> { |
935 | private final VirtualLink vlink; | 962 | private final VirtualLink vlink; |
936 | private String reason = ""; | 963 | private String reason = ""; |
937 | 964 | ||
938 | - public VirtualLinkJsonArrayMatcher(VirtualLink vlinkValue) { | 965 | + private VirtualLinkJsonArrayMatcher(VirtualLink vlinkValue) { |
939 | vlink = vlinkValue; | 966 | vlink = vlinkValue; |
940 | } | 967 | } |
941 | 968 | ||
942 | @Override | 969 | @Override |
943 | public boolean matchesSafely(JsonArray json) { | 970 | public boolean matchesSafely(JsonArray json) { |
944 | - final int expectedAttributes = 2; | ||
945 | - | ||
946 | for (int jsonLinkIndex = 0; jsonLinkIndex < json.size(); | 971 | for (int jsonLinkIndex = 0; jsonLinkIndex < json.size(); |
947 | jsonLinkIndex++) { | 972 | jsonLinkIndex++) { |
948 | 973 | ||
... | @@ -1037,4 +1062,207 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { | ... | @@ -1037,4 +1062,207 @@ public class VirtualNetworkWebResourceTest extends ResourceTest { |
1037 | assertThat(response.getStatus(), is(HttpURLConnection.HTTP_NO_CONTENT)); | 1062 | assertThat(response.getStatus(), is(HttpURLConnection.HTTP_NO_CONTENT)); |
1038 | verify(mockVnetAdminService); | 1063 | verify(mockVnetAdminService); |
1039 | } | 1064 | } |
1065 | + | ||
1066 | + // Tests for Virtual Hosts | ||
1067 | + | ||
1068 | + /** | ||
1069 | + * Tests the result of the REST API GET when there are no virtual hosts. | ||
1070 | + */ | ||
1071 | + @Test | ||
1072 | + public void testGetVirtualHostsEmptyArray() { | ||
1073 | + NetworkId networkId = networkId4; | ||
1074 | + expect(mockVnetService.getVirtualHosts(networkId)).andReturn(ImmutableSet.of()).anyTimes(); | ||
1075 | + replay(mockVnetService); | ||
1076 | + | ||
1077 | + WebTarget wt = target(); | ||
1078 | + String location = "vnets/" + networkId.toString() + "/hosts"; | ||
1079 | + String response = wt.path(location).request().get(String.class); | ||
1080 | + assertThat(response, is("{\"hosts\":[]}")); | ||
1081 | + | ||
1082 | + verify(mockVnetService); | ||
1083 | + } | ||
1084 | + | ||
1085 | + /** | ||
1086 | + * Tests the result of the REST API GET when virtual hosts are defined. | ||
1087 | + */ | ||
1088 | + @Test | ||
1089 | + public void testGetVirtualHostsArray() { | ||
1090 | + NetworkId networkId = networkId3; | ||
1091 | + final Set<VirtualHost> vhostSet = ImmutableSet.of(vhost1, vhost2); | ||
1092 | + expect(mockVnetService.getVirtualHosts(networkId)).andReturn(vhostSet).anyTimes(); | ||
1093 | + replay(mockVnetService); | ||
1094 | + | ||
1095 | + WebTarget wt = target(); | ||
1096 | + String location = "vnets/" + networkId.toString() + "/hosts"; | ||
1097 | + String response = wt.path(location).request().get(String.class); | ||
1098 | + assertThat(response, containsString("{\"hosts\":[")); | ||
1099 | + | ||
1100 | + final JsonObject result = Json.parse(response).asObject(); | ||
1101 | + assertThat(result, notNullValue()); | ||
1102 | + | ||
1103 | + assertThat(result.names(), hasSize(1)); | ||
1104 | + assertThat(result.names().get(0), is("hosts")); | ||
1105 | + | ||
1106 | + final JsonArray vnetJsonArray = result.get("hosts").asArray(); | ||
1107 | + assertThat(vnetJsonArray, notNullValue()); | ||
1108 | + assertEquals("Virtual hosts array is not the correct size.", | ||
1109 | + vhostSet.size(), vnetJsonArray.size()); | ||
1110 | + | ||
1111 | + vhostSet.forEach(vhost -> assertThat(vnetJsonArray, hasVhost(vhost))); | ||
1112 | + | ||
1113 | + verify(mockVnetService); | ||
1114 | + } | ||
1115 | + | ||
1116 | + /** | ||
1117 | + * Hamcrest matcher to check that a virtual host representation in JSON matches | ||
1118 | + * the actual virtual host. | ||
1119 | + */ | ||
1120 | + private static final class VirtualHostJsonMatcher extends HostResourceTest.HostJsonMatcher { | ||
1121 | + private final VirtualHost vhost; | ||
1122 | + private String reason = ""; | ||
1123 | + | ||
1124 | + private VirtualHostJsonMatcher(VirtualHost vhostValue) { | ||
1125 | + super(vhostValue); | ||
1126 | + vhost = vhostValue; | ||
1127 | + } | ||
1128 | + | ||
1129 | + @Override | ||
1130 | + public boolean matchesSafely(JsonObject jsonHost) { | ||
1131 | + if (!super.matchesSafely(jsonHost)) { | ||
1132 | + return false; | ||
1133 | + } | ||
1134 | + // check NetworkId | ||
1135 | + String jsonNetworkId = jsonHost.get(ID).asString(); | ||
1136 | + String networkId = vhost.networkId().toString(); | ||
1137 | + if (!jsonNetworkId.equals(networkId)) { | ||
1138 | + reason = ID + " was " + jsonNetworkId; | ||
1139 | + return false; | ||
1140 | + } | ||
1141 | + return true; | ||
1142 | + } | ||
1143 | + | ||
1144 | + @Override | ||
1145 | + public void describeTo(Description description) { | ||
1146 | + description.appendText(reason); | ||
1147 | + } | ||
1148 | + } | ||
1149 | + | ||
1150 | + /** | ||
1151 | + * Factory to allocate a virtual host matcher. | ||
1152 | + * | ||
1153 | + * @param vhost virtual host object we are looking for | ||
1154 | + * @return matcher | ||
1155 | + */ | ||
1156 | + private static VirtualHostJsonMatcher matchesVirtualHost(VirtualHost vhost) { | ||
1157 | + return new VirtualHostJsonMatcher(vhost); | ||
1158 | + } | ||
1159 | + | ||
1160 | + /** | ||
1161 | + * Hamcrest matcher to check that a virtual host is represented properly in a JSON | ||
1162 | + * array of hosts. | ||
1163 | + */ | ||
1164 | + private static final class VirtualHostJsonArrayMatcher extends TypeSafeMatcher<JsonArray> { | ||
1165 | + private final VirtualHost vhost; | ||
1166 | + private String reason = ""; | ||
1167 | + | ||
1168 | + private VirtualHostJsonArrayMatcher(VirtualHost vhostValue) { | ||
1169 | + vhost = vhostValue; | ||
1170 | + } | ||
1171 | + | ||
1172 | + @Override | ||
1173 | + public boolean matchesSafely(JsonArray json) { | ||
1174 | + for (int jsonHostIndex = 0; jsonHostIndex < json.size(); | ||
1175 | + jsonHostIndex++) { | ||
1176 | + | ||
1177 | + JsonObject jsonHost = json.get(jsonHostIndex).asObject(); | ||
1178 | + | ||
1179 | + if (matchesVirtualHost(vhost).matchesSafely(jsonHost)) { | ||
1180 | + return true; | ||
1181 | + } | ||
1182 | + } | ||
1183 | + return false; | ||
1184 | + } | ||
1185 | + | ||
1186 | + @Override | ||
1187 | + public void describeTo(Description description) { | ||
1188 | + description.appendText(reason); | ||
1189 | + } | ||
1190 | + } | ||
1191 | + | ||
1192 | + /** | ||
1193 | + * Factory to allocate a virtual host array matcher. | ||
1194 | + * | ||
1195 | + * @param vhost virtual host object we are looking for | ||
1196 | + * @return matcher | ||
1197 | + */ | ||
1198 | + private VirtualHostJsonArrayMatcher hasVhost(VirtualHost vhost) { | ||
1199 | + return new VirtualHostJsonArrayMatcher(vhost); | ||
1200 | + } | ||
1201 | + | ||
1202 | + /** | ||
1203 | + * Tests adding of new virtual host using POST via JSON stream. | ||
1204 | + */ | ||
1205 | + @Test | ||
1206 | + public void testPostVirtualHost() { | ||
1207 | + NetworkId networkId = networkId3; | ||
1208 | + expect(mockVnetAdminService.createVirtualHost(networkId, hId1, mac1, vlan1, loc1, ipSet1)) | ||
1209 | + .andReturn(vhost1); | ||
1210 | + replay(mockVnetAdminService); | ||
1211 | + | ||
1212 | + WebTarget wt = target(); | ||
1213 | + InputStream jsonStream = VirtualNetworkWebResourceTest.class | ||
1214 | + .getResourceAsStream("post-virtual-host.json"); | ||
1215 | + String reqLocation = "vnets/" + networkId.toString() + "/hosts"; | ||
1216 | + Response response = wt.path(reqLocation).request(MediaType.APPLICATION_JSON_TYPE) | ||
1217 | + .post(Entity.json(jsonStream)); | ||
1218 | + assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED)); | ||
1219 | + | ||
1220 | + String location = response.getLocation().getPath(); | ||
1221 | + assertThat(location, Matchers.startsWith("/" + reqLocation)); | ||
1222 | + | ||
1223 | + verify(mockVnetAdminService); | ||
1224 | + } | ||
1225 | + | ||
1226 | + /** | ||
1227 | + * Tests adding of a null virtual host using POST via JSON stream. | ||
1228 | + */ | ||
1229 | + @Test | ||
1230 | + public void testPostVirtualHostNullJsonStream() { | ||
1231 | + NetworkId networkId = networkId3; | ||
1232 | + replay(mockVnetAdminService); | ||
1233 | + | ||
1234 | + WebTarget wt = target(); | ||
1235 | + try { | ||
1236 | + String reqLocation = "vnets/" + networkId.toString() + "/hosts"; | ||
1237 | + wt.path(reqLocation) | ||
1238 | + .request(MediaType.APPLICATION_JSON_TYPE) | ||
1239 | + .post(Entity.json(null), String.class); | ||
1240 | + fail("POST of null virtual host did not throw an exception"); | ||
1241 | + } catch (BadRequestException ex) { | ||
1242 | + assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request")); | ||
1243 | + } | ||
1244 | + | ||
1245 | + verify(mockVnetAdminService); | ||
1246 | + } | ||
1247 | + | ||
1248 | + /** | ||
1249 | + * Tests removing a virtual host with DELETE request. | ||
1250 | + */ | ||
1251 | + @Test | ||
1252 | + public void testDeleteVirtualHost() { | ||
1253 | + NetworkId networkId = networkId3; | ||
1254 | + mockVnetAdminService.removeVirtualHost(networkId, hId1); | ||
1255 | + expectLastCall(); | ||
1256 | + replay(mockVnetAdminService); | ||
1257 | + | ||
1258 | + WebTarget wt = target() | ||
1259 | + .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true); | ||
1260 | + InputStream jsonStream = VirtualNetworkWebResourceTest.class | ||
1261 | + .getResourceAsStream("post-virtual-host.json"); | ||
1262 | + String reqLocation = "vnets/" + networkId.toString() + "/hosts"; | ||
1263 | + Response response = wt.path(reqLocation).request().method("DELETE", Entity.json(jsonStream)); | ||
1264 | + | ||
1265 | + assertThat(response.getStatus(), is(HttpURLConnection.HTTP_NO_CONTENT)); | ||
1266 | + verify(mockVnetAdminService); | ||
1267 | + } | ||
1040 | } | 1268 | } | ... | ... |
-
Please register or login to post a comment