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.core.Context;
23 import javax.ws.rs.core.MediaType;
24 import javax.ws.rs.core.Response;
25 import javax.ws.rs.core.SecurityContext;
26 import javax.ws.rs.core.UriInfo;
28 import org.codehaus.enunciate.jaxrs.ResponseCode;
29 import org.codehaus.enunciate.jaxrs.StatusCodes;
30 import org.codehaus.enunciate.jaxrs.TypeHint;
31 import org.opendaylight.controller.containermanager.IContainerManager;
32 import org.opendaylight.controller.forwarding.staticrouting.IForwardingStaticRouting;
33 import org.opendaylight.controller.forwarding.staticrouting.StaticRouteConfig;
34 import org.opendaylight.controller.northbound.commons.RestMessages;
35 import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
36 import org.opendaylight.controller.northbound.commons.exception.NotAcceptableException;
37 import org.opendaylight.controller.northbound.commons.exception.ResourceConflictException;
38 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
39 import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
40 import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
41 import org.opendaylight.controller.sal.authorization.Privilege;
42 import org.opendaylight.controller.sal.utils.GlobalConstants;
43 import org.opendaylight.controller.sal.utils.ServiceHelper;
44 import org.opendaylight.controller.sal.utils.Status;
47 * <p>Static Routing Northbound API allows for the management of the static
50 * An example request/response for retrieving the static routes may look like this: </br>
52 * GET http://localhost:8080/controller/nb/v2/staticroute/default HTTP/1.1
53 * Accept: application/json
56 * Content-Type: application/json
60 * "prefix":"10.10.1.0/24",
68 * Authentication scheme : <b>HTTP Basic</b><br>
69 * Authentication realm : <b>opendaylight</b><br>
70 * Transport : <b>HTTP and HTTPS</b><br>
74 public class StaticRoutingNorthbound {
76 private String username;
79 public void setSecurityContext(SecurityContext context) {
80 if (context != null && context.getUserPrincipal() != null) username = context.getUserPrincipal().getName();
82 protected String getUserName() {
88 private List<StaticRoute> getStaticRoutesInternal(String containerName) {
90 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
91 .getInstance(IForwardingStaticRouting.class, containerName,
94 if (staticRouting == null) {
95 throw new ResourceNotFoundException(RestMessages.NOCONTAINER
99 List<StaticRoute> routes = new ArrayList<StaticRoute>();
101 for (StaticRouteConfig conf : staticRouting.getStaticRouteConfigs()
103 StaticRoute route = new StaticRoute(conf.getName(), conf
104 .getStaticRoute(), conf.getNextHop());
111 * Get a list of static routes present on the given container.
113 * @param containerName Name of the Container. The Container name for the base controller is "default".
114 * @return List of configured static routes on the given container
120 * http://localhost:8080/controller/nb/v2/staticroute/default/routes
122 * Response body in XML:
124 * <staticRoute>
125 * <name>route-1</name>
126 * <prefix>10.10.1.0/24</prefix>
127 * <nextHop>1.1.1.1</nextHop>
128 * </staticRoute>
131 * Response body in JSON:
136 * "prefix": "10.10.1.0/24",
137 * "nextHop": "1.1.1.1"
143 @Path("/{containerName}/routes")
145 @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
146 @TypeHint(StaticRoutes.class)
148 @ResponseCode(code = 200, condition = "Operation successful"),
149 @ResponseCode(code = 404, condition = "The containerName passed was not found") })
150 public StaticRoutes getStaticRoutes(
151 @PathParam("containerName") String containerName) {
153 if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
154 Privilege.WRITE, this)){
156 UnauthorizedException("User is not authorized to perform this operation on container "
159 return new StaticRoutes(getStaticRoutesInternal(containerName));
163 * Returns the static route for the provided configuration name on a given container
165 * @param containerName Name of the Container. The Container name for the base controller is "default".
166 * @param route Name of the Static Route configuration
167 * @return Static route configured with the supplied Name.
173 * http://localhost:8080/controller/nb/v2/staticroute/default/route/route-1
175 * Response body in XML:
177 * <staticRoute>
178 * <name>route-1</name>
179 * <prefix>10.10.1.0/24</prefix>
180 * <nextHop>1.1.1.1</nextHop>
181 * </staticRoute>
183 * Response body in JSON:
186 * "prefix":"10.10.1.0/24",
187 * "nextHop":"1.1.1.1"
192 @Path("/{containerName}/route/{route}")
194 @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
195 @TypeHint(StaticRoute.class)
197 @ResponseCode(code = 200, condition = "Operation successful"),
198 @ResponseCode(code = 404, condition = "The Container Name or Static Route Configuration name passed was not found") })
199 public StaticRoute getStaticRoute(
200 @PathParam("containerName") String containerName,
201 @PathParam("route") String route) {
203 if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
204 Privilege.WRITE, this)){
206 UnauthorizedException("User is not authorized to perform this operation on container "
209 List<StaticRoute> routes = this.getStaticRoutesInternal(containerName);
210 for (StaticRoute r : routes) {
211 if (r.getName().equalsIgnoreCase(route)) {
216 throw new ResourceNotFoundException(RestMessages.NOSTATICROUTE
222 * Add a new Static Route. If a route by the given name already exists, this
223 * method will return a non-successful status response.
225 * @param containerName Name of the Container. The Container name for the base controller is "default".
226 * @param route Name of the Static Route configuration
227 * @return Response as dictated by the HTTP Response code
233 * http://localhost:8080/controller/nb/v2/staticroute/default/route/route-1
235 * Request body in XML:
236 * <staticRoute>
237 * <name>route-1</name>
238 * <prefix>10.10.1.0/24</prefix>
239 * <nextHop>1.1.1.1</nextHop>
240 * </staticRoute>
241 * Request body in JSON:
244 * "prefix":"10.10.1.0/24",
245 * "nextHop":"1.1.1.1"
249 @Path("/{containerName}/route/{route}")
251 @Consumes( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
253 @ResponseCode(code = 201, condition = "Created Static Route successfully"),
254 @ResponseCode(code = 404, condition = "The Container Name passed is not found"),
255 @ResponseCode(code = 406, condition = "Cannot operate on Default Container when other Containers are active"),
256 @ResponseCode(code = 409, condition = "Failed to create Static Route entry due to Conflicting Name or Prefix."), })
257 public Response addStaticRoute(
258 @Context UriInfo uriInfo,
259 @PathParam(value = "containerName") String containerName,
260 @PathParam(value = "route") String route,
261 @TypeHint(StaticRoute.class) StaticRoute staticRouteData) {
264 if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
265 Privilege.WRITE, this)){
267 UnauthorizedException("User is not authorized to perform this operation on container "
270 handleDefaultDisabled(containerName);
272 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
273 .getInstance(IForwardingStaticRouting.class, containerName,
276 if (staticRouting == null) {
277 throw new ResourceNotFoundException(RestMessages.NOCONTAINER
281 StaticRoute sRoute = staticRouteData;
282 StaticRouteConfig cfgObject = new StaticRouteConfig(sRoute.getName(),
283 sRoute.getPrefix(), sRoute.getNextHop());
284 Status response = staticRouting.addStaticRoute(cfgObject);
285 if (response.isSuccess()) {
286 NorthboundUtils.auditlog("Static Route", username, "added", route, containerName);
287 return Response.created(uriInfo.getRequestUri()).build();
289 throw new ResourceConflictException(response.getDescription());
294 * Delete a Static Route
296 * @param containerName Name of the Container. The Container name for the base controller is "default".
297 * @param route Name of the Static Route configuration to be removed
299 * @return Response as dictated by the HTTP Response code
305 * DELETE http://localhost:8080/controller/nb/v2/staticroute/default/route/route-1
309 @Path("/{containerName}/route/{route}")
312 @ResponseCode(code = 204, condition = "Static route removed successfully"),
313 @ResponseCode(code = 404, condition = "Container Name or Configuration Name not found"),
314 @ResponseCode(code = 406, condition = "Cannot operate on Default Container when other Containers are active") })
315 public Response removeStaticRoute(
316 @PathParam(value = "containerName") String containerName,
317 @PathParam(value = "route") String route) {
319 if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
320 Privilege.WRITE, this)){
322 UnauthorizedException("User is not authorized to perform this operation on container "
325 handleDefaultDisabled(containerName);
327 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
328 .getInstance(IForwardingStaticRouting.class, containerName,
331 if (staticRouting == null) {
332 throw new ResourceNotFoundException(RestMessages.NOCONTAINER
336 Status status = staticRouting.removeStaticRoute(route);
337 if (status.isSuccess()) {
338 NorthboundUtils.auditlog("Static Route", username, "removed", route, containerName);
339 return Response.noContent().build();
341 return NorthboundUtils.getResponse(status);
344 private void handleDefaultDisabled(String containerName) {
345 IContainerManager containerManager = (IContainerManager) ServiceHelper
346 .getGlobalInstance(IContainerManager.class, this);
347 if (containerManager == null) {
348 throw new InternalServerErrorException(RestMessages.INTERNALERROR
351 if (containerName.equals(GlobalConstants.DEFAULT.toString())
352 && containerManager.hasNonDefaultContainer()) {
353 throw new NotAcceptableException(RestMessages.DEFAULTDISABLED