bc998035b129db8cfc594c04e5819f54dd99e378
[neutron.git] /
1 /*
2  * Copyright IBM Corporation, 2015.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.neutron.northbound.api;
10
11 import java.net.HttpURLConnection;
12
13 import java.util.ArrayList;
14 import java.util.HashMap;
15 import java.util.Iterator;
16 import java.util.List;
17 import java.util.Map;
18
19 import javax.ws.rs.Consumes;
20 import javax.ws.rs.DELETE;
21 import javax.ws.rs.GET;
22 import javax.ws.rs.POST;
23 import javax.ws.rs.PUT;
24 import javax.ws.rs.Path;
25 import javax.ws.rs.PathParam;
26 import javax.ws.rs.Produces;
27 import javax.ws.rs.QueryParam;
28 import javax.ws.rs.core.Context;
29 import javax.ws.rs.core.MediaType;
30 import javax.ws.rs.core.Response;
31 import javax.ws.rs.core.UriInfo;
32
33 import org.codehaus.enunciate.jaxrs.ResponseCode;
34 import org.codehaus.enunciate.jaxrs.StatusCodes;
35 import org.codehaus.enunciate.jaxrs.TypeHint;
36 import org.opendaylight.neutron.spi.INeutronVPNServiceAware;
37 import org.opendaylight.neutron.spi.INeutronVPNServiceCRUD;
38 import org.opendaylight.neutron.spi.NeutronCRUDInterfaces;
39 import org.opendaylight.neutron.spi.NeutronVPNService;
40
41 /**
42  * Neutron Northbound REST APIs for VPN Service.<br>
43  * This class provides REST APIs for managing neutron VPN Services
44  *
45  * <br>
46  * <br>
47  * Authentication scheme : <b>HTTP Basic</b><br>
48  * Authentication realm : <b>opendaylight</b><br>
49  * Transport : <b>HTTP and HTTPS</b><br>
50  * <br>
51  * HTTPS Authentication is disabled by default. Administrator can enable it in
52  * tomcat-server.xml after adding a proper keystore / SSL certificate from a
53  * trusted authority.<br>
54  * More info :
55  * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
56  *
57  */
58
59 @Path("/vpn/vpnservices")
60 public class NeutronVPNServicesNorthbound {
61
62     private static final int HTTP_OK_BOTTOM = 200;
63     private static final int HTTP_OK_TOP = 299;
64     private static final String INTERFACE_NAME = "VPNService CRUD Interface";
65     private static final String UUID_NO_EXIST = "VPNService UUID does not exist.";
66     private static final String NO_PROVIDERS = "No providers registered.  Please try again later";
67     private static final String NO_PROVIDER_LIST = "Couldn't get providers list.  Please try again later";
68
69     private NeutronVPNService extractFields(NeutronVPNService o, List<String> fields) {
70         return o.extractFields(fields);
71     }
72
73     @Context
74     UriInfo uriInfo;
75
76     private NeutronCRUDInterfaces getNeutronInterfaces() {
77         NeutronCRUDInterfaces answer = new NeutronCRUDInterfaces().fetchINeutronVPNServiceCRUD(this);
78         if (answer.getVPNServiceInterface() == null) {
79             throw new ServiceUnavailableException(INTERFACE_NAME
80                 + RestMessages.SERVICEUNAVAILABLE.toString());
81         }
82         return answer;
83     }
84
85     /**
86      * Returns a list of all VPN Services
87      */
88
89     @GET
90     @Produces({ MediaType.APPLICATION_JSON })
91     @StatusCodes({ @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
92             @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
93             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
94             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
95     public Response listVPNServices(
96             // return fields
97             @QueryParam("fields") List<String> fields,
98             // OpenStack VPNService attributes
99             @QueryParam("id") String queryID,
100             @QueryParam("tenant_id") String queryTenantID,
101             @QueryParam("name") String queryName,
102             @QueryParam("admin_state_up") String queryAdminStateUp,
103             @QueryParam("router_id") String queryRouterID,
104             @QueryParam("status") String queryStatus,
105             @QueryParam("subnet_id") String querySubnetID,
106             // pagination
107             @QueryParam("limit") String limit,
108             @QueryParam("marker") String marker,
109             @QueryParam("page_reverse") String pageReverse
110     // sorting not supported
111     ) {
112         INeutronVPNServiceCRUD VPNServiceInterface = getNeutronInterfaces().getVPNServiceInterface();
113         List<NeutronVPNService> allVPNService = VPNServiceInterface.getAllVPNService();
114         List<NeutronVPNService> ans = new ArrayList<NeutronVPNService>();
115         Iterator<NeutronVPNService> i = allVPNService.iterator();
116         while (i.hasNext()) {
117             NeutronVPNService oSS = i.next();
118             if ((queryID == null || queryID.equals(oSS.getID()))
119                     && (queryName == null || queryName.equals(oSS.getName()))
120                     && (queryAdminStateUp == null || queryAdminStateUp.equals(oSS.getAdminStateUp()))
121                     && (queryStatus == null || queryStatus.equals(oSS.getStatus()))
122                     && (querySubnetID == null || querySubnetID.equals(oSS.getSubnetUUID()))
123                     && (queryRouterID == null || queryRouterID.equals(oSS.getRouterUUID()))
124                     && (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {
125                 if (fields.size() > 0) {
126                     ans.add(extractFields(oSS, fields));
127                 } else {
128                     ans.add(oSS);
129                 }
130             }
131         }
132
133         return Response.status(HttpURLConnection.HTTP_OK).entity(new NeutronVPNServiceRequest(ans)).build();
134     }
135
136     /**
137      * Returns a specific VPN Service
138      */
139
140     @Path("{serviceID}")
141     @GET
142     @Produces({ MediaType.APPLICATION_JSON })
143     @StatusCodes({ @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
144             @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
145             @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
146             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
147             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
148     public Response showVPNService(@PathParam("serviceID") String serviceID,
149     // return fields
150             @QueryParam("fields") List<String> fields) {
151         INeutronVPNServiceCRUD VPNServiceInterface = getNeutronInterfaces().getVPNServiceInterface();
152         if (!VPNServiceInterface.neutronVPNServiceExists(serviceID)) {
153             throw new ResourceNotFoundException(UUID_NO_EXIST);
154         }
155         if (fields.size() > 0) {
156             NeutronVPNService ans = VPNServiceInterface.getVPNService(serviceID);
157             return Response.status(HttpURLConnection.HTTP_OK).entity(new NeutronVPNServiceRequest(extractFields(ans, fields))).build();
158         } else {
159             return Response.status(HttpURLConnection.HTTP_OK)
160                     .entity(new NeutronVPNServiceRequest(VPNServiceInterface.getVPNService(serviceID))).build();
161         }
162     }
163
164     /**
165      * Creates new VPN Service
166      */
167     @POST
168     @Produces({ MediaType.APPLICATION_JSON })
169     @Consumes({ MediaType.APPLICATION_JSON })
170     @TypeHint(NeutronVPNService.class)
171     @StatusCodes({ @ResponseCode(code = HttpURLConnection.HTTP_CREATED, condition = "Created"),
172             @ResponseCode(code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
173             @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
174             @ResponseCode(code = HttpURLConnection.HTTP_FORBIDDEN, condition = "Forbidden"),
175             @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
176             @ResponseCode(code = HttpURLConnection.HTTP_CONFLICT, condition = "Conflict"),
177             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
178             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
179     public Response createVPNService(final NeutronVPNServiceRequest input) {
180         INeutronVPNServiceCRUD VPNServiceInterface = getNeutronInterfaces().getVPNServiceInterface();
181         if (input.isSingleton()) {
182             NeutronVPNService singleton = input.getSingleton();
183
184             Object[] instances = NeutronUtil.getInstances(INeutronVPNServiceAware.class, this);
185             if (instances != null) {
186                 if (instances.length > 0) {
187                     for (Object instance : instances) {
188                         INeutronVPNServiceAware service = (INeutronVPNServiceAware) instance;
189                         int status = service.canCreateNeutronVPNService(singleton);
190                         if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
191                             return Response.status(status).build();
192                         }
193                     }
194                 } else {
195                     throw new ServiceUnavailableException(NO_PROVIDERS);
196                 }
197             } else {
198                 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
199             }
200
201             VPNServiceInterface.addVPNService(singleton);
202             if (instances != null) {
203                 for (Object instance : instances) {
204                     INeutronVPNServiceAware service = (INeutronVPNServiceAware) instance;
205                     service.neutronVPNServiceCreated(singleton);
206                 }
207             }
208         } else {
209             Object[] instances = NeutronUtil.getInstances(INeutronVPNServiceAware.class, this);
210             for (NeutronVPNService test : input.getBulk()) {
211                 if (instances != null) {
212                     if (instances.length > 0) {
213                         for (Object instance : instances) {
214                             INeutronVPNServiceAware service = (INeutronVPNServiceAware) instance;
215                             int status = service.canCreateNeutronVPNService(test);
216                             if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
217                                 return Response.status(status).build();
218                             }
219                         }
220                     } else {
221                         throw new ServiceUnavailableException(NO_PROVIDERS);
222                     }
223                 } else {
224                     throw new ServiceUnavailableException(NO_PROVIDER_LIST);
225                 }
226             }
227             /*
228              * now, each element of the bulk request can be added to the cache
229              */
230             for (NeutronVPNService test : input.getBulk()) {
231                 VPNServiceInterface.addVPNService(test);
232                 if (instances != null) {
233                     for (Object instance : instances) {
234                         INeutronVPNServiceAware service = (INeutronVPNServiceAware) instance;
235                         service.neutronVPNServiceCreated(test);
236                     }
237                 }
238             }
239         }
240         return Response.status(HttpURLConnection.HTTP_CREATED).entity(input).build();
241     }
242
243     /**
244      * Updates a VPN Service
245      */
246     @Path("{serviceID}")
247     @PUT
248     @Produces({ MediaType.APPLICATION_JSON })
249     @Consumes({ MediaType.APPLICATION_JSON })
250     @StatusCodes({ @ResponseCode(code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
251             @ResponseCode(code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
252             @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
253             @ResponseCode(code = HttpURLConnection.HTTP_FORBIDDEN, condition = "Forbidden"),
254             @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
255             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
256             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
257     public Response updateVPNService(@PathParam("serviceID") String serviceID, final NeutronVPNServiceRequest input) {
258         INeutronVPNServiceCRUD VPNServiceInterface = getNeutronInterfaces().getVPNServiceInterface();
259
260         NeutronVPNService delta = input.getSingleton();
261         NeutronVPNService original = VPNServiceInterface.getVPNService(serviceID);
262
263         Object[] instances = NeutronUtil.getInstances(INeutronVPNServiceAware.class, this);
264         if (instances != null) {
265             if (instances.length > 0) {
266                 for (Object instance : instances) {
267                     INeutronVPNServiceAware service = (INeutronVPNServiceAware) instance;
268                     int status = service.canUpdateNeutronVPNService(delta, original);
269                     if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
270                         return Response.status(status).build();
271                     }
272                 }
273             } else {
274                 throw new ServiceUnavailableException(NO_PROVIDERS);
275             }
276         } else {
277             throw new ServiceUnavailableException(NO_PROVIDER_LIST);
278         }
279
280         /*
281          * update the object and return it
282          */
283         VPNServiceInterface.updateVPNService(serviceID, delta);
284         NeutronVPNService updatedVPNService = VPNServiceInterface.getVPNService(serviceID);
285         if (instances != null) {
286             for (Object instance : instances) {
287                 INeutronVPNServiceAware service = (INeutronVPNServiceAware) instance;
288                 service.neutronVPNServiceUpdated(updatedVPNService);
289             }
290         }
291         return Response.status(HttpURLConnection.HTTP_OK).entity(new NeutronVPNServiceRequest(VPNServiceInterface.getVPNService(serviceID)))
292                 .build();
293     }
294
295     /**
296      * Deletes a VPN Service
297      */
298
299     @Path("{serviceID}")
300     @DELETE
301     @StatusCodes({ @ResponseCode(code = HttpURLConnection.HTTP_NO_CONTENT, condition = "No Content"),
302             @ResponseCode(code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
303             @ResponseCode(code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
304             @ResponseCode(code = HttpURLConnection.HTTP_CONFLICT, condition = "Conflict"),
305             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
306             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
307     public Response deleteVPNService(@PathParam("serviceID") String serviceID) {
308         INeutronVPNServiceCRUD VPNServiceInterface = getNeutronInterfaces().getVPNServiceInterface();
309
310         NeutronVPNService singleton = VPNServiceInterface.getVPNService(serviceID);
311         Object[] instances = NeutronUtil.getInstances(INeutronVPNServiceAware.class, this);
312         if (instances != null) {
313             if (instances.length > 0) {
314                 for (Object instance : instances) {
315                     INeutronVPNServiceAware service = (INeutronVPNServiceAware) instance;
316                     int status = service.canDeleteNeutronVPNService(singleton);
317                     if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
318                         return Response.status(status).build();
319                     }
320                 }
321             } else {
322                 throw new ServiceUnavailableException(NO_PROVIDERS);
323             }
324         } else {
325             throw new ServiceUnavailableException(NO_PROVIDER_LIST);
326         }
327
328         VPNServiceInterface.removeVPNService(serviceID);
329         if (instances != null) {
330             for (Object instance : instances) {
331                 INeutronVPNServiceAware service = (INeutronVPNServiceAware) instance;
332                 service.neutronVPNServiceDeleted(singleton);
333             }
334         }
335         return Response.status(HttpURLConnection.HTTP_NO_CONTENT).build();
336     }
337 }