blob: 1ebfe560fdbc12a0b4891ad7f3f6b9524bbd73a1 [file] [log] [blame]
Claudine Chiufb8b8162016-04-01 23:50:51 +00001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Claudine Chiufb8b8162016-04-01 23:50:51 +00003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.rest.resources;
18
19import com.fasterxml.jackson.databind.JsonNode;
20import com.fasterxml.jackson.databind.node.ObjectNode;
21import org.onosproject.incubator.net.virtual.NetworkId;
22import org.onosproject.incubator.net.virtual.TenantId;
23import org.onosproject.incubator.net.virtual.VirtualDevice;
24import org.onosproject.incubator.net.virtual.VirtualNetwork;
25import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
26import org.onosproject.incubator.net.virtual.VirtualNetworkService;
27import org.onosproject.incubator.net.virtual.VirtualPort;
28import org.onosproject.net.DefaultAnnotations;
29import org.onosproject.net.DefaultDevice;
30import org.onosproject.net.DefaultPort;
31import org.onosproject.net.Device;
32import org.onosproject.net.DeviceId;
33import org.onosproject.net.Port;
34import org.onosproject.net.PortNumber;
35import org.onosproject.rest.AbstractWebResource;
36
37import javax.ws.rs.Consumes;
38import javax.ws.rs.DELETE;
39import javax.ws.rs.GET;
40import javax.ws.rs.POST;
41import javax.ws.rs.Path;
42import javax.ws.rs.PathParam;
43import javax.ws.rs.Produces;
44import javax.ws.rs.core.Context;
45import javax.ws.rs.core.MediaType;
46import javax.ws.rs.core.Response;
47import javax.ws.rs.core.UriBuilder;
48import javax.ws.rs.core.UriInfo;
49import java.io.IOException;
50import java.io.InputStream;
51import java.util.Collection;
52import java.util.List;
53import java.util.Set;
54import java.util.stream.Collectors;
55
56/**
57 * Query and Manage Virtual Network elements.
58 */
59@Path("vnets")
60public class VirtualNetworkWebResource extends AbstractWebResource {
61
62 private static final String MISSING_FIELD = "Missing ";
63 private static final String INVALID_FIELD = "Invalid ";
64
65 private final VirtualNetworkAdminService vnetAdminService = get(VirtualNetworkAdminService.class);
66 private final VirtualNetworkService vnetService = get(VirtualNetworkService.class);
67
68 @Context
69 UriInfo uriInfo;
70
71 // VirtualNetwork
72 // TODO Query vnets by tenant
73
74 /**
75 * Returns all virtual networks.
76 *
77 * @return 200 OK
78 */
79 @GET
80 @Produces(MediaType.APPLICATION_JSON)
81 public Response getVirtualNetworks() {
82 Set<TenantId> tenantIds = vnetAdminService.getTenantIds();
83 List<VirtualNetwork> allVnets = tenantIds.stream()
84 .map(tenantId -> vnetService.getVirtualNetworks(tenantId))
85 .flatMap(Collection::stream)
86 .collect(Collectors.toList());
87 return ok(encodeArray(VirtualNetwork.class, "vnets", allVnets)).build();
88 }
89
90 /**
91 * Creates a virtual network from the JSON input stream.
92 *
93 * @param stream TenantId JSON stream
94 * @return status of the request - CREATED if the JSON is correct,
95 * BAD_REQUEST if the JSON is invalid
96 * @onos.rsModel TenantId
97 */
98 @POST
99 @Consumes(MediaType.APPLICATION_JSON)
100 @Produces(MediaType.APPLICATION_JSON)
101 public Response createVirtualNetwork(InputStream stream) {
102 try {
103 final TenantId tid = TenantId.tenantId(getFromJsonStream(stream, "id").asText());
104 VirtualNetwork newVnet = vnetAdminService.createVirtualNetwork(tid);
105 UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
106 .path("vnets")
107 .path(newVnet.id().toString());
108 return Response
109 .created(locationBuilder.build())
110 .build();
111 } catch (IOException e) {
112 throw new IllegalArgumentException(e);
113 }
114 }
115
116 /**
117 * Removes the virtual network with the specified network identifier.
118 *
119 * @param networkId network identifier
120 * @return 200 OK, 404 not found
121 */
122 @DELETE
123 @Path("{networkId}")
124 public Response removeVirtualNetwork(@PathParam("networkId") long networkId) {
125 final NetworkId nid = NetworkId.networkId(networkId);
126 vnetAdminService.removeVirtualNetwork(nid);
127 return Response.ok().build();
128 }
129
130 // VirtualDevice
131
132 /**
133 * Returns all virtual network devices in a virtual network.
134 *
135 * @param networkId network identifier
136 * @return 200 OK
137 */
138 @GET
139 @Produces(MediaType.APPLICATION_JSON)
140 @Path("{networkId}/devices")
141 public Response getVirtualDevices(@PathParam("networkId") long networkId) {
142 final NetworkId nid = NetworkId.networkId(networkId);
143 Set<VirtualDevice> vdevs = vnetService.getVirtualDevices(nid);
144 return ok(encodeArray(VirtualDevice.class, "devices", vdevs)).build();
145 }
146
147 /**
148 * Creates a virtual device from the JSON input stream.
149 *
150 * @param networkId network identifier
151 * @param stream Virtual device JSON stream
152 * @return status of the request - CREATED if the JSON is correct,
153 * BAD_REQUEST if the JSON is invalid
154 * @onos.rsModel VirtualDevice
155 */
156 @POST
157 @Path("{networkId}/devices/")
158 @Consumes(MediaType.APPLICATION_JSON)
159 @Produces(MediaType.APPLICATION_JSON)
160 public Response createVirtualDevice(@PathParam("networkId") long networkId,
161 InputStream stream) {
162 try {
163 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
164 final VirtualDevice vdevReq = codec(VirtualDevice.class).decode(jsonTree, this);
165 JsonNode specifiedRegionId = jsonTree.get("networkId");
166 if (specifiedRegionId != null &&
167 specifiedRegionId.asLong() != (networkId)) {
168 throw new IllegalArgumentException(INVALID_FIELD + "networkId");
169 }
170 final VirtualDevice vdevRes = vnetAdminService.createVirtualDevice(vdevReq.networkId(),
171 vdevReq.id());
172 UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
173 .path("vnets").path(specifiedRegionId.asText())
174 .path("devices").path(vdevRes.id().toString());
175 return Response
176 .created(locationBuilder.build())
177 .build();
178 } catch (IOException e) {
179 throw new IllegalArgumentException(e);
180 }
181 }
182
183 /**
184 * Removes the virtual network device from the virtual network.
185 *
186 * @param networkId network identifier
187 * @param deviceId device identifier
188 * @return 200 OK, 404 not found
189 */
190 @DELETE
191 @Path("{networkId}/devices/{deviceId}")
192 public Response removeVirtualDevice(@PathParam("networkId") long networkId,
193 @PathParam("deviceId") String deviceId) {
194 final NetworkId nid = NetworkId.networkId(networkId);
195 final DeviceId did = DeviceId.deviceId(deviceId);
196 vnetAdminService.removeVirtualDevice(nid, did);
197 return Response.ok().build();
198 }
199
200 // VirtualPort
201
202 /**
203 * Returns all virtual network ports in a virtual device in a virtual network.
204 *
205 * @param networkId network identifier
206 * @param deviceId virtual device identifier
207 * @return 200 OK
208 */
209 @GET
210 @Produces(MediaType.APPLICATION_JSON)
211 @Path("{networkId}/devices/{deviceId}/ports")
212 public Response getVirtualPorts(@PathParam("networkId") long networkId,
213 @PathParam("deviceId") String deviceId) {
214 final NetworkId nid = NetworkId.networkId(networkId);
215 Iterable<VirtualPort> vports = vnetService.getVirtualPorts(nid, DeviceId.deviceId(deviceId));
216 return ok(encodeArray(VirtualPort.class, "ports", vports)).build();
217 }
218
219 /**
220 * Creates a virtual network port in a virtual device in a virtual network.
221 *
222 * @param networkId network identifier
223 * @param virtDeviceId virtual device identifier
224 * @param stream Virtual device JSON stream
225 * @return status of the request - CREATED if the JSON is correct,
226 * BAD_REQUEST if the JSON is invalid
227 * @onos.rsModel VirtualPort
228 */
229 @POST
230 @Consumes(MediaType.APPLICATION_JSON)
231 @Produces(MediaType.APPLICATION_JSON)
232 @Path("{networkId}/devices/{deviceId}/ports")
233 public Response createVirtualPort(@PathParam("networkId") long networkId,
234 @PathParam("deviceId") String virtDeviceId,
235 InputStream stream) {
236 try {
237 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
238// final VirtualPort vportReq = codec(VirtualPort.class).decode(jsonTree, this);
239 JsonNode specifiedNetworkId = jsonTree.get("networkId");
240 JsonNode specifiedDeviceId = jsonTree.get("deviceId");
241 if (specifiedNetworkId != null &&
242 specifiedNetworkId.asLong() != (networkId)) {
243 throw new IllegalArgumentException(INVALID_FIELD + "networkId");
244 }
245 if (specifiedDeviceId != null &&
246 !specifiedDeviceId.asText().equals(virtDeviceId)) {
247 throw new IllegalArgumentException(INVALID_FIELD + "deviceId");
248 }
249 JsonNode specifiedPortNum = jsonTree.get("portNum");
250 JsonNode specifiedPhysDeviceId = jsonTree.get("physDeviceId");
251 JsonNode specifiedPhysPortNum = jsonTree.get("physPortNum");
252 final NetworkId nid = NetworkId.networkId(networkId);
253 DeviceId vdevId = DeviceId.deviceId(virtDeviceId);
254 DefaultAnnotations annotations = DefaultAnnotations.builder().build();
255 Device physDevice = new DefaultDevice(null, DeviceId.deviceId(specifiedPhysDeviceId.asText()),
256 null, null, null, null, null, null, annotations);
257 Port realizedBy = new DefaultPort(physDevice,
258 PortNumber.portNumber(specifiedPhysPortNum.asText()), true);
259 VirtualPort vport = vnetAdminService.createVirtualPort(nid, vdevId,
260 PortNumber.portNumber(specifiedPortNum.asText()), realizedBy);
261 UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
262 .path("vnets").path(specifiedNetworkId.asText())
263 .path("devices").path(specifiedDeviceId.asText())
264 .path("ports").path(vport.number().toString());
265 return Response
266 .created(locationBuilder.build())
267 .build();
268 } catch (IOException e) {
269 throw new IllegalArgumentException(e);
270 }
271 }
272
273 /**
274 * Removes the virtual network port from the virtual device in a virtual network.
275 *
276 * @param networkId network identifier
277 * @param deviceId virtual device identifier
278 * @param portNum virtual port number
279 * @return 200 OK, 404 not found
280 */
281 @DELETE
282 @Path("{networkId}/devices/{deviceId}/ports/{portNum}")
283 public Response removeVirtualPort(@PathParam("networkId") long networkId,
284 @PathParam("deviceId") String deviceId,
285 @PathParam("portNum") long portNum) {
286 final NetworkId nid = NetworkId.networkId(networkId);
287 vnetAdminService.removeVirtualPort(nid, DeviceId.deviceId(deviceId),
288 PortNumber.portNumber(portNum));
289 return Response.ok().build();
290 }
291
292 // TODO VirtualLink
293
294 /**
295 * Get the tenant identifier from the JSON stream.
296 *
297 * @param stream TenantId JSON stream
298 * @param jsonFieldName field name
299 * @return JsonNode
300 * @throws IOException
301 */
302 private JsonNode getFromJsonStream(InputStream stream, String jsonFieldName) throws IOException {
303 ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
304 JsonNode jsonNode = jsonTree.get(jsonFieldName);
305
306 if (jsonNode == null) {
307 throw new IllegalArgumentException(MISSING_FIELD + jsonFieldName);
308 }
309 return jsonNode;
310 }
311}