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.POST;
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;
27 import javax.xml.bind.JAXBElement;
29 import org.codehaus.enunciate.jaxrs.ResponseCode;
30 import org.codehaus.enunciate.jaxrs.StatusCodes;
31 import org.codehaus.enunciate.jaxrs.TypeHint;
32 import org.opendaylight.controller.containermanager.IContainerManager;
33 import org.opendaylight.controller.forwarding.staticrouting.IForwardingStaticRouting;
34 import org.opendaylight.controller.forwarding.staticrouting.StaticRouteConfig;
35 import org.opendaylight.controller.northbound.commons.RestMessages;
36 import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
37 import org.opendaylight.controller.northbound.commons.exception.NotAcceptableException;
38 import org.opendaylight.controller.northbound.commons.exception.ResourceConflictException;
39 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
40 import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
41 import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
42 import org.opendaylight.controller.sal.authorization.Privilege;
43 import org.opendaylight.controller.sal.utils.GlobalConstants;
44 import org.opendaylight.controller.sal.utils.ServiceHelper;
45 import org.opendaylight.controller.sal.utils.Status;
48 * <p>Static Routing Northbound API allows for the management of the static
51 * An example request/response for retrieving the static routes may look like this: </br>
53 * GET http://localhost:8080/controller/nb/v2/staticroute/default HTTP/1.1
54 * Accept: application/json
57 * Content-Type: application/json
59 * {"staticRoute":{"name":"route-1","prefix":"10.10.1.0/24","nextHop":"1.1.1.1"}}
64 * Authentication scheme : <b>HTTP Basic</b><br>
65 * Authentication realm : <b>opendaylight</b><br>
66 * Transport : <b>HTTP and HTTPS</b><br>
70 public class StaticRoutingNorthbound {
72 private String username;
75 public void setSecurityContext(SecurityContext context) {
76 if (context != null && context.getUserPrincipal() != null) username = context.getUserPrincipal().getName();
78 protected String getUserName() {
84 private List<StaticRoute> getStaticRoutesInternal(String containerName) {
86 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
87 .getInstance(IForwardingStaticRouting.class, containerName,
90 if (staticRouting == null) {
91 throw new ResourceNotFoundException(RestMessages.NOCONTAINER
95 List<StaticRoute> routes = new ArrayList<StaticRoute>();
97 for (StaticRouteConfig conf : staticRouting.getStaticRouteConfigs()
99 StaticRoute route = new StaticRoute(conf.getName(), conf
100 .getStaticRoute(), conf.getNextHop());
107 * Get a list of static routes present on the given container.
109 * @param containerName Name of the Container. The Container name for the base controller is "default".
110 * @return List of configured static routes on the given container
116 * GET http://localhost:8080/controller/nb/v2/staticroute/default
120 * <staticRoute>
121 * <name>route-1</name>
122 * <prefix>10.10.1.0/24</prefix>
123 * <nextHop>1.1.1.1</nextHop>
124 * </staticRoute>
128 * {"staticRoute":{"name":"route-1","prefix":"10.10.1.0/24","nextHop":"1.1.1.1"}}
132 @Path("/{containerName}")
134 @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
135 @TypeHint(StaticRoutes.class)
137 @ResponseCode(code = 200, condition = "Operation successful"),
138 @ResponseCode(code = 404, condition = "The containerName passed was not found") })
139 public StaticRoutes getStaticRoutes(
140 @PathParam("containerName") String containerName) {
142 if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
143 Privilege.WRITE, this)){
145 UnauthorizedException("User is not authorized to perform this operation on container "
148 return new StaticRoutes(getStaticRoutesInternal(containerName));
152 * Returns the static route for the provided configuration name on a given container
154 * @param containerName Name of the Container. The Container name for the base controller is "default".
155 * @param route Name of the Static Route configuration
156 * @return Static route configured with the supplied Name.
162 * GET http://localhost:8080/controller/nb/v2/staticroute/default/route/route-1
166 * <staticRoute>
167 * <name>route-1</name>
168 * <prefix>10.10.1.0/24</prefix>
169 * <nextHop>1.1.1.1</nextHop>
170 * </staticRoute>
173 * {"name":"route-1","prefix":"10.10.1.0/24","nextHop":"1.1.1.1"}
177 @Path("/{containerName}/route/{route}")
179 @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
180 @TypeHint(StaticRoute.class)
182 @ResponseCode(code = 200, condition = "Operation successful"),
183 @ResponseCode(code = 404, condition = "The Container Name or Static Route Configuration name passed was not found") })
184 public StaticRoute getStaticRoute(
185 @PathParam("containerName") String containerName,
186 @PathParam("route") String route) {
188 if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
189 Privilege.WRITE, this)){
191 UnauthorizedException("User is not authorized to perform this operation on container "
194 List<StaticRoute> routes = this.getStaticRoutesInternal(containerName);
195 for (StaticRoute r : routes) {
196 if (r.getName().equalsIgnoreCase(route)) {
201 throw new ResourceNotFoundException(RestMessages.NOSTATICROUTE
207 * Add a new Static Route
209 * @param containerName Name of the Container. The Container name for the base controller is "default".
210 * @param route Name of the Static Route configuration
211 * @return Response as dictated by the HTTP Response code
217 * POST http://localhost:8080/controller/nb/v2/staticroute/default/route/route-1
219 * Request payload in JSON:
220 * {"name":"route-1","prefix":"10.10.1.0/24","nextHop":"1.1.1.1"}
224 @Path("/{containerName}/route/{route}")
226 @Consumes( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
228 @ResponseCode(code = 201, condition = "Created Static Route successfully"),
229 @ResponseCode(code = 404, condition = "The Container Name passed is not found"),
230 @ResponseCode(code = 406, condition = "Cannot operate on Default Container when other Containers are active"),
231 @ResponseCode(code = 409, condition = "Failed to create Static Route entry due to Conflicting Name or Prefix."), })
232 public Response addStaticRoute(
233 @Context UriInfo uriInfo,
234 @PathParam(value = "containerName") String containerName,
235 @PathParam(value = "route") String route,
236 @TypeHint(StaticRoute.class) StaticRoute staticRouteData) {
239 if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
240 Privilege.WRITE, this)){
242 UnauthorizedException("User is not authorized to perform this operation on container "
245 handleDefaultDisabled(containerName);
247 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
248 .getInstance(IForwardingStaticRouting.class, containerName,
251 if (staticRouting == null) {
252 throw new ResourceNotFoundException(RestMessages.NOCONTAINER
256 StaticRoute sRoute = staticRouteData;
257 StaticRouteConfig cfgObject = new StaticRouteConfig(sRoute.getName(),
258 sRoute.getPrefix(), sRoute.getNextHop());
259 Status response = staticRouting.addStaticRoute(cfgObject);
260 if (response.isSuccess()) {
261 NorthboundUtils.auditlog("Static Route", username, "added", route, containerName);
262 return Response.created(uriInfo.getRequestUri()).build();
264 throw new ResourceConflictException(response.getDescription());
269 * Delete a Static Route
271 * @param containerName Name of the Container. The Container name for the base controller is "default".
272 * @param route Name of the Static Route configuration to be removed
274 * @return Response as dictated by the HTTP Response code
280 * DELETE http://localhost:8080/controller/nb/v2/staticroute/default/route/route-1
284 @Path("/{containerName}/route/{route}")
287 @ResponseCode(code = 200, condition = "Operation successful"),
288 @ResponseCode(code = 404, condition = "Container Name or Configuration Name not found"),
289 @ResponseCode(code = 406, condition = "Cannot operate on Default Container when other Containers are active") })
290 public Response removeStaticRoute(
291 @PathParam(value = "containerName") String containerName,
292 @PathParam(value = "route") String route) {
294 if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
295 Privilege.WRITE, this)){
297 UnauthorizedException("User is not authorized to perform this operation on container "
300 handleDefaultDisabled(containerName);
302 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
303 .getInstance(IForwardingStaticRouting.class, containerName,
306 if (staticRouting == null) {
307 throw new ResourceNotFoundException(RestMessages.NOCONTAINER
311 Status status = staticRouting.removeStaticRoute(route);
312 if (status.isSuccess()) {
313 NorthboundUtils.auditlog("Static Route", username, "removed", route, containerName);
314 return Response.ok().build();
316 throw new ResourceNotFoundException(status.getDescription());
319 private void handleDefaultDisabled(String containerName) {
320 IContainerManager containerManager = (IContainerManager) ServiceHelper
321 .getGlobalInstance(IContainerManager.class, this);
322 if (containerManager == null) {
323 throw new InternalServerErrorException(RestMessages.INTERNALERROR
326 if (containerName.equals(GlobalConstants.DEFAULT.toString())
327 && containerManager.hasNonDefaultContainer()) {
328 throw new NotAcceptableException(RestMessages.DEFAULTDISABLED