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) username = context.getUserPrincipal().getName();
93 protected String getUserName() {
99 private List<StaticRoute> getStaticRoutesInternal(String containerName) {
101 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
102 .getInstance(IForwardingStaticRouting.class, containerName,
105 if (staticRouting == null) {
106 throw new ResourceNotFoundException(RestMessages.NOCONTAINER
110 List<StaticRoute> routes = new ArrayList<StaticRoute>();
112 for (StaticRouteConfig conf : staticRouting.getStaticRouteConfigs()
114 StaticRoute route = new StaticRoute(conf.getName(), conf
115 .getStaticRoute(), conf.getNextHop());
122 * Get a list of static routes present on the given container.
124 * @param containerName Name of the Container. The Container name for the base controller is "default".
125 * @return List of configured static routes on the given container
131 * http://localhost:8080/controller/nb/v2/staticroute/default/routes
133 * Response body in XML:
135 * <staticRoute>
136 * <name>route-1</name>
137 * <prefix>10.10.1.0/24</prefix>
138 * <nextHop>1.1.1.1</nextHop>
139 * </staticRoute>
142 * Response body in JSON:
147 * "prefix": "10.10.1.0/24",
148 * "nextHop": "1.1.1.1"
154 @Path("/{containerName}/routes")
156 @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
157 @TypeHint(StaticRoutes.class)
159 @ResponseCode(code = 200, condition = "Operation successful"),
160 @ResponseCode(code = 404, condition = "The containerName passed was not found") })
161 public StaticRoutes getStaticRoutes(
162 @PathParam("containerName") String containerName,
163 @QueryParam("_q") String queryString) {
165 if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
166 Privilege.WRITE, this)){
168 UnauthorizedException("User is not authorized to perform this operation on container "
171 StaticRoutes result = new StaticRoutes(getStaticRoutesInternal(containerName));
172 if (queryString != null) {
173 queryContext.createQuery(queryString, StaticRoutes.class)
174 .filter(result, StaticRoute.class);
180 * Returns the static route for the provided configuration name on a given container
182 * @param containerName Name of the Container. The Container name for the base controller is "default".
183 * @param route Name of the Static Route configuration
184 * @return Static route configured with the supplied Name.
190 * http://localhost:8080/controller/nb/v2/staticroute/default/route/route-1
192 * Response body in XML:
194 * <staticRoute>
195 * <name>route-1</name>
196 * <prefix>10.10.1.0/24</prefix>
197 * <nextHop>1.1.1.1</nextHop>
198 * </staticRoute>
200 * Response body in JSON:
203 * "prefix":"10.10.1.0/24",
204 * "nextHop":"1.1.1.1"
209 @Path("/{containerName}/route/{route}")
211 @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
212 @TypeHint(StaticRoute.class)
214 @ResponseCode(code = 200, condition = "Operation successful"),
215 @ResponseCode(code = 404, condition = "The Container Name or Static Route Configuration name passed was not found") })
216 public StaticRoute getStaticRoute(
217 @PathParam("containerName") String containerName,
218 @PathParam("route") String route) {
220 if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
221 Privilege.WRITE, this)){
223 UnauthorizedException("User is not authorized to perform this operation on container "
226 List<StaticRoute> routes = this.getStaticRoutesInternal(containerName);
227 for (StaticRoute r : routes) {
228 if (r.getName().equalsIgnoreCase(route)) {
233 throw new ResourceNotFoundException(RestMessages.NOSTATICROUTE
239 * Add a new Static Route. If a route by the given name already exists, this
240 * method will return a non-successful status response.
242 * @param containerName Name of the Container. The Container name for the base controller is "default".
243 * @param route Name of the Static Route configuration
244 * @return Response as dictated by the HTTP Response code
250 * http://localhost:8080/controller/nb/v2/staticroute/default/route/route-1
252 * Request body in XML:
253 * <staticRoute>
254 * <name>route-1</name>
255 * <prefix>10.10.1.0/24</prefix>
256 * <nextHop>1.1.1.1</nextHop>
257 * </staticRoute>
258 * Request body in JSON:
261 * "prefix":"10.10.1.0/24",
262 * "nextHop":"1.1.1.1"
266 @Path("/{containerName}/route/{route}")
268 @Consumes( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
270 @ResponseCode(code = 201, condition = "Created Static Route successfully"),
271 @ResponseCode(code = 404, condition = "The Container Name passed is not found"),
272 @ResponseCode(code = 406, condition = "Cannot operate on Default Container when other Containers are active"),
273 @ResponseCode(code = 409, condition = "Failed to create Static Route entry due to Conflicting Name or Prefix."), })
274 public Response addStaticRoute(
275 @Context UriInfo uriInfo,
276 @PathParam(value = "containerName") String containerName,
277 @PathParam(value = "route") String route,
278 @TypeHint(StaticRoute.class) StaticRoute staticRouteData) {
281 if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
282 Privilege.WRITE, this)){
284 UnauthorizedException("User is not authorized to perform this operation on container "
287 handleDefaultDisabled(containerName);
289 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
290 .getInstance(IForwardingStaticRouting.class, containerName,
293 if (staticRouting == null) {
294 throw new ResourceNotFoundException(RestMessages.NOCONTAINER
298 StaticRoute sRoute = staticRouteData;
299 StaticRouteConfig cfgObject = new StaticRouteConfig(sRoute.getName(),
300 sRoute.getPrefix(), sRoute.getNextHop());
301 Status response = staticRouting.addStaticRoute(cfgObject);
302 if (response.isSuccess()) {
303 NorthboundUtils.auditlog("Static Route", username, "added", route, containerName);
304 return Response.created(uriInfo.getRequestUri()).build();
306 throw new ResourceConflictException(response.getDescription());
311 * Delete a Static Route
313 * @param containerName Name of the Container. The Container name for the base controller is "default".
314 * @param route Name of the Static Route configuration to be removed
316 * @return Response as dictated by the HTTP Response code
322 * DELETE http://localhost:8080/controller/nb/v2/staticroute/default/route/route-1
326 @Path("/{containerName}/route/{route}")
329 @ResponseCode(code = 204, condition = "Static route removed successfully"),
330 @ResponseCode(code = 404, condition = "Container Name or Configuration Name not found"),
331 @ResponseCode(code = 406, condition = "Cannot operate on Default Container when other Containers are active") })
332 public Response removeStaticRoute(
333 @PathParam(value = "containerName") String containerName,
334 @PathParam(value = "route") String route) {
336 if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
337 Privilege.WRITE, this)){
339 UnauthorizedException("User is not authorized to perform this operation on container "
342 handleDefaultDisabled(containerName);
344 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
345 .getInstance(IForwardingStaticRouting.class, containerName,
348 if (staticRouting == null) {
349 throw new ResourceNotFoundException(RestMessages.NOCONTAINER
353 Status status = staticRouting.removeStaticRoute(route);
354 if (status.isSuccess()) {
355 NorthboundUtils.auditlog("Static Route", username, "removed", route, containerName);
356 return Response.noContent().build();
358 return NorthboundUtils.getResponse(status);
361 private void handleDefaultDisabled(String containerName) {
362 IContainerManager containerManager = (IContainerManager) ServiceHelper
363 .getGlobalInstance(IContainerManager.class, this);
364 if (containerManager == null) {
365 throw new InternalServerErrorException(RestMessages.INTERNALERROR
368 if (containerName.equals(GlobalConstants.DEFAULT.toString())
369 && containerManager.hasNonDefaultContainer()) {
370 throw new NotAcceptableException(RestMessages.DEFAULTDISABLED