3 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
10 package org.opendaylight.controller.forwarding.staticrouting.northbound;
12 import java.util.ArrayList;
13 import java.util.List;
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;
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;
50 * <p>Static Routing Northbound API allows for the management of the static
53 * An example request/response for retrieving the static routes may look like this: </br>
55 * GET http://localhost:8080/controller/nb/v2/staticroute/default HTTP/1.1
56 * Accept: application/json
59 * Content-Type: application/json
63 * "prefix":"10.10.1.0/24",
71 * Authentication scheme : <b>HTTP Basic</b><br>
72 * Authentication realm : <b>opendaylight</b><br>
73 * Transport : <b>HTTP and HTTPS</b><br>
77 public class StaticRoutingNorthbound {
79 private String username;
80 private QueryContext queryContext;
83 public void setQueryContext(ContextResolver<QueryContext> queryCtxResolver) {
84 if (queryCtxResolver != null) {
85 queryContext = queryCtxResolver.getContext(QueryContext.class);
90 public void setSecurityContext(SecurityContext context) {
91 if (context != null && context.getUserPrincipal() != null) {
92 username = context.getUserPrincipal().getName();
95 protected String getUserName() {
101 private List<StaticRoute> getStaticRoutesInternal(String containerName) {
103 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
104 .getInstance(IForwardingStaticRouting.class, containerName,
107 if (staticRouting == null) {
108 throw new ResourceNotFoundException(RestMessages.NOCONTAINER
112 List<StaticRoute> routes = new ArrayList<StaticRoute>();
114 for (StaticRouteConfig conf : staticRouting.getStaticRouteConfigs()
116 StaticRoute route = new StaticRoute(conf.getName(), conf
117 .getStaticRoute(), conf.getNextHop());
124 * Get a list of static routes present on the given container.
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
133 * http://localhost:8080/controller/nb/v2/staticroute/default/routes
135 * Response body in XML:
137 * <staticRoute>
138 * <name>route-1</name>
139 * <prefix>10.10.1.0/24</prefix>
140 * <nextHop>1.1.1.1</nextHop>
141 * </staticRoute>
144 * Response body in JSON:
149 * "prefix": "10.10.1.0/24",
150 * "nextHop": "1.1.1.1"
156 @Path("/{containerName}/routes")
158 @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
159 @TypeHint(StaticRoutes.class)
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) {
167 if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
168 Privilege.WRITE, this)){
170 UnauthorizedException("User is not authorized to perform this operation on container "
173 StaticRoutes result = new StaticRoutes(getStaticRoutesInternal(containerName));
174 if (queryString != null) {
175 queryContext.createQuery(queryString, StaticRoutes.class)
176 .filter(result, StaticRoute.class);
182 * Returns the static route for the provided configuration name on a given container
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.
192 * http://localhost:8080/controller/nb/v2/staticroute/default/route/route-1
194 * Response body in XML:
196 * <staticRoute>
197 * <name>route-1</name>
198 * <prefix>10.10.1.0/24</prefix>
199 * <nextHop>1.1.1.1</nextHop>
200 * </staticRoute>
202 * Response body in JSON:
205 * "prefix":"10.10.1.0/24",
206 * "nextHop":"1.1.1.1"
211 @Path("/{containerName}/route/{route}")
213 @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
214 @TypeHint(StaticRoute.class)
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) {
222 if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
223 Privilege.WRITE, this)){
225 UnauthorizedException("User is not authorized to perform this operation on container "
228 List<StaticRoute> routes = this.getStaticRoutesInternal(containerName);
229 for (StaticRoute r : routes) {
230 if (r.getName().equalsIgnoreCase(route)) {
235 throw new ResourceNotFoundException(RestMessages.NOSTATICROUTE
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.
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
252 * http://localhost:8080/controller/nb/v2/staticroute/default/route/route-1
254 * Request body in XML:
255 * <staticRoute>
256 * <name>route-1</name>
257 * <prefix>10.10.1.0/24</prefix>
258 * <nextHop>1.1.1.1</nextHop>
259 * </staticRoute>
260 * Request body in JSON:
263 * "prefix":"10.10.1.0/24",
264 * "nextHop":"1.1.1.1"
268 @Path("/{containerName}/route/{route}")
270 @Consumes( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
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) {
283 if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
284 Privilege.WRITE, this)){
286 UnauthorizedException("User is not authorized to perform this operation on container "
289 handleDefaultDisabled(containerName);
291 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
292 .getInstance(IForwardingStaticRouting.class, containerName,
295 if (staticRouting == null) {
296 throw new ResourceNotFoundException(RestMessages.NOCONTAINER
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();
308 throw new ResourceConflictException(response.getDescription());
313 * Delete a Static Route
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
318 * @return Response as dictated by the HTTP Response code
324 * DELETE http://localhost:8080/controller/nb/v2/staticroute/default/route/route-1
328 @Path("/{containerName}/route/{route}")
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) {
338 if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
339 Privilege.WRITE, this)){
341 UnauthorizedException("User is not authorized to perform this operation on container "
344 handleDefaultDisabled(containerName);
346 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
347 .getInstance(IForwardingStaticRouting.class, containerName,
350 if (staticRouting == null) {
351 throw new ResourceNotFoundException(RestMessages.NOCONTAINER
355 Status status = staticRouting.removeStaticRoute(route);
356 if (status.isSuccess()) {
357 NorthboundUtils.auditlog("Static Route", username, "removed", route, containerName);
358 return Response.noContent().build();
360 return NorthboundUtils.getResponse(status);
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
370 if (containerName.equals(GlobalConstants.DEFAULT.toString())
371 && containerManager.hasNonDefaultContainer()) {
372 throw new NotAcceptableException(RestMessages.DEFAULTDISABLED