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