Change NeutronCRUDInterfaces class from static
[neutron.git] / northbound-api / src / main / java / org / opendaylight / neutron / northbound / api / NeutronSecurityGroupsNorthbound.java
1 /*
2  * Copyright (C) 2014 Red Hat, Inc.
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
10 package org.opendaylight.neutron.northbound.api;
11
12 import java.net.HttpURLConnection;
13
14 import java.util.ArrayList;
15 import java.util.HashMap;
16 import java.util.Iterator;
17 import java.util.List;
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.MediaType;
29 import javax.ws.rs.core.Response;
30
31 import org.codehaus.enunciate.jaxrs.ResponseCode;
32 import org.codehaus.enunciate.jaxrs.StatusCodes;
33 import org.opendaylight.neutron.spi.INeutronSecurityGroupAware;
34 import org.opendaylight.neutron.spi.INeutronSecurityGroupCRUD;
35 import org.opendaylight.neutron.spi.NeutronCRUDInterfaces;
36 import org.opendaylight.neutron.spi.NeutronSecurityGroup;
37
38 /**
39  * Neutron Northbound REST APIs for Security Group.<br>
40  * This class provides REST APIs for managing neutron Security Group
41  * <p>
42  * <br>
43  * <br>
44  * Authentication scheme : <b>HTTP Basic</b><br>
45  * Authentication realm : <b>opendaylight</b><br>
46  * Transport : <b>HTTP and HTTPS</b><br>
47  * <br>
48  * HTTPS Authentication is disabled by default. Administrator can enable it in
49  * tomcat-server.xml after adding a proper keystore / SSL certificate from a
50  * trusted authority.<br>
51  * More info :
52  * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
53  */
54 @Path ("/security-groups")
55 public class NeutronSecurityGroupsNorthbound {
56     private static final int HTTP_OK_BOTTOM = 200;
57     private static final int HTTP_OK_TOP = 299;
58     private static final String INTERFACE_NAME = "Security Group CRUD Interface";
59     private static final String UUID_NO_EXIST = "Security Group UUID does not exist.";
60     private static final String NO_PROVIDERS = "No providers registered.  Please try again later";
61     private static final String NO_PROVIDER_LIST = "Couldn't get providers list.  Please try again later";
62
63     private NeutronSecurityGroup extractFields(NeutronSecurityGroup o, List<String> fields) {
64         return o.extractFields(fields);
65     }
66
67     private NeutronCRUDInterfaces getNeutronInterfaces() {
68         NeutronCRUDInterfaces answer = new NeutronCRUDInterfaces().fetchINeutronSecurityGroupCRUD(this);
69         if (answer.getSecurityGroupInterface() == null) {
70             throw new ServiceUnavailableException(INTERFACE_NAME
71                 + RestMessages.SERVICEUNAVAILABLE.toString());
72         }
73         return answer;
74     }
75
76     /**
77      * Returns a list of all Security Groups
78      */
79     @GET
80     @Produces ({MediaType.APPLICATION_JSON})
81     @StatusCodes ({
82             @ResponseCode (code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
83             @ResponseCode (code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
84             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
85             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
86
87     public Response listGroups(
88             // return fields
89             @QueryParam ("fields") List<String> fields,
90             // OpenStack security group attributes
91             @QueryParam ("id") String querySecurityGroupUUID,
92             @QueryParam ("name") String querySecurityGroupName,
93             @QueryParam ("description") String querySecurityDescription,
94             @QueryParam ("tenant_id") String querySecurityTenantID,
95             @QueryParam ("limit") String limit,
96             @QueryParam ("marker") String marker,
97             @QueryParam ("page_reverse") String pageReverse
98     ) {
99         INeutronSecurityGroupCRUD securityGroupInterface = getNeutronInterfaces().getSecurityGroupInterface();
100         List<NeutronSecurityGroup> allSecurityGroups = securityGroupInterface.getAllNeutronSecurityGroups();
101         List<NeutronSecurityGroup> ans = new ArrayList<NeutronSecurityGroup>();
102         Iterator<NeutronSecurityGroup> i = allSecurityGroups.iterator();
103         while (i.hasNext()) {
104             NeutronSecurityGroup nsg = i.next();
105             if ((querySecurityGroupUUID == null ||
106                     querySecurityGroupUUID.equals(nsg.getSecurityGroupUUID())) &&
107                     (querySecurityGroupName == null ||
108                             querySecurityGroupName.equals(nsg.getSecurityGroupName())) &&
109                     (querySecurityDescription == null ||
110                             querySecurityDescription.equals(nsg.getSecurityGroupDescription())) &&
111                     (querySecurityTenantID == null ||
112                             querySecurityTenantID.equals(nsg.getSecurityGroupTenantID()))) {
113                 if (fields.size() > 0) {
114                     ans.add(extractFields(nsg, fields));
115                 } else {
116                     ans.add(nsg);
117                 }
118             }
119         }
120         return Response.status(HttpURLConnection.HTTP_OK).entity(
121                 new NeutronSecurityGroupRequest(ans)).build();
122     }
123
124     /**
125      * Returns a specific Security Group
126      */
127
128     @Path ("{securityGroupUUID}")
129     @GET
130     @Produces ({MediaType.APPLICATION_JSON})
131     @StatusCodes ({
132             @ResponseCode (code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
133             @ResponseCode (code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
134             @ResponseCode (code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
135             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
136             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
137     public Response showSecurityGroup(@PathParam ("securityGroupUUID") String securityGroupUUID,
138                                       // return fields
139                                       @QueryParam ("fields") List<String> fields) {
140         INeutronSecurityGroupCRUD securityGroupInterface = getNeutronInterfaces().getSecurityGroupInterface();
141         if (!securityGroupInterface.neutronSecurityGroupExists(securityGroupUUID)) {
142             throw new ResourceNotFoundException(UUID_NO_EXIST);
143         }
144         if (!fields.isEmpty()) {
145             NeutronSecurityGroup ans = securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID);
146             return Response.status(HttpURLConnection.HTTP_OK).entity(
147                     new NeutronSecurityGroupRequest(extractFields(ans, fields))).build();
148         } else {
149             return Response.status(HttpURLConnection.HTTP_OK).entity(new NeutronSecurityGroupRequest(securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID))).build();
150         }
151     }
152
153     /**
154      * Creates new Security Group
155      */
156
157     @POST
158     @Produces ({MediaType.APPLICATION_JSON})
159     @Consumes ({MediaType.APPLICATION_JSON})
160     @StatusCodes ({
161             @ResponseCode (code = HttpURLConnection.HTTP_CREATED, condition = "Created"),
162             @ResponseCode (code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
163             @ResponseCode (code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
164             @ResponseCode (code = HttpURLConnection.HTTP_FORBIDDEN, condition = "Forbidden"),
165             @ResponseCode (code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
166             @ResponseCode (code = HttpURLConnection.HTTP_CONFLICT, condition = "Conflict"),
167             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
168             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
169     public Response createSecurityGroups(final NeutronSecurityGroupRequest input) {
170         INeutronSecurityGroupCRUD securityGroupInterface = getNeutronInterfaces().getSecurityGroupInterface();
171
172         if (input.isSingleton()) {
173             NeutronSecurityGroup singleton = input.getSingleton();
174
175             /*
176              *  Verify that the Security Group doesn't already exist.
177              */
178             if (securityGroupInterface.neutronSecurityGroupExists(singleton.getSecurityGroupUUID())) {
179                 throw new BadRequestException("Security Group UUID already exists");
180             }
181
182             Object[] instances = NeutronUtil.getInstances(INeutronSecurityGroupAware.class, this);
183             if (instances != null) {
184                 if (instances.length > 0) {
185                     for (Object instance : instances) {
186                         INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
187                         int status = service.canCreateNeutronSecurityGroup(singleton);
188                         if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
189                             return Response.status(status).build();
190                         }
191                     }
192                 } else {
193                     throw new ServiceUnavailableException(NO_PROVIDERS);
194                 }
195             } else {
196                 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
197             }
198             // Add to Neutron cache
199             securityGroupInterface.addNeutronSecurityGroup(singleton);
200             if (instances != null) {
201                 for (Object instance : instances) {
202                     INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
203                     service.neutronSecurityGroupCreated(singleton);
204                 }
205             }
206         } else {
207             List<NeutronSecurityGroup> bulk = input.getBulk();
208             Iterator<NeutronSecurityGroup> i = bulk.iterator();
209             HashMap<String, NeutronSecurityGroup> testMap = new HashMap<String, NeutronSecurityGroup>();
210             Object[] instances = NeutronUtil.getInstances(INeutronSecurityGroupAware.class, this);
211             while (i.hasNext()) {
212                 NeutronSecurityGroup test = i.next();
213
214                 /*
215                  *  Verify that the security group doesn't already exist
216                  */
217
218                 if (securityGroupInterface.neutronSecurityGroupExists(test.getSecurityGroupUUID())) {
219                     throw new BadRequestException("Security Group UUID already is already created");
220                 }
221                 if (instances != null) {
222                     if (instances.length > 0) {
223                         for (Object instance : instances) {
224                             INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
225                             int status = service.canCreateNeutronSecurityGroup(test);
226                             if ((status < HTTP_OK_BOTTOM) || (status > HTTP_OK_TOP)) {
227                                 return Response.status(status).build();
228                             }
229                         }
230                     } else {
231                         throw new BadRequestException(NO_PROVIDERS);
232                     }
233                 } else {
234                     throw new ServiceUnavailableException(NO_PROVIDER_LIST);
235                 }
236             }
237
238             /*
239              * now, each element of the bulk request can be added to the cache
240              */
241             i = bulk.iterator();
242             while (i.hasNext()) {
243                 NeutronSecurityGroup test = i.next();
244                 securityGroupInterface.addNeutronSecurityGroup(test);
245                 if (instances != null) {
246                     for (Object instance : instances) {
247                         INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
248                         service.neutronSecurityGroupCreated(test);
249                     }
250                 }
251             }
252         }
253         return Response.status(HttpURLConnection.HTTP_CREATED).entity(input).build();
254     }
255
256     /**
257      * Updates a Security Group
258      */
259
260     @Path ("{securityGroupUUID}")
261     @PUT
262     @Produces ({MediaType.APPLICATION_JSON})
263     @Consumes ({MediaType.APPLICATION_JSON})
264     @StatusCodes ({
265             @ResponseCode (code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
266             @ResponseCode (code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
267             @ResponseCode (code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
268             @ResponseCode (code = HttpURLConnection.HTTP_FORBIDDEN, condition = "Forbidden"),
269             @ResponseCode (code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
270             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
271             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
272     public Response updateSecurityGroup(
273             @PathParam ("securityGroupUUID") String securityGroupUUID, final NeutronSecurityGroupRequest input) {
274         INeutronSecurityGroupCRUD securityGroupInterface = getNeutronInterfaces().getSecurityGroupInterface();
275
276         /*
277          * verify the Security Group exists and there is only one delta provided
278          */
279         if (!securityGroupInterface.neutronSecurityGroupExists(securityGroupUUID)) {
280             throw new ResourceNotFoundException(UUID_NO_EXIST);
281         }
282         if (!input.isSingleton()) {
283             throw new BadRequestException("Only singleton edit supported");
284         }
285         NeutronSecurityGroup delta = input.getSingleton();
286         NeutronSecurityGroup original = securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID);
287
288         if (delta.getSecurityGroupUUID() != null ||
289                 delta.getSecurityGroupTenantID() != null ||
290                 delta.getSecurityGroupName() != null ||
291                 delta.getSecurityGroupDescription() != null) {
292             throw new BadRequestException("Attribute edit blocked by Neutron");
293         }
294
295         Object[] instances =  NeutronUtil.getInstances(INeutronSecurityGroupAware.class, this);
296         if (instances != null) {
297             if (instances.length > 0) {
298                 for (Object instance : instances) {
299                     INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
300                     int status = service.canUpdateNeutronSecurityGroup(delta, original);
301                     if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
302                         return Response.status(status).build();
303                     }
304                 }
305             } else {
306                 throw new ServiceUnavailableException(NO_PROVIDERS);
307             }
308         } else {
309             throw new ServiceUnavailableException(NO_PROVIDER_LIST);
310         }
311
312         /*
313          * update the object and return it
314          */
315         securityGroupInterface.updateNeutronSecurityGroup(securityGroupUUID, delta);
316         NeutronSecurityGroup updatedSecurityGroup = securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID);
317         if (instances != null) {
318             for (Object instance : instances) {
319                 INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
320                 service.neutronSecurityGroupUpdated(updatedSecurityGroup);
321             }
322         }
323         return Response.status(HttpURLConnection.HTTP_OK).entity(new NeutronSecurityGroupRequest(securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID))).build();
324     }
325
326     /**
327      * Deletes a Security Group
328      */
329
330     @Path ("{securityGroupUUID}")
331     @DELETE
332     @StatusCodes ({
333             @ResponseCode (code = HttpURLConnection.HTTP_NO_CONTENT, condition = "No Content"),
334             @ResponseCode (code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
335             @ResponseCode (code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
336             @ResponseCode (code = HttpURLConnection.HTTP_CONFLICT, condition = "Conflict"),
337             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
338             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
339     public Response deleteSecurityGroup(
340             @PathParam ("securityGroupUUID") String securityGroupUUID) {
341         INeutronSecurityGroupCRUD securityGroupInterface = getNeutronInterfaces().getSecurityGroupInterface();
342
343         /*
344          * verify the Security Group exists and it isn't currently in use
345          */
346         if (!securityGroupInterface.neutronSecurityGroupExists(securityGroupUUID)) {
347             throw new ResourceNotFoundException(UUID_NO_EXIST);
348         }
349         if (securityGroupInterface.neutronSecurityGroupInUse(securityGroupUUID)) {
350             return Response.status(HttpURLConnection.HTTP_CONFLICT).build();
351         }
352         NeutronSecurityGroup singleton = securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID);
353         Object[] instances = NeutronUtil.getInstances(INeutronSecurityGroupAware.class, this);
354         if (instances != null) {
355             if (instances.length > 0) {
356                 for (Object instance : instances) {
357                     INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
358                     int status = service.canDeleteNeutronSecurityGroup(singleton);
359                     if ((status < HTTP_OK_BOTTOM) || (status > HTTP_OK_TOP)) {
360                         return Response.status(status).build();
361                     }
362                 }
363             } else {
364                 throw new ServiceUnavailableException(NO_PROVIDERS);
365             }
366         } else {
367             throw new ServiceUnavailableException(NO_PROVIDER_LIST);
368         }
369
370         /*
371          * remove it and return 204 status
372          */
373         securityGroupInterface.removeNeutronSecurityGroup(securityGroupUUID);
374         if (instances != null) {
375             for (Object instance : instances) {
376                 INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
377                 service.neutronSecurityGroupDeleted(singleton);
378             }
379         }
380         return Response.status(HttpURLConnection.HTTP_NO_CONTENT).build();
381     }
382 }