Merge "Reuse PEM provider in netconf-testtool."
[controller.git] / opendaylight / adsal / northbound / staticrouting / src / main / java / org / opendaylight / controller / forwarding / staticrouting / northbound / StaticRoutingNorthbound.java
1
2 /*
3  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7  * and is available at http://www.eclipse.org/legal/epl-v10.html
8  */
9
10 package org.opendaylight.controller.forwarding.staticrouting.northbound;
11
12 import java.util.ArrayList;
13 import java.util.List;
14
15 import javax.ws.rs.Consumes;
16 import javax.ws.rs.DELETE;
17 import javax.ws.rs.GET;
18 import javax.ws.rs.PUT;
19 import javax.ws.rs.Path;
20 import javax.ws.rs.PathParam;
21 import javax.ws.rs.Produces;
22 import javax.ws.rs.QueryParam;
23 import javax.ws.rs.core.Context;
24 import javax.ws.rs.core.MediaType;
25 import javax.ws.rs.core.Response;
26 import javax.ws.rs.core.SecurityContext;
27 import javax.ws.rs.core.UriInfo;
28 import javax.ws.rs.ext.ContextResolver;
29
30 import org.codehaus.enunciate.jaxrs.ResponseCode;
31 import org.codehaus.enunciate.jaxrs.StatusCodes;
32 import org.codehaus.enunciate.jaxrs.TypeHint;
33 import org.opendaylight.controller.containermanager.IContainerManager;
34 import org.opendaylight.controller.forwarding.staticrouting.IForwardingStaticRouting;
35 import org.opendaylight.controller.forwarding.staticrouting.StaticRouteConfig;
36 import org.opendaylight.controller.northbound.commons.RestMessages;
37 import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
38 import org.opendaylight.controller.northbound.commons.exception.NotAcceptableException;
39 import org.opendaylight.controller.northbound.commons.exception.ResourceConflictException;
40 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
41 import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
42 import org.opendaylight.controller.northbound.commons.query.QueryContext;
43 import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
44 import org.opendaylight.controller.sal.authorization.Privilege;
45 import org.opendaylight.controller.sal.utils.GlobalConstants;
46 import org.opendaylight.controller.sal.utils.ServiceHelper;
47 import org.opendaylight.controller.sal.utils.Status;
48
49 /**
50  * <p>Static Routing Northbound API allows for the management of the static
51  * routes.</p>
52  * </br>
53  * An example request/response for retrieving the static routes may look like this: </br>
54  * <pre>
55  * GET http://localhost:8080/controller/nb/v2/staticroute/default HTTP/1.1
56  * Accept: application/json
57  *
58  * HTTP/1.1 200 OK
59  * Content-Type: application/json
60  *
61  * { "staticRoute":[
62  *       "name":"route-1",
63  *       "prefix":"10.10.1.0/24",
64  *       "nextHop":"1.1.1.1"
65  *   ]
66  * }
67  *
68  * </pre>
69  *
70  * <br><br>
71  * Authentication scheme : <b>HTTP Basic</b><br>
72  * Authentication realm : <b>opendaylight</b><br>
73  * Transport : <b>HTTP and HTTPS</b><br>
74  * <br>
75  */
76 @Path("/")
77 public class StaticRoutingNorthbound {
78
79     private String username;
80     private QueryContext queryContext;
81
82     @Context
83     public void setQueryContext(ContextResolver<QueryContext> queryCtxResolver) {
84       if (queryCtxResolver != null) {
85         queryContext = queryCtxResolver.getContext(QueryContext.class);
86       }
87     }
88
89     @Context
90     public void setSecurityContext(SecurityContext context) {
91         if (context != null && context.getUserPrincipal() != null) {
92             username = context.getUserPrincipal().getName();
93         }
94     }
95     protected String getUserName() {
96         return username;
97     }
98
99
100
101     private List<StaticRoute> getStaticRoutesInternal(String containerName) {
102
103         IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
104                 .getInstance(IForwardingStaticRouting.class, containerName,
105                         this);
106
107         if (staticRouting == null) {
108             throw new ResourceNotFoundException(RestMessages.NOCONTAINER
109                     .toString());
110         }
111
112         List<StaticRoute> routes = new ArrayList<StaticRoute>();
113
114         for (StaticRouteConfig conf : staticRouting.getStaticRouteConfigs()
115                 .values()) {
116             StaticRoute route = new StaticRoute(conf.getName(), conf
117                     .getStaticRoute(), conf.getNextHop());
118             routes.add(route);
119         }
120         return routes;
121     }
122
123     /**
124      * Get a list of static routes present on the given container.
125      *
126      * @param containerName Name of the Container. The Container name for the base controller is "default".
127      * @return List of configured static routes on the given container
128      *
129      * <pre>
130      * Example:
131      *
132      * Request URL:
133      * http://localhost:8080/controller/nb/v2/staticroute/default/routes
134      *
135      * Response body in XML:
136      *  &lt;list&gt;
137      *   &lt;staticRoute&gt;
138      *     &lt;name&gt;route-1&lt;/name&gt;
139      *     &lt;prefix&gt;10.10.1.0/24&lt;/prefix&gt;
140      *     &lt;nextHop&gt;1.1.1.1&lt;/nextHop&gt;
141      *   &lt;/staticRoute&gt;
142      *  &lt;/list&gt;
143      *
144      * Response body in JSON:
145      * {
146      *    "staticRoute": [
147      *      {
148      *       "name": "route-1",
149      *       "prefix": "10.10.1.0/24",
150      *       "nextHop": "1.1.1.1"
151      *      }
152      *    ]
153      * }
154      * </pre>
155      */
156     @Path("/{containerName}/routes")
157     @GET
158     @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
159     @TypeHint(StaticRoutes.class)
160     @StatusCodes( {
161             @ResponseCode(code = 200, condition = "Operation successful"),
162             @ResponseCode(code = 404, condition = "The containerName passed was not found") })
163     public StaticRoutes getStaticRoutes(
164             @PathParam("containerName") String containerName,
165             @QueryParam("_q") String queryString) {
166
167         if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
168                 Privilege.WRITE, this)){
169             throw new
170                 UnauthorizedException("User is not authorized to perform this operation on container "
171                             + containerName);
172         }
173         StaticRoutes result = new StaticRoutes(getStaticRoutesInternal(containerName));
174         if (queryString != null) {
175             queryContext.createQuery(queryString, StaticRoutes.class)
176                 .filter(result, StaticRoute.class);
177         }
178         return result;
179     }
180
181     /**
182      * Returns the static route for the provided configuration name on a given container
183      *
184      * @param containerName Name of the Container. The Container name for the base controller is "default".
185      * @param route Name of the Static Route configuration
186      * @return Static route configured with the supplied Name.
187      *
188      * <pre>
189      * Example:
190      *
191      * Request URL:
192      * http://localhost:8080/controller/nb/v2/staticroute/default/route/route-1
193      *
194      * Response body in XML:
195      *
196      *   &lt;staticRoute&gt;
197      *     &lt;name&gt;route-1&lt;/name&gt;
198      *     &lt;prefix&gt;10.10.1.0/24&lt;/prefix&gt;
199      *     &lt;nextHop&gt;1.1.1.1&lt;/nextHop&gt;
200      *   &lt;/staticRoute&gt;
201      *
202      * Response body in JSON:
203      * {
204      *    "name":"route-1",
205      *    "prefix":"10.10.1.0/24",
206      *    "nextHop":"1.1.1.1"
207      * }
208      *
209      * </pre>
210      */
211     @Path("/{containerName}/route/{route}")
212     @GET
213     @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
214     @TypeHint(StaticRoute.class)
215     @StatusCodes( {
216             @ResponseCode(code = 200, condition = "Operation successful"),
217             @ResponseCode(code = 404, condition = "The Container Name or Static Route Configuration name passed was not found") })
218     public StaticRoute getStaticRoute(
219             @PathParam("containerName") String containerName,
220             @PathParam("route") String route) {
221
222         if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
223                 Privilege.WRITE, this)){
224             throw new
225                 UnauthorizedException("User is not authorized to perform this operation on container "
226                             + containerName);
227         }
228         List<StaticRoute> routes = this.getStaticRoutesInternal(containerName);
229         for (StaticRoute r : routes) {
230             if (r.getName().equalsIgnoreCase(route)) {
231                 return r;
232             }
233         }
234
235         throw new ResourceNotFoundException(RestMessages.NOSTATICROUTE
236                 .toString());
237     }
238
239     /**
240      *
241      * Add a new Static Route. If a route by the given name already exists, this
242      * method will return a non-successful status response.
243      *
244      * @param containerName Name of the Container. The Container name for the base controller is "default".
245      * @param route Name of the Static Route configuration
246      * @return Response as dictated by the HTTP Response code
247      *
248      * <pre>
249      * Example:
250      *
251      * Request URL:
252      * http://localhost:8080/controller/nb/v2/staticroute/default/route/route-1
253      *
254      * Request body in XML:
255      * &lt;staticRoute&gt;
256      *   &lt;name&gt;route-1&lt;/name&gt;
257      *   &lt;prefix>10.10.1.0/24&lt;/prefix&gt;
258      *   &lt;nextHop&gt;1.1.1.1&lt;/nextHop&gt;
259      *   &lt;/staticRoute&gt;
260      * Request body in JSON:
261      * {
262      *    "name":"route-1",
263      *    "prefix":"10.10.1.0/24",
264      *    "nextHop":"1.1.1.1"
265      * }
266      * </pre>
267      */
268     @Path("/{containerName}/route/{route}")
269     @PUT
270     @Consumes( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
271     @StatusCodes( {
272             @ResponseCode(code = 201, condition = "Created Static Route successfully"),
273             @ResponseCode(code = 404, condition = "The Container Name passed is not found"),
274             @ResponseCode(code = 406, condition = "Cannot operate on Default Container when other Containers are active"),
275             @ResponseCode(code = 409, condition = "Failed to create Static Route entry due to Conflicting Name or Prefix."), })
276     public Response addStaticRoute(
277             @Context UriInfo uriInfo,
278             @PathParam(value = "containerName") String containerName,
279             @PathParam(value = "route") String route,
280             @TypeHint(StaticRoute.class) StaticRoute staticRouteData) {
281
282
283         if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
284                 Privilege.WRITE, this)){
285             throw new
286                 UnauthorizedException("User is not authorized to perform this operation on container "
287                             + containerName);
288         }
289         handleDefaultDisabled(containerName);
290
291         IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
292                 .getInstance(IForwardingStaticRouting.class, containerName,
293                         this);
294
295         if (staticRouting == null) {
296             throw new ResourceNotFoundException(RestMessages.NOCONTAINER
297                     .toString());
298         }
299
300         StaticRoute sRoute = staticRouteData;
301         StaticRouteConfig cfgObject = new StaticRouteConfig(sRoute.getName(),
302                 sRoute.getPrefix(), sRoute.getNextHop());
303         Status response = staticRouting.addStaticRoute(cfgObject);
304         if (response.isSuccess()) {
305             NorthboundUtils.auditlog("Static Route", username, "added", route, containerName);
306             return Response.created(uriInfo.getRequestUri()).build();
307         }
308         throw new ResourceConflictException(response.getDescription());
309     }
310
311     /**
312      *
313      * Delete a Static Route
314      *
315      * @param containerName Name of the Container. The Container name for the base controller is "default".
316      * @param route Name of the Static Route configuration to be removed
317      *
318      * @return Response as dictated by the HTTP Response code
319      *
320      * <pre>
321      * Example:
322      *
323      * Request URL:
324      * DELETE http://localhost:8080/controller/nb/v2/staticroute/default/route/route-1
325      *
326      * </pre>
327      */
328     @Path("/{containerName}/route/{route}")
329     @DELETE
330     @StatusCodes( {
331             @ResponseCode(code = 204, condition = "Static route removed successfully"),
332             @ResponseCode(code = 404, condition = "Container Name or Configuration Name not found"),
333             @ResponseCode(code = 406, condition = "Cannot operate on Default Container when other Containers are active") })
334     public Response removeStaticRoute(
335             @PathParam(value = "containerName") String containerName,
336             @PathParam(value = "route") String route) {
337
338         if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
339                 Privilege.WRITE, this)){
340             throw new
341                 UnauthorizedException("User is not authorized to perform this operation on container "
342                             + containerName);
343         }
344         handleDefaultDisabled(containerName);
345
346         IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
347                 .getInstance(IForwardingStaticRouting.class, containerName,
348                         this);
349
350         if (staticRouting == null) {
351             throw new ResourceNotFoundException(RestMessages.NOCONTAINER
352                     .toString());
353         }
354
355         Status status = staticRouting.removeStaticRoute(route);
356         if (status.isSuccess()) {
357             NorthboundUtils.auditlog("Static Route", username, "removed", route, containerName);
358             return Response.noContent().build();
359         }
360         return NorthboundUtils.getResponse(status);
361     }
362
363     private void handleDefaultDisabled(String containerName) {
364         IContainerManager containerManager = (IContainerManager) ServiceHelper
365                 .getGlobalInstance(IContainerManager.class, this);
366         if (containerManager == null) {
367             throw new InternalServerErrorException(RestMessages.INTERNALERROR
368                     .toString());
369         }
370         if (containerName.equals(GlobalConstants.DEFAULT.toString())
371                 && containerManager.hasNonDefaultContainer()) {
372             throw new NotAcceptableException(RestMessages.DEFAULTDISABLED
373                     .toString());
374         }
375     }
376 }