Merge "BUG 1082 Migrate sal-rest-connector to Async Data Broker API"
[controller.git] / opendaylight / northbound / networkconfiguration / neutron / src / main / java / org / opendaylight / controller / networkconfig / neutron / northbound / NeutronFirewallNorthbound.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 package org.opendaylight.controller.networkconfig.neutron.northbound;
10
11
12 import org.codehaus.enunciate.jaxrs.ResponseCode;
13 import org.codehaus.enunciate.jaxrs.StatusCodes;
14 import org.opendaylight.controller.networkconfig.neutron.INeutronFirewallAware;
15 import org.opendaylight.controller.networkconfig.neutron.INeutronFirewallCRUD;
16 import org.opendaylight.controller.networkconfig.neutron.INeutronFirewallRuleCRUD;
17 import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
18 import org.opendaylight.controller.networkconfig.neutron.NeutronFirewall;
19 import org.opendaylight.controller.northbound.commons.RestMessages;
20 import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
21 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
22 import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
23 import org.opendaylight.controller.sal.utils.ServiceHelper;
24
25 import javax.ws.rs.Consumes;
26 import javax.ws.rs.DELETE;
27 import javax.ws.rs.GET;
28 import javax.ws.rs.POST;
29 import javax.ws.rs.PUT;
30 import javax.ws.rs.Path;
31 import javax.ws.rs.PathParam;
32 import javax.ws.rs.Produces;
33 import javax.ws.rs.QueryParam;
34 import javax.ws.rs.core.MediaType;
35 import javax.ws.rs.core.Response;
36 import java.util.ArrayList;
37 import java.util.HashMap;
38 import java.util.Iterator;
39 import java.util.List;
40
41 /**
42  * Neutron Northbound REST APIs for Firewall.<br>
43  * This class provides REST APIs for managing neutron Firewall
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 @Path("/fw/firewalls")
59 public class NeutronFirewallNorthbound {
60
61     private NeutronFirewall extractFields(NeutronFirewall o, List<String> fields) {
62         return o.extractFields(fields);
63     }
64
65     /**
66      * Returns a list of all Firewalls */
67     @GET
68     @Produces({ MediaType.APPLICATION_JSON })
69     @StatusCodes({
70             @ResponseCode(code = 200, condition = "Operation successful"),
71             @ResponseCode(code = 401, condition = "Unauthorized"),
72             @ResponseCode(code = 501, condition = "Not Implemented") })
73
74     public Response listGroups(
75             // return fields
76             @QueryParam("fields") List<String> fields,
77             // OpenStack firewall attributes
78             @QueryParam("id") String queryFirewallUUID,
79             @QueryParam("tenant_id") String queryFirewallTenantID,
80             @QueryParam("name") String queryFirewallName,
81             @QueryParam("description") String queryFirewallDescription,
82             @QueryParam("shared") Boolean queryFirewallAdminStateIsUp,
83             @QueryParam("status") String queryFirewallStatus,
84             @QueryParam("shared") Boolean queryFirewallIsShared,
85             @QueryParam("firewall_policy_id") String queryFirewallPolicyID,
86             // pagination
87             @QueryParam("limit") String limit,
88             @QueryParam("marker") String marker,
89             @QueryParam("page_reverse") String pageReverse
90             // sorting not supported
91     ) {
92         INeutronFirewallCRUD firewallInterface = NeutronCRUDInterfaces.getINeutronFirewallCRUD(this);
93         INeutronFirewallRuleCRUD firewallRuleInterface = NeutronCRUDInterfaces.getINeutronFirewallRuleCRUD(this);
94
95         if (firewallInterface == null) {
96             throw new ServiceUnavailableException("Firewall CRUD Interface "
97                     + RestMessages.SERVICEUNAVAILABLE.toString());
98         }
99         List<NeutronFirewall> allFirewalls = firewallInterface.getAllNeutronFirewalls();
100         List<NeutronFirewall> ans = new ArrayList<NeutronFirewall>();
101         Iterator<NeutronFirewall> i = allFirewalls.iterator();
102         while (i.hasNext()) {
103             NeutronFirewall nsg = i.next();
104             if ((queryFirewallUUID == null ||
105                 queryFirewallUUID.equals(nsg.getFirewallUUID())) &&
106                 (queryFirewallTenantID == null ||
107                     queryFirewallTenantID.equals(nsg.getFirewallTenantID())) &&
108                 (queryFirewallName == null ||
109                     queryFirewallName.equals(nsg.getFirewallName())) &&
110                 (queryFirewallDescription == null ||
111                     queryFirewallDescription.equals(nsg.getFirewallDescription())) &&
112                 (queryFirewallAdminStateIsUp == null ||
113                     queryFirewallAdminStateIsUp.equals(nsg.getFirewallAdminStateIsUp())) &&
114                 (queryFirewallStatus == null ||
115                     queryFirewallStatus.equals(nsg.getFirewallStatus())) &&
116                 (queryFirewallIsShared == null ||
117                     queryFirewallIsShared.equals(nsg.getFirewallIsShared())) &&
118                 (queryFirewallPolicyID == null ||
119                     queryFirewallPolicyID.equals(nsg.getFirewallPolicyID()))) {
120                 if (fields.size() > 0) {
121                     ans.add(extractFields(nsg,fields));
122                 } else {
123                     ans.add(nsg);
124                 }
125             }
126         }
127         //TODO: apply pagination to results
128         return Response.status(200).entity(
129                 new NeutronFirewallRequest(ans)).build();
130     }
131
132     /**
133      * Returns a specific Firewall */
134
135     @Path("{firewallUUID}")
136     @GET
137     @Produces({ MediaType.APPLICATION_JSON })
138     @StatusCodes({
139             @ResponseCode(code = 200, condition = "Operation successful"),
140             @ResponseCode(code = 401, condition = "Unauthorized"),
141             @ResponseCode(code = 404, condition = "Not Found"),
142             @ResponseCode(code = 501, condition = "Not Implemented") })
143     public Response showFirewall(@PathParam("firewallUUID") String firewallUUID,
144                                       // return fields
145                                       @QueryParam("fields") List<String> fields) {
146         INeutronFirewallCRUD firewallInterface = NeutronCRUDInterfaces.getINeutronFirewallCRUD(this);
147         if (firewallInterface == null) {
148             throw new ServiceUnavailableException("Firewall CRUD Interface "
149                     + RestMessages.SERVICEUNAVAILABLE.toString());
150         }
151         if (!firewallInterface.neutronFirewallExists(firewallUUID)) {
152             throw new ResourceNotFoundException("Firewall UUID does not exist.");
153         }
154         if (fields.size() > 0) {
155             NeutronFirewall ans = firewallInterface.getNeutronFirewall(firewallUUID);
156             return Response.status(200).entity(
157                     new NeutronFirewallRequest(extractFields(ans, fields))).build();
158         } else {
159             return Response.status(200).entity(new NeutronFirewallRequest(firewallInterface.getNeutronFirewall(firewallUUID))).build();
160         }
161     }
162
163     /**
164      * Creates new Firewall */
165
166     @POST
167     @Produces({ MediaType.APPLICATION_JSON })
168     @Consumes({ MediaType.APPLICATION_JSON })
169     @StatusCodes({
170             @ResponseCode(code = 201, condition = "Created"),
171             @ResponseCode(code = 400, condition = "Bad Request"),
172             @ResponseCode(code = 401, condition = "Unauthorized"),
173             @ResponseCode(code = 403, condition = "Forbidden"),
174             @ResponseCode(code = 404, condition = "Not Found"),
175             @ResponseCode(code = 409, condition = "Conflict"),
176             @ResponseCode(code = 501, condition = "Not Implemented") })
177     public Response createFirewalls(final NeutronFirewallRequest input) {
178         INeutronFirewallCRUD firewallInterface = NeutronCRUDInterfaces.getINeutronFirewallCRUD(this);
179         if (firewallInterface == null) {
180             throw new ServiceUnavailableException("Firewall CRUD Interface "
181                     + RestMessages.SERVICEUNAVAILABLE.toString());
182         }
183         if (input.isSingleton()) {
184             NeutronFirewall singleton = input.getSingleton();
185
186             /*
187              *  Verify that the Firewall doesn't already exist.
188              */
189             if (firewallInterface.neutronFirewallExists(singleton.getFirewallUUID())) {
190                 throw new BadRequestException("Firewall UUID already exists");
191             }
192             firewallInterface.addNeutronFirewall(singleton);
193             Object[] instances = ServiceHelper.getGlobalInstances(INeutronFirewallAware.class, this, null);
194             if (instances != null) {
195                 for (Object instance : instances) {
196                     INeutronFirewallAware service = (INeutronFirewallAware) instance;
197                     int status = service.canCreateNeutronFirewall(singleton);
198                     if (status < 200 || status > 299) {
199                         return Response.status(status).build();
200                     }
201                 }
202             }
203             firewallInterface.addNeutronFirewall(singleton);
204             if (instances != null) {
205                 for (Object instance : instances) {
206                     INeutronFirewallAware service = (INeutronFirewallAware) instance;
207                     service.neutronFirewallCreated(singleton);
208                 }
209             }
210         } else {
211             List<NeutronFirewall> bulk = input.getBulk();
212             Iterator<NeutronFirewall> i = bulk.iterator();
213             HashMap<String, NeutronFirewall> testMap = new HashMap<String, NeutronFirewall>();
214             Object[] instances = ServiceHelper.getGlobalInstances(INeutronFirewallAware.class, this, null);
215             while (i.hasNext()) {
216                 NeutronFirewall test = i.next();
217
218                 /*
219                  *  Verify that the secruity group doesn't already exist
220                  */
221                 if (firewallInterface.neutronFirewallExists(test.getFirewallUUID())) {
222                     throw new BadRequestException("Firewall UUID already is already created");
223                 }
224                 if (testMap.containsKey(test.getFirewallUUID())) {
225                     throw new BadRequestException("Firewall UUID already exists");
226                 }
227                 if (instances != null) {
228                     for (Object instance : instances) {
229                         INeutronFirewallAware service = (INeutronFirewallAware) instance;
230                         int status = service.canCreateNeutronFirewall(test);
231                         if (status < 200 || status > 299) {
232                             return Response.status(status).build();
233                         }
234                     }
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                 NeutronFirewall test = i.next();
244                 firewallInterface.addNeutronFirewall(test);
245                 if (instances != null) {
246                     for (Object instance : instances) {
247                         INeutronFirewallAware service = (INeutronFirewallAware) instance;
248                         service.neutronFirewallCreated(test);
249                     }
250                 }
251             }
252         }
253         return Response.status(201).entity(input).build();
254     }
255
256     /**
257      * Updates a Firewall */
258
259     @Path("{firewallUUID}")
260     @PUT
261     @Produces({ MediaType.APPLICATION_JSON })
262     @Consumes({ MediaType.APPLICATION_JSON })
263     @StatusCodes({
264             @ResponseCode(code = 200, condition = "Operation successful"),
265             @ResponseCode(code = 400, condition = "Bad Request"),
266             @ResponseCode(code = 401, condition = "Unauthorized"),
267             @ResponseCode(code = 403, condition = "Forbidden"),
268             @ResponseCode(code = 404, condition = "Not Found"),
269             @ResponseCode(code = 501, condition = "Not Implemented") })
270     public Response updateFirewall(
271             @PathParam("firewallUUID") String firewallUUID, final NeutronFirewallRequest input) {
272         INeutronFirewallCRUD firewallInterface = NeutronCRUDInterfaces.getINeutronFirewallCRUD(this);
273         if (firewallInterface == null) {
274             throw new ServiceUnavailableException("Firewall CRUD Interface "
275                     + RestMessages.SERVICEUNAVAILABLE.toString());
276         }
277
278         /*
279          * verify the Firewall exists and there is only one delta provided
280          */
281         if (!firewallInterface.neutronFirewallExists(firewallUUID)) {
282             throw new ResourceNotFoundException("Firewall UUID does not exist.");
283         }
284         if (!input.isSingleton()) {
285             throw new BadRequestException("Only singleton edit supported");
286         }
287         NeutronFirewall delta = input.getSingleton();
288         NeutronFirewall original = firewallInterface.getNeutronFirewall(firewallUUID);
289
290         /*
291          * updates restricted by Neutron
292          */
293         if (delta.getFirewallUUID() != null ||
294                 delta.getFirewallTenantID() != null ||
295                 delta.getFirewallName() != null ||
296                 delta.getFirewallDescription() != null ||
297                 delta.getFirewallAdminStateIsUp() != null ||
298                 delta.getFirewallStatus() != null ||
299                 delta.getFirewallIsShared() != null ||
300                 delta.getFirewallPolicyID() != null) {
301             throw new BadRequestException("Attribute edit blocked by Neutron");
302         }
303
304         Object[] instances = ServiceHelper.getGlobalInstances(INeutronFirewallAware.class, this, null);
305         if (instances != null) {
306             for (Object instance : instances) {
307                 INeutronFirewallAware service = (INeutronFirewallAware) instance;
308                 int status = service.canUpdateNeutronFirewall(delta, original);
309                 if (status < 200 || status > 299) {
310                     return Response.status(status).build();
311                 }
312             }
313         }
314
315         /*
316          * update the object and return it
317          */
318         firewallInterface.updateNeutronFirewall(firewallUUID, delta);
319         NeutronFirewall updatedFirewall = firewallInterface.getNeutronFirewall(firewallUUID);
320         if (instances != null) {
321             for (Object instance : instances) {
322                 INeutronFirewallAware service = (INeutronFirewallAware) instance;
323                 service.neutronFirewallUpdated(updatedFirewall);
324             }
325         }
326         return Response.status(200).entity(new NeutronFirewallRequest(firewallInterface.getNeutronFirewall(firewallUUID))).build();
327     }
328
329     /**
330      * Deletes a Firewall */
331
332     @Path("{firewallUUID}")
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     public Response deleteFirewall(
341             @PathParam("firewallUUID") String firewallUUID) {
342         INeutronFirewallCRUD firewallInterface = NeutronCRUDInterfaces.getINeutronFirewallCRUD(this);
343         if (firewallInterface == null) {
344             throw new ServiceUnavailableException("Firewall CRUD Interface "
345                     + RestMessages.SERVICEUNAVAILABLE.toString());
346         }
347
348         /*
349          * verify the Firewall exists and it isn't currently in use
350          */
351         if (!firewallInterface.neutronFirewallExists(firewallUUID)) {
352             throw new ResourceNotFoundException("Firewall UUID does not exist.");
353         }
354         if (firewallInterface.neutronFirewallInUse(firewallUUID)) {
355             return Response.status(409).build();
356         }
357         NeutronFirewall singleton = firewallInterface.getNeutronFirewall(firewallUUID);
358         Object[] instances = ServiceHelper.getGlobalInstances(INeutronFirewallAware.class, this, null);
359         if (instances != null) {
360             for (Object instance : instances) {
361                 INeutronFirewallAware service = (INeutronFirewallAware) instance;
362                 int status = service.canDeleteNeutronFirewall(singleton);
363                 if (status < 200 || status > 299) {
364                     return Response.status(status).build();
365                 }
366             }
367         }
368
369         /*
370          * remove it and return 204 status
371          */
372         firewallInterface.removeNeutronFirewall(firewallUUID);
373         if (instances != null) {
374             for (Object instance : instances) {
375                 INeutronFirewallAware service = (INeutronFirewallAware) instance;
376                 service.neutronFirewallDeleted(singleton);
377             }
378         }
379         return Response.status(204).build();
380     }
381 }