Merge "BUG #4044 binding:host_id is string, not UUID"
[neutron.git] / northbound-api / src / main / java / org / opendaylight / neutron / northbound / api / NeutronSecurityRulesNorthbound.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 import java.util.Map;
19
20 import javax.ws.rs.Consumes;
21 import javax.ws.rs.DELETE;
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.MediaType;
30 import javax.ws.rs.core.Response;
31
32 import org.codehaus.enunciate.jaxrs.ResponseCode;
33 import org.codehaus.enunciate.jaxrs.StatusCodes;
34 import org.opendaylight.neutron.spi.INeutronSecurityRuleAware;
35 import org.opendaylight.neutron.spi.INeutronSecurityRuleCRUD;
36 import org.opendaylight.neutron.spi.NeutronCRUDInterfaces;
37 import org.opendaylight.neutron.spi.NeutronSecurityRule;
38
39 /**
40  * Neutron Northbound REST APIs for Security Rule.<br>
41  * This class provides REST APIs for managing neutron Security Rule
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
56 @Path ("/security-group-rules")
57 public class NeutronSecurityRulesNorthbound {
58     private static final int HTTP_OK_BOTTOM = 200;
59     private static final int HTTP_OK_TOP = 299;
60     private static final String INTERFACE_NAME = "Security Rule CRUD Interface";
61     private static final String UUID_NO_EXIST = "Security Rule UUID does not exist.";
62     private static final String UUID_EXISTS = "Security Rule UUID already exists.";
63     private static final String NO_PROVIDERS = "No providers registered.  Please try again later";
64     private static final String NO_PROVIDER_LIST = "Couldn't get providers list.  Please try again later";
65
66     private NeutronSecurityRule extractFields(NeutronSecurityRule o, List<String> fields) {
67         return o.extractFields(fields);
68     }
69
70     private NeutronCRUDInterfaces getNeutronInterfaces() {
71         NeutronCRUDInterfaces answer = new NeutronCRUDInterfaces().fetchINeutronSecurityRuleCRUD(this);
72         if (answer.getSecurityRuleInterface() == null) {
73             throw new ServiceUnavailableException(INTERFACE_NAME
74                 + RestMessages.SERVICEUNAVAILABLE.toString());
75         }
76         return answer;
77     }
78
79     /**
80      * Returns a list of all Security Rules
81      */
82     @GET
83     @Produces ({MediaType.APPLICATION_JSON})
84     @StatusCodes ({
85             @ResponseCode (code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
86             @ResponseCode (code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
87             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
88             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
89     public Response listRules(
90             // return fields
91             @QueryParam ("fields") List<String> fields,
92             // OpenStack security rule attributes
93             @QueryParam ("id") String querySecurityRuleUUID,
94             @QueryParam ("direction") String querySecurityRuleDirection,
95             @QueryParam ("protocol") String querySecurityRuleProtocol,
96             @QueryParam ("port_range_min") Integer querySecurityRulePortMin,
97             @QueryParam ("port_range_max") Integer querySecurityRulePortMax,
98             @QueryParam ("ethertype") String querySecurityRuleEthertype,
99             @QueryParam ("remote_ip_prefix") String querySecurityRuleIpPrefix,
100             @QueryParam ("remote_group_id") String querySecurityRemoteGroupID,
101             @QueryParam ("security_group_id") String querySecurityRuleGroupID,
102             @QueryParam ("tenant_id") String querySecurityRuleTenantID,
103             @QueryParam ("limit") String limit,
104             @QueryParam ("marker") String marker,
105             @QueryParam ("page_reverse") String pageReverse
106     ) {
107         INeutronSecurityRuleCRUD securityRuleInterface = getNeutronInterfaces().getSecurityRuleInterface();
108         List<NeutronSecurityRule> allSecurityRules = securityRuleInterface.getAllNeutronSecurityRules();
109         List<NeutronSecurityRule> ans = new ArrayList<NeutronSecurityRule>();
110         Iterator<NeutronSecurityRule> i = allSecurityRules.iterator();
111         while (i.hasNext()) {
112             NeutronSecurityRule nsr = i.next();
113             if ((querySecurityRuleUUID == null ||
114                     querySecurityRuleUUID.equals(nsr.getSecurityRuleUUID())) &&
115                     (querySecurityRuleDirection == null ||
116                             querySecurityRuleDirection.equals(nsr.getSecurityRuleDirection())) &&
117                     (querySecurityRuleProtocol == null ||
118                             querySecurityRuleProtocol.equals(nsr.getSecurityRuleProtocol())) &&
119                     (querySecurityRulePortMin == null ||
120                             querySecurityRulePortMin.equals(nsr.getSecurityRulePortMin())) &&
121                     (querySecurityRulePortMax == null ||
122                             querySecurityRulePortMax.equals(nsr.getSecurityRulePortMax())) &&
123                     (querySecurityRuleEthertype == null ||
124                             querySecurityRuleEthertype.equals(nsr.getSecurityRuleEthertype())) &&
125                     (querySecurityRuleIpPrefix == null ||
126                             querySecurityRuleIpPrefix.equals(nsr.getSecurityRuleRemoteIpPrefix())) &&
127                     (querySecurityRuleGroupID == null ||
128                             querySecurityRuleGroupID.equals(nsr.getSecurityRuleGroupID())) &&
129                     (querySecurityRemoteGroupID == null ||
130                             querySecurityRemoteGroupID.equals(nsr.getSecurityRemoteGroupID())) &&
131                     (querySecurityRuleTenantID == null ||
132                             querySecurityRuleTenantID.equals(nsr.getSecurityRuleTenantID()))) {
133                 if (fields.size() > 0) {
134                     ans.add(extractFields(nsr, fields));
135                 } else {
136                     ans.add(nsr);
137                 }
138             }
139         }
140         return Response.status(HttpURLConnection.HTTP_OK).entity(
141                 new NeutronSecurityRuleRequest(ans)).build();
142     }
143
144     /**
145      * Returns a specific Security Rule
146      */
147
148     @Path ("{securityRuleUUID}")
149     @GET
150     @Produces ({MediaType.APPLICATION_JSON})
151     @StatusCodes ({
152             @ResponseCode (code = HttpURLConnection.HTTP_OK, condition = "Operation successful"),
153             @ResponseCode (code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
154             @ResponseCode (code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
155             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
156             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
157     public Response showSecurityRule(@PathParam ("securityRuleUUID") String securityRuleUUID,
158                                      // return fields
159                                      @QueryParam ("fields") List<String> fields) {
160         INeutronSecurityRuleCRUD securityRuleInterface = getNeutronInterfaces().getSecurityRuleInterface();
161         if (!securityRuleInterface.neutronSecurityRuleExists(securityRuleUUID)) {
162             throw new ResourceNotFoundException(UUID_NO_EXIST);
163         }
164         if (!fields.isEmpty()) {
165             NeutronSecurityRule ans = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID);
166             return Response.status(HttpURLConnection.HTTP_OK).entity(
167                     new NeutronSecurityRuleRequest(extractFields(ans, fields))).build();
168         } else {
169             return Response.status(HttpURLConnection.HTTP_OK).entity(new NeutronSecurityRuleRequest(securityRuleInterface.getNeutronSecurityRule(securityRuleUUID))).build();
170         }
171     }
172
173     /**
174      * Creates new Security Rule
175      */
176
177     @POST
178     @Produces ({MediaType.APPLICATION_JSON})
179     @Consumes ({MediaType.APPLICATION_JSON})
180     @StatusCodes ({
181             @ResponseCode (code = HttpURLConnection.HTTP_CREATED, condition = "Created"),
182             @ResponseCode (code = HttpURLConnection.HTTP_BAD_REQUEST, condition = "Bad Request"),
183             @ResponseCode (code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
184             @ResponseCode (code = HttpURLConnection.HTTP_FORBIDDEN, condition = "Forbidden"),
185             @ResponseCode (code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
186             @ResponseCode (code = HttpURLConnection.HTTP_CONFLICT, condition = "Conflict"),
187             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
188             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
189     public Response createSecurityRules(final NeutronSecurityRuleRequest input) {
190         INeutronSecurityRuleCRUD securityRuleInterface = getNeutronInterfaces().getSecurityRuleInterface();
191
192         if (input.isSingleton()) {
193             NeutronSecurityRule singleton = input.getSingleton();
194             Object[] instances = NeutronUtil.getInstances(INeutronSecurityRuleAware.class, this);
195             if (instances != null) {
196                 if (instances.length > 0) {
197                     for (Object instance : instances) {
198                         INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
199                         int status = service.canCreateNeutronSecurityRule(singleton);
200                         if ((status < HTTP_OK_BOTTOM) || (status > HTTP_OK_TOP)) {
201                             return Response.status(status).build();
202                         }
203                     }
204                 } else {
205                     throw new ServiceUnavailableException(NO_PROVIDERS);
206                 }
207             } else {
208                 throw new ServiceUnavailableException(NO_PROVIDER_LIST);
209             }
210
211             // add rule to cache
212             singleton.initDefaults();
213             securityRuleInterface.addNeutronSecurityRule(singleton);
214             if (instances != null) {
215                 for (Object instance : instances) {
216                     INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
217                     service.neutronSecurityRuleCreated(singleton);
218                 }
219             }
220         } else {
221             Object[] instances = NeutronUtil.getInstances(INeutronSecurityRuleAware.class, this);
222             for (NeutronSecurityRule test : input.getBulk()) {
223                 if (instances != null) {
224                     if (instances.length > 0) {
225                         for (Object instance : instances) {
226                             INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
227                             int status = service.canCreateNeutronSecurityRule(test);
228                             if ((status < HTTP_OK_BOTTOM) || (status > HTTP_OK_TOP)) {
229                                 return Response.status(status).build();
230                             }
231                         }
232                     } else {
233                         throw new ServiceUnavailableException(NO_PROVIDERS);
234                     }
235                 } else {
236                     throw new ServiceUnavailableException(NO_PROVIDER_LIST);
237                 }
238             }
239
240             /*
241              * now, each element of the bulk request can be added to the cache
242              */
243             for (NeutronSecurityRule test : input.getBulk()) {
244                 securityRuleInterface.addNeutronSecurityRule(test);
245                 if (instances != null) {
246                     for (Object instance : instances) {
247                         INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
248                         service.neutronSecurityRuleCreated(test);
249                     }
250                 }
251             }
252         }
253         return Response.status(HttpURLConnection.HTTP_CREATED).entity(input).build();
254     }
255
256     /**
257      * Updates a Security Rule
258      */
259
260     @Path ("{securityRuleUUID}")
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 updateSecurityRule(
273             @PathParam ("securityRuleUUID") String securityRuleUUID, final NeutronSecurityRuleRequest input) {
274         INeutronSecurityRuleCRUD securityRuleInterface = getNeutronInterfaces().getSecurityRuleInterface();
275
276         NeutronSecurityRule delta = input.getSingleton();
277         NeutronSecurityRule original = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID);
278
279         Object[] instances = NeutronUtil.getInstances(INeutronSecurityRuleAware.class, this);
280         if (instances != null) {
281             if (instances.length > 0) {
282                 for (Object instance : instances) {
283                     INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
284                     int status = service.canUpdateNeutronSecurityRule(delta, original);
285                     if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
286                         return Response.status(status).build();
287                     }
288                 }
289             } else {
290                 throw new ServiceUnavailableException(NO_PROVIDERS);
291             }
292         } else {
293             throw new ServiceUnavailableException(NO_PROVIDER_LIST);
294         }
295
296         /*
297          * update the object and return it
298          */
299         securityRuleInterface.updateNeutronSecurityRule(securityRuleUUID, delta);
300         NeutronSecurityRule updatedSecurityRule = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID);
301         if (instances != null) {
302             for (Object instance : instances) {
303                 INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
304                 service.neutronSecurityRuleUpdated(updatedSecurityRule);
305             }
306         }
307         return Response.status(HttpURLConnection.HTTP_OK).entity(new NeutronSecurityRuleRequest(securityRuleInterface.getNeutronSecurityRule(securityRuleUUID))).build();
308     }
309
310     /**
311      * Deletes a Security Rule
312      */
313
314     @Path ("{securityRuleUUID}")
315     @DELETE
316     @StatusCodes ({
317             @ResponseCode (code = HttpURLConnection.HTTP_NO_CONTENT, condition = "No Content"),
318             @ResponseCode (code = HttpURLConnection.HTTP_UNAUTHORIZED, condition = "Unauthorized"),
319             @ResponseCode (code = HttpURLConnection.HTTP_NOT_FOUND, condition = "Not Found"),
320             @ResponseCode (code = HttpURLConnection.HTTP_CONFLICT, condition = "Conflict"),
321             @ResponseCode(code = HttpURLConnection.HTTP_NOT_IMPLEMENTED, condition = "Not Implemented"),
322             @ResponseCode(code = HttpURLConnection.HTTP_UNAVAILABLE, condition = "No providers available") })
323     public Response deleteSecurityRule(
324             @PathParam ("securityRuleUUID") String securityRuleUUID) {
325         INeutronSecurityRuleCRUD securityRuleInterface = getNeutronInterfaces().getSecurityRuleInterface();
326
327         NeutronSecurityRule singleton = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID);
328         Object[] instances = NeutronUtil.getInstances(INeutronSecurityRuleAware.class, this);
329         if (instances != null) {
330             if (instances.length > 0) {
331                 for (Object instance : instances) {
332                     INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
333                     int status = service.canDeleteNeutronSecurityRule(singleton);
334                     if (status < HTTP_OK_BOTTOM || status > HTTP_OK_TOP) {
335                         return Response.status(status).build();
336                     }
337                 }
338             } else {
339                 throw new ServiceUnavailableException(NO_PROVIDERS);
340             }
341         } else {
342             throw new ServiceUnavailableException(NO_PROVIDER_LIST);
343         }
344
345
346         /*
347          * remove it and return 204 status
348          */
349         securityRuleInterface.removeNeutronSecurityRule(securityRuleUUID);
350         if (instances != null) {
351             for (Object instance : instances) {
352                 INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
353                 service.neutronSecurityRuleDeleted(singleton);
354             }
355         }
356         return Response.status(HttpURLConnection.HTTP_NO_CONTENT).build();
357     }
358 }