2 * Copyright IBM Corporation, 2013. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.neutron.northbound.api;
11 import java.net.HttpURLConnection;
13 import java.util.ArrayList;
14 import java.util.HashMap;
15 import java.util.Iterator;
16 import java.util.List;
19 import javax.ws.rs.Consumes;
20 import javax.ws.rs.DELETE;
21 import javax.ws.rs.DefaultValue;
22 import javax.ws.rs.GET;
23 import javax.ws.rs.POST;
24 import javax.ws.rs.PUT;
25 import javax.ws.rs.Path;
26 import javax.ws.rs.PathParam;
27 import javax.ws.rs.Produces;
28 import javax.ws.rs.QueryParam;
29 import javax.ws.rs.core.Context;
30 import javax.ws.rs.core.MediaType;
31 import javax.ws.rs.core.Response;
32 import javax.ws.rs.core.UriInfo;
34 import org.codehaus.enunciate.jaxrs.ResponseCode;
35 import org.codehaus.enunciate.jaxrs.StatusCodes;
36 import org.codehaus.enunciate.jaxrs.TypeHint;
37 import org.opendaylight.neutron.spi.INeutronNetworkAware;
38 import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
39 import org.opendaylight.neutron.spi.NeutronCRUDInterfaces;
40 import org.opendaylight.neutron.spi.NeutronNetwork;
43 * Neutron Northbound REST APIs for Network.<br>
44 * This class provides REST APIs for managing neutron Networks
48 * Authentication scheme : <b>HTTP Basic</b><br>
49 * Authentication realm : <b>opendaylight</b><br>
50 * Transport : <b>HTTP and HTTPS</b><br>
52 * HTTPS Authentication is disabled by default. Administrator can enable it in
53 * tomcat-server.xml after adding a proper keystore / SSL certificate from a
54 * trusted authority.<br>
56 * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
61 public class NeutronNetworksNorthbound {
66 private static final int HTTP_OK_BOTTOM = 200;
67 private static final int HTTP_OK_TOP = 299;
68 private static final String INTERFACE_NAME = "Network CRUD Interface";
69 private static final String UUID_NO_EXIST = "Network UUID does not exist.";
70 private static final String UUID_EXISTS = "Network UUID already exists.";
71 private static final String NO_PROVIDERS = "No providers registered. Please try again later";
72 private static final String NO_PROVIDER_LIST = "Couldn't get providers list. Please try again later";
74 private NeutronNetwork extractFields(NeutronNetwork o, List<String> fields) {
75 return o.extractFields(fields);
78 private NeutronCRUDInterfaces getNeutronInterfaces() {
79 NeutronCRUDInterfaces answer = new NeutronCRUDInterfaces().fetchINeutronNetworkCRUD(this);
80 if (answer.getNetworkInterface() == null) {
81 throw new ServiceUnavailableException(INTERFACE_NAME
82 + RestMessages.SERVICEUNAVAILABLE.toString());
88 * Returns a list of all Networks */
91 @Produces({ MediaType.APPLICATION_JSON })
92 //@TypeHint(OpenStackNetworks.class)
94 @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
95 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
96 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
97 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
98 public Response listNetworks(
100 @QueryParam("fields") List<String> fields,
101 // note: openstack isn't clear about filtering on lists, so we aren't handling them
102 @QueryParam("id") String queryID,
103 @QueryParam("name") String queryName,
104 @QueryParam("admin_state_up") String queryAdminStateUp,
105 @QueryParam("status") String queryStatus,
106 @QueryParam("shared") String queryShared,
107 @QueryParam("tenant_id") String queryTenantID,
108 @QueryParam("router_external") String queryRouterExternal,
109 @QueryParam("provider_network_type") String queryProviderNetworkType,
110 @QueryParam("provider_physical_network") String queryProviderPhysicalNetwork,
111 @QueryParam("provider_segmentation_id") String queryProviderSegmentationID,
113 @QueryParam("limit") Integer limit,
114 @QueryParam("marker") String marker,
115 @DefaultValue("false") @QueryParam("page_reverse") Boolean pageReverse
116 // sorting not supported
118 INeutronNetworkCRUD networkInterface = getNeutronInterfaces().getNetworkInterface();
119 List<NeutronNetwork> allNetworks = networkInterface.getAllNetworks();
120 List<NeutronNetwork> ans = new ArrayList<NeutronNetwork>();
121 Iterator<NeutronNetwork> i = allNetworks.iterator();
122 while (i.hasNext()) {
123 NeutronNetwork oSN = i.next();
124 //match filters: TODO provider extension
125 Boolean bAdminStateUp = null;
126 Boolean bShared = null;
127 Boolean bRouterExternal = null;
128 if (queryAdminStateUp != null) {
129 bAdminStateUp = Boolean.valueOf(queryAdminStateUp);
131 if (queryShared != null) {
132 bShared = Boolean.valueOf(queryShared);
134 if (queryRouterExternal != null) {
135 bRouterExternal = Boolean.valueOf(queryRouterExternal);
137 if ((queryID == null || queryID.equals(oSN.getID())) &&
138 (queryName == null || queryName.equals(oSN.getNetworkName())) &&
139 (bAdminStateUp == null || bAdminStateUp.booleanValue() == oSN.isAdminStateUp()) &&
140 (queryStatus == null || queryStatus.equals(oSN.getStatus())) &&
141 (bShared == null || bShared.booleanValue() == oSN.isShared()) &&
142 (bRouterExternal == null || bRouterExternal.booleanValue() == oSN.isRouterExternal()) &&
143 (queryTenantID == null || queryTenantID.equals(oSN.getTenantID()))) {
144 if (fields.size() > 0) {
145 ans.add(extractFields(oSN,fields));
152 if (limit != null && ans.size() > 1) {
153 // Return a paginated request
154 NeutronNetworkRequest request = (NeutronNetworkRequest) PaginatedRequestFactory.createRequest(limit,
155 marker, pageReverse, uriInfo, ans, NeutronNetwork.class);
156 return Response.status(HttpURLConnection.HTTP_OK).entity(request).build();
159 return Response.status(HttpURLConnection.HTTP_OK).entity(new NeutronNetworkRequest(ans)).build();
164 * Returns a specific Network */
168 @Produces({ MediaType.APPLICATION_JSON })
169 //@TypeHint(OpenStackNetworks.class)
171 @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
172 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
173 @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
174 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
175 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
176 public Response showNetwork(
177 @PathParam("netUUID") String netUUID,
179 @QueryParam("fields") List<String> fields
181 INeutronNetworkCRUD networkInterface = getNeutronInterfaces().getNetworkInterface();
182 if (!networkInterface.networkExists(netUUID)) {
183 throw new ResourceNotFoundException(UUID_NO_EXIST);
185 if (fields.size() > 0) {
186 NeutronNetwork ans = networkInterface.getNetwork(netUUID);
187 return Response.status(HttpURLConnection.HTTP_OK).entity(
188 new NeutronNetworkRequest(extractFields(ans, fields))).build();
190 return Response.status(HttpURLConnection.HTTP_OK).entity(
191 new NeutronNetworkRequest(networkInterface.getNetwork(netUUID))).build();
196 * Creates new Networks */
198 @Produces({ MediaType.APPLICATION_JSON })
199 @Consumes({ MediaType.APPLICATION_JSON })
200 @TypeHint(NeutronNetwork.class)
202 @ResponseCode(code = HttpURLConnection.HTTP_CREATED, condition = "Created"),
203 @ResponseCode(code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
204 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
205 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
206 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
207 public Response createNetworks(final NeutronNetworkRequest input) {
208 INeutronNetworkCRUD networkInterface = getNeutronInterfaces().getNetworkInterface();
209 if (input.isSingleton()) {
210 NeutronNetwork singleton = input.getSingleton();
213 * network ID can't already exist
215 if (networkInterface.networkExists(singleton.getID())) {
216 throw new BadRequestException(UUID_EXISTS);
219 Object[] instances = NeutronUtil.getInstances(INeutronNetworkAware.class, this);
220 if (instances != null) {
221 if (instances.length > 0) {
222 for (Object instance : instances) {
223 INeutronNetworkAware service = (INeutronNetworkAware) instance;
224 int status = service.canCreateNetwork(singleton);
225 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
226 return Response.status(status).build();
230 throw new ServiceUnavailableException(NO_PROVIDERS);
233 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
236 // add network to cache
237 singleton.initDefaults();
238 networkInterface.addNetwork(singleton);
239 if (instances != null) {
240 for (Object instance : instances) {
241 INeutronNetworkAware service = (INeutronNetworkAware) instance;
242 service.neutronNetworkCreated(singleton);
247 List<NeutronNetwork> bulk = input.getBulk();
248 Iterator<NeutronNetwork> i = bulk.iterator();
249 Map<String, NeutronNetwork> testMap = new HashMap<String, NeutronNetwork>();
250 Object[] instances = NeutronUtil.getInstances(INeutronNetworkAware.class, this);
251 while (i.hasNext()) {
252 NeutronNetwork test = i.next();
255 * network ID can't already exist, nor can there be an entry for this UUID
256 * already in this bulk request
258 if (networkInterface.networkExists(test.getID())) {
259 throw new BadRequestException(UUID_EXISTS);
261 if (testMap.containsKey(test.getID())) {
262 throw new BadRequestException(UUID_EXISTS);
264 if (instances != null) {
265 if (instances.length > 0) {
266 for (Object instance: instances) {
267 INeutronNetworkAware service = (INeutronNetworkAware) instance;
268 int status = service.canCreateNetwork(test);
269 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
270 return Response.status(status).build();
274 throw new ServiceUnavailableException(NO_PROVIDERS);
277 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
279 testMap.put(test.getID(),test);
282 // now that everything passed, add items to the cache
284 while (i.hasNext()) {
285 NeutronNetwork test = i.next();
287 networkInterface.addNetwork(test);
288 if (instances != null) {
289 for (Object instance: instances) {
290 INeutronNetworkAware service = (INeutronNetworkAware) instance;
291 service.neutronNetworkCreated(test);
296 return Response.status(HttpURLConnection.HTTP_CREATED).entity(input).build();
300 * Updates a Network */
303 @Produces({ MediaType.APPLICATION_JSON })
304 @Consumes({ MediaType.APPLICATION_JSON })
305 //@TypeHint(OpenStackNetworks.class)
307 @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
308 @ResponseCode(code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
309 @ResponseCode(code = HttpURLConnection.HTTP_FORBIDDEN, condition = "Forbidden"),
310 @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
311 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
312 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
313 public Response updateNetwork(
314 @PathParam("netUUID") String netUUID, final NeutronNetworkRequest input
316 INeutronNetworkCRUD networkInterface = getNeutronInterfaces().getNetworkInterface();
319 * network has to exist and only a single object is supported
321 if (!networkInterface.networkExists(netUUID)) {
322 throw new ResourceNotFoundException(UUID_NO_EXIST);
324 if (!input.isSingleton()) {
325 throw new BadRequestException("only singleton edits supported");
327 NeutronNetwork updatedObject = input.getSingleton();
330 * note: what we get appears to not be a delta but
331 * rather an incomplete updated object. So we need to set
332 * the ID to complete the object and then send that down
336 updatedObject.setID(netUUID);
337 Object[] instances = NeutronUtil.getInstances(INeutronNetworkAware.class, this);
338 if (instances != null) {
339 if (instances.length > 0) {
340 for (Object instance : instances) {
341 INeutronNetworkAware service = (INeutronNetworkAware) instance;
342 NeutronNetwork original = networkInterface.getNetwork(netUUID);
343 int status = service.canUpdateNetwork(updatedObject, original);
344 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
345 return Response.status(status).build();
349 throw new ServiceUnavailableException(NO_PROVIDERS);
352 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
355 // update network object
356 networkInterface.updateNetwork(netUUID, updatedObject);
357 if (instances != null) {
358 for (Object instance : instances) {
359 INeutronNetworkAware service = (INeutronNetworkAware) instance;
360 service.neutronNetworkUpdated(updatedObject);
363 return Response.status(HttpURLConnection.HTTP_OK).entity(
364 new NeutronNetworkRequest(networkInterface.getNetwork(netUUID))).build();
368 * Deletes a Network */
373 @ResponseCode(code = HttpURLConnection.HTTP_NO_CONTENT, condition = "No Content"),
374 @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
375 @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
376 @ResponseCode(code = HttpURLConnection.HTTP_CONFLICT, condition = "Network In Use"),
377 @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
378 @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
379 public Response deleteNetwork(
380 @PathParam("netUUID") String netUUID) {
381 INeutronNetworkCRUD networkInterface = getNeutronInterfaces().getNetworkInterface();
384 * network has to exist and not be in use before it can be removed
386 if (!networkInterface.networkExists(netUUID)) {
387 throw new ResourceNotFoundException(UUID_NO_EXIST);
389 if (networkInterface.networkInUse(netUUID)) {
390 throw new ResourceConflictException("Network ID in use");
393 NeutronNetwork singleton = networkInterface.getNetwork(netUUID);
394 Object[] instances = NeutronUtil.getInstances(INeutronNetworkAware.class, this);
395 if (instances != null) {
396 if (instances.length > 0) {
397 for (Object instance : instances) {
398 INeutronNetworkAware service = (INeutronNetworkAware) instance;
399 int status = service.canDeleteNetwork(singleton);
400 if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
401 return Response.status(status).build();
405 throw new ServiceUnavailableException(NO_PROVIDERS);
408 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
411 networkInterface.removeNetwork(netUUID);
412 if (instances != null) {
413 for (Object instance : instances) {
414 INeutronNetworkAware service = (INeutronNetworkAware) instance;
415 service.neutronNetworkDeleted(singleton);
418 return Response.status(HttpURLConnection.HTTP_NO_CONTENT).build();