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.PUT;
20 import javax.ws.rs.Path;
21 import javax.ws.rs.PathParam;
22 import javax.ws.rs.Produces;
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.xml.bind.JAXBElement;
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.utils.NorthboundUtils;
43 import org.opendaylight.controller.sal.authorization.Privilege;
44 import org.opendaylight.controller.sal.utils.GlobalConstants;
45 import org.opendaylight.controller.sal.utils.ServiceHelper;
46 import org.opendaylight.controller.sal.utils.Status;
49 * <p>Static Routing Northbound API allows for the management of the static
52 * An example request/response for retrieving the static routes may look like this: </br>
54 * GET http://localhost:8080/controller/nb/v2/staticroute/default HTTP/1.1
55 * Accept: application/json
58 * Content-Type: application/json
60 * {"staticRoute":{"name":"route-1","prefix":"10.10.1.0/24","nextHop":"1.1.1.1"}}
65 * Authentication scheme : <b>HTTP Basic</b><br>
66 * Authentication realm : <b>opendaylight</b><br>
67 * Transport : <b>HTTP and HTTPS</b><br>
71 public class StaticRoutingNorthbound {
73 private String username;
76 public void setSecurityContext(SecurityContext context) {
77 if (context != null && context.getUserPrincipal() != null) username = context.getUserPrincipal().getName();
79 protected String getUserName() {
85 private List<StaticRoute> getStaticRoutesInternal(String containerName) {
87 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
88 .getInstance(IForwardingStaticRouting.class, containerName,
91 if (staticRouting == null) {
92 throw new ResourceNotFoundException(RestMessages.NOCONTAINER
96 List<StaticRoute> routes = new ArrayList<StaticRoute>();
98 for (StaticRouteConfig conf : staticRouting.getStaticRouteConfigs()
100 StaticRoute route = new StaticRoute(conf.getName(), conf
101 .getStaticRoute(), conf.getNextHop());
108 * Get a list of static routes present on the given container.
110 * @param containerName Name of the Container. The Container name for the base controller is "default".
111 * @return List of configured static routes on the given container
117 * GET http://localhost:8080/controller/nb/v2/staticroute/default/routes
121 * <staticRoute>
122 * <name>route-1</name>
123 * <prefix>10.10.1.0/24</prefix>
124 * <nextHop>1.1.1.1</nextHop>
125 * </staticRoute>
129 * {"staticRoute":{"name":"route-1","prefix":"10.10.1.0/24","nextHop":"1.1.1.1"}}
133 @Path("/{containerName}/routes")
135 @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
136 @TypeHint(StaticRoutes.class)
138 @ResponseCode(code = 200, condition = "Operation successful"),
139 @ResponseCode(code = 404, condition = "The containerName passed was not found") })
140 public StaticRoutes getStaticRoutes(
141 @PathParam("containerName") String containerName) {
143 if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
144 Privilege.WRITE, this)){
146 UnauthorizedException("User is not authorized to perform this operation on container "
149 return new StaticRoutes(getStaticRoutesInternal(containerName));
153 * Returns the static route for the provided configuration name on a given container
155 * @param containerName Name of the Container. The Container name for the base controller is "default".
156 * @param route Name of the Static Route configuration
157 * @return Static route configured with the supplied Name.
163 * GET http://localhost:8080/controller/nb/v2/staticroute/default/route/route-1
167 * <staticRoute>
168 * <name>route-1</name>
169 * <prefix>10.10.1.0/24</prefix>
170 * <nextHop>1.1.1.1</nextHop>
171 * </staticRoute>
174 * {"name":"route-1","prefix":"10.10.1.0/24","nextHop":"1.1.1.1"}
178 @Path("/{containerName}/route/{route}")
180 @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
181 @TypeHint(StaticRoute.class)
183 @ResponseCode(code = 200, condition = "Operation successful"),
184 @ResponseCode(code = 404, condition = "The Container Name or Static Route Configuration name passed was not found") })
185 public StaticRoute getStaticRoute(
186 @PathParam("containerName") String containerName,
187 @PathParam("route") String route) {
189 if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
190 Privilege.WRITE, this)){
192 UnauthorizedException("User is not authorized to perform this operation on container "
195 List<StaticRoute> routes = this.getStaticRoutesInternal(containerName);
196 for (StaticRoute r : routes) {
197 if (r.getName().equalsIgnoreCase(route)) {
202 throw new ResourceNotFoundException(RestMessages.NOSTATICROUTE
208 * Add a new Static Route. If a route by the given name already exists, this
209 * method will return a non-successful status response.
211 * @param containerName Name of the Container. The Container name for the base controller is "default".
212 * @param route Name of the Static Route configuration
213 * @return Response as dictated by the HTTP Response code
219 * PUT http://localhost:8080/controller/nb/v2/staticroute/default/route/route-1
221 * Request payload in JSON:
222 * {"name":"route-1","prefix":"10.10.1.0/24","nextHop":"1.1.1.1"}
226 @Path("/{containerName}/route/{route}")
228 @Consumes( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
230 @ResponseCode(code = 201, condition = "Created Static Route successfully"),
231 @ResponseCode(code = 404, condition = "The Container Name passed is not found"),
232 @ResponseCode(code = 406, condition = "Cannot operate on Default Container when other Containers are active"),
233 @ResponseCode(code = 409, condition = "Failed to create Static Route entry due to Conflicting Name or Prefix."), })
234 public Response addStaticRoute(
235 @Context UriInfo uriInfo,
236 @PathParam(value = "containerName") String containerName,
237 @PathParam(value = "route") String route,
238 @TypeHint(StaticRoute.class) StaticRoute staticRouteData) {
241 if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
242 Privilege.WRITE, this)){
244 UnauthorizedException("User is not authorized to perform this operation on container "
247 handleDefaultDisabled(containerName);
249 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
250 .getInstance(IForwardingStaticRouting.class, containerName,
253 if (staticRouting == null) {
254 throw new ResourceNotFoundException(RestMessages.NOCONTAINER
258 StaticRoute sRoute = staticRouteData;
259 StaticRouteConfig cfgObject = new StaticRouteConfig(sRoute.getName(),
260 sRoute.getPrefix(), sRoute.getNextHop());
261 Status response = staticRouting.addStaticRoute(cfgObject);
262 if (response.isSuccess()) {
263 NorthboundUtils.auditlog("Static Route", username, "added", route, containerName);
264 return Response.created(uriInfo.getRequestUri()).build();
266 throw new ResourceConflictException(response.getDescription());
271 * Delete a Static Route
273 * @param containerName Name of the Container. The Container name for the base controller is "default".
274 * @param route Name of the Static Route configuration to be removed
276 * @return Response as dictated by the HTTP Response code
282 * DELETE http://localhost:8080/controller/nb/v2/staticroute/default/route/route-1
286 @Path("/{containerName}/route/{route}")
289 @ResponseCode(code = 204, condition = "Static route removed successfully"),
290 @ResponseCode(code = 404, condition = "Container Name or Configuration Name not found"),
291 @ResponseCode(code = 406, condition = "Cannot operate on Default Container when other Containers are active") })
292 public Response removeStaticRoute(
293 @PathParam(value = "containerName") String containerName,
294 @PathParam(value = "route") String route) {
296 if(!NorthboundUtils.isAuthorized(getUserName(), containerName,
297 Privilege.WRITE, this)){
299 UnauthorizedException("User is not authorized to perform this operation on container "
302 handleDefaultDisabled(containerName);
304 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
305 .getInstance(IForwardingStaticRouting.class, containerName,
308 if (staticRouting == null) {
309 throw new ResourceNotFoundException(RestMessages.NOCONTAINER
313 Status status = staticRouting.removeStaticRoute(route);
314 if (status.isSuccess()) {
315 NorthboundUtils.auditlog("Static Route", username, "removed", route, containerName);
316 return Response.noContent().build();
318 return NorthboundUtils.getResponse(status);
321 private void handleDefaultDisabled(String containerName) {
322 IContainerManager containerManager = (IContainerManager) ServiceHelper
323 .getGlobalInstance(IContainerManager.class, this);
324 if (containerManager == null) {
325 throw new InternalServerErrorException(RestMessages.INTERNALERROR
328 if (containerName.equals(GlobalConstants.DEFAULT.toString())
329 && containerManager.hasNonDefaultContainer()) {
330 throw new NotAcceptableException(RestMessages.DEFAULTDISABLED