2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.controllermanager.northbound;
11 import java.util.HashSet;
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;
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.northbound.commons.RestMessages;
34 import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
35 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
36 import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
37 import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
38 import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
39 import org.opendaylight.controller.sal.authorization.Privilege;
40 import org.opendaylight.controller.sal.core.Property;
41 import org.opendaylight.controller.sal.utils.GlobalConstants;
42 import org.opendaylight.controller.sal.utils.ServiceHelper;
43 import org.opendaylight.controller.sal.utils.Status;
44 import org.opendaylight.controller.switchmanager.ISwitchManager;
47 * The class provides Northbound REST APIs to manager the controller. Currently
48 * it supports getting controller property(ies), setting a property, and
54 public class ControllerManagerNorthbound {
56 private String username;
59 public void setSecurityContext(SecurityContext context) {
60 if (context != null && context.getUserPrincipal() != null) {
61 username = context.getUserPrincipal().getName();
65 protected String getUserName() {
69 private ISwitchManager getISwitchManagerService(String containerName) {
70 ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName,
73 if (switchManager == null) {
74 throw new ServiceUnavailableException("Switch Manager " + RestMessages.SERVICEUNAVAILABLE.toString());
81 * Retrieve a property or all properties for the controller in the network
83 * @param containerName
84 * Name of the Container (Eg. 'default')
86 * Name of the Property specified by
87 * {@link org.opendaylight.controller.sal.core.Property} and its
93 * http://localhost:8080/controller/nb/v2/controllermanager/default/properties/?propertyName=macAddress
95 * Response Body in XML:
96 * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
97 * <controllerProperties>
100 * <value>3e:04:ef:11:13:80</value>
103 * </controllerProperties>
105 * Response Body in JSON:
106 * { "controllerProperties":
109 * { "value": "3e:04:ef:11:13:80" }
115 @Path("/{containerName}/properties/")
117 @TypeHint(Property.class)
118 @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
119 @StatusCodes({ @ResponseCode(code = 200, condition = "Operation successful"),
120 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
121 @ResponseCode(code = 404, condition = "The containerName or property is not found"),
122 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
123 public ControllerProperties getControllerProperties(@PathParam("containerName") String containerName,
124 @QueryParam("propertyName") String propertyName) {
126 if (!isValidContainer(containerName)) {
127 throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
130 if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) {
131 throw new UnauthorizedException("User is not authorized to perform this operation on container "
135 ISwitchManager switchManager = getISwitchManagerService(containerName);
137 if (propertyName == null) {
138 Map<String, Property> propertyMap = switchManager.getControllerProperties();
139 Set<Property> properties = new HashSet<Property>(propertyMap.values());
140 return new ControllerProperties(properties);
143 Set<Property> properties = new HashSet<Property>();
144 Property property = switchManager.getControllerProperty(propertyName);
145 if (property == null) {
146 throw new ResourceNotFoundException("Unable to find property with name: " + propertyName);
148 properties.add(property);
150 return new ControllerProperties(properties);
155 * Add a controller property to the controller. This method overrides
156 * previously set property values if the property already exist.
158 * @param containerName
159 * Name of the Container (Eg. 'default')
160 * @param propertyName
161 * Name of the Property specified by
162 * {@link org.opendaylight.controller.sal.core.Property} and its
164 * @param propertyValue
165 * Value of the Property specified by
166 * {@link org.opendaylight.controller.sal.core.Property} and its
168 * @return Response as dictated by the HTTP Response Status code
173 * http://localhost:8080/controller/nb/v2/controllermanager/default/properties/description/defaultController
175 @Path("/{containerName}/properties/{propertyName}/{propertyValue}")
177 @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
178 @StatusCodes({ @ResponseCode(code = 201, condition = "Operation successful"),
179 @ResponseCode(code = 400, condition = "Invalid property parameters"),
180 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
181 @ResponseCode(code = 404, condition = "The containerName or property is not found"),
182 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
183 public Response setControllerProperty(@Context UriInfo uriInfo, @PathParam("containerName") String containerName,
184 @PathParam("propertyName") String propertyName, @PathParam("propertyValue") String propertyValue) {
186 if (!isValidContainer(containerName)) {
187 throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
190 if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) {
191 throw new UnauthorizedException("User is not authorized to perform this operation on container "
195 ISwitchManager switchManager = getISwitchManagerService(containerName);
197 Property prop = switchManager.createProperty(propertyName, propertyValue);
199 throw new BadRequestException("Property with name " + propertyName + " cannot be created.");
202 Status status = switchManager.setControllerProperty(prop);
204 if (status.isSuccess()) {
205 NorthboundUtils.auditlog("Controller Property", username, "updated", propertyName);
206 return Response.created(uriInfo.getRequestUri()).build();
208 return NorthboundUtils.getResponse(status);
212 * Delete a property of the controller
214 * @param containerName
215 * Name of the Container (Eg. 'default')
216 * @param propertyName
217 * Name of the Property specified by
218 * {@link org.opendaylight.controller.sal.core.Property} and its
220 * @return Response as dictated by the HTTP Response Status code
225 * http://localhost:8080/controller/nb/v2/controllermanager/default/properties/description
227 @Path("/{containerName}/properties/{propertyName}")
229 @StatusCodes({ @ResponseCode(code = 204, condition = "Property removed successfully"),
230 @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),
231 @ResponseCode(code = 404, condition = "The containerName is not found"),
232 @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") })
233 public Response removeControllerProperty(@PathParam("containerName") String containerName,
234 @PathParam("propertyName") String propertyName) {
236 if (!isValidContainer(containerName)) {
237 throw new ResourceNotFoundException("Container " + containerName + " does not exist.");
240 if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) {
241 throw new UnauthorizedException("User is not authorized to perform this operation on container "
245 ISwitchManager switchManager = getISwitchManagerService(containerName);
247 Status status = switchManager.removeControllerProperty(propertyName);
249 if (status.isSuccess()) {
250 NorthboundUtils.auditlog("Controller Property", username, "removed", propertyName);
252 return Response.noContent().build();
254 return NorthboundUtils.getResponse(status);
257 private boolean isValidContainer(String containerName) {
258 if (containerName.equals(GlobalConstants.DEFAULT.toString())) {
261 IContainerManager containerManager = (IContainerManager) ServiceHelper.getGlobalInstance(
262 IContainerManager.class, this);
263 if (containerManager == null) {
264 throw new ServiceUnavailableException("Container Manager " + RestMessages.SERVICEUNAVAILABLE.toString());
266 if (containerManager.getContainerNames().contains(containerName)) {