X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fadsal%2Fnorthbound%2Fcontrollermanager%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcontrollermanager%2Fnorthbound%2FControllerManagerNorthbound.java;fp=opendaylight%2Fadsal%2Fnorthbound%2Fcontrollermanager%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcontrollermanager%2Fnorthbound%2FControllerManagerNorthbound.java;h=aaf93d1f4bacb0c73ace34595121f6641ce33323;hb=42c32160bfd41de57189bb246fec5ffb48ed8e9e;hp=0000000000000000000000000000000000000000;hpb=edf5bfcee83c750853253ccfd991ba7000f5f65b;p=controller.git diff --git a/opendaylight/adsal/northbound/controllermanager/src/main/java/org/opendaylight/controller/controllermanager/northbound/ControllerManagerNorthbound.java b/opendaylight/adsal/northbound/controllermanager/src/main/java/org/opendaylight/controller/controllermanager/northbound/ControllerManagerNorthbound.java new file mode 100644 index 0000000000..aaf93d1f4b --- /dev/null +++ b/opendaylight/adsal/northbound/controllermanager/src/main/java/org/opendaylight/controller/controllermanager/northbound/ControllerManagerNorthbound.java @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.controller.controllermanager.northbound; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.SecurityContext; +import javax.ws.rs.core.UriInfo; +import javax.ws.rs.ext.ContextResolver; + +import org.codehaus.enunciate.jaxrs.ResponseCode; +import org.codehaus.enunciate.jaxrs.StatusCodes; +import org.codehaus.enunciate.jaxrs.TypeHint; +import org.opendaylight.controller.configuration.IConfigurationService; +import org.opendaylight.controller.containermanager.IContainerManager; +import org.opendaylight.controller.northbound.commons.RestMessages; +import org.opendaylight.controller.northbound.commons.exception.BadRequestException; +import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException; +import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException; +import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException; +import org.opendaylight.controller.northbound.commons.query.QueryContext; +import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils; +import org.opendaylight.controller.sal.authorization.Privilege; +import org.opendaylight.controller.sal.core.Property; +import org.opendaylight.controller.sal.utils.GlobalConstants; +import org.opendaylight.controller.sal.utils.ServiceHelper; +import org.opendaylight.controller.sal.utils.Status; +import org.opendaylight.controller.switchmanager.ISwitchManager; + +/** + * The class provides Northbound REST APIs to manager the controller. Currently + * it supports getting controller property(ies), setting a property, and + * removing a property + * + */ + +@Path("/") +public class ControllerManagerNorthbound { + + private String username; + private QueryContext queryContext; + + @Context + public void setQueryContext(ContextResolver queryCtxResolver) { + if (queryCtxResolver != null) { + queryContext = queryCtxResolver.getContext(QueryContext.class); + } + } + + @Context + public void setSecurityContext(SecurityContext context) { + if (context != null && context.getUserPrincipal() != null) { + username = context.getUserPrincipal().getName(); + } + } + + protected String getUserName() { + return username; + } + + private ISwitchManager getISwitchManagerService(String containerName) { + ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName, + this); + + if (switchManager == null) { + throw new ServiceUnavailableException("Switch Manager " + RestMessages.SERVICEUNAVAILABLE.toString()); + } + + return switchManager; + } + + /** + * Retrieve a property or all properties for the controller in the network + * + * @param containerName + * Name of the Container (Eg. 'default') + * @param propertyName + * Name of the Property specified by + * {@link org.opendaylight.controller.sal.core.Property} and its + * extended classes + * + * Example: + * + * Request URL: + * http://localhost:8080/controller/nb/v2/controllermanager/default/properties/?propertyName=macAddress + * + * Response Body in XML: + * + * + * + * + * 3e:04:ef:11:13:80 + * + * + * + * + * Response Body in JSON: + * { "controllerProperties": + * {"properties": + * { "macAddress": + * { "value": "3e:04:ef:11:13:80" } + * } + * } + * } + * + */ + @Path("/{containerName}/properties/") + @GET + @TypeHint(Property.class) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @StatusCodes({ @ResponseCode(code = 200, condition = "Operation successful"), + @ResponseCode(code = 401, condition = "User not authorized to perform this operation"), + @ResponseCode(code = 404, condition = "The containerName or property is not found"), + @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") }) + public ControllerProperties getControllerProperties(@PathParam("containerName") String containerName, + @QueryParam("propertyName") String propertyName, + @QueryParam("_q") String queryString) { + + if (!isValidContainer(containerName)) { + throw new ResourceNotFoundException("Container " + containerName + " does not exist."); + } + + if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) { + throw new UnauthorizedException("User is not authorized to perform this operation on container " + + containerName); + } + + ISwitchManager switchManager = getISwitchManagerService(containerName); + + if (propertyName == null) { + Map propertyMap = switchManager.getControllerProperties(); + Set properties = new HashSet(propertyMap.values()); + return new ControllerProperties(properties); + } + + Set properties = new HashSet(); + Property property = switchManager.getControllerProperty(propertyName); + if (property == null) { + throw new ResourceNotFoundException("Unable to find property with name: " + propertyName); + } + properties.add(property); + ControllerProperties result = new ControllerProperties(properties); + if (queryString != null) { + queryContext.createQuery(queryString, ControllerProperties.class) + .filter(result, Property.class); + } + return result; + + } + + /** + * Add a controller property to the controller. This method overrides + * previously set property values if the property already exist. + * + * @param containerName + * Name of the Container (Eg. 'default') + * @param propertyName + * Name of the Property specified by + * {@link org.opendaylight.controller.sal.core.Property} and its + * extended classes + * @param propertyValue + * Value of the Property specified by + * {@link org.opendaylight.controller.sal.core.Property} and its + * extended classes + * @return Response as dictated by the HTTP Response Status code + * + * Example: + * + * Request URL: + * http://localhost:8080/controller/nb/v2/controllermanager/default/properties/description/defaultController + */ + @Path("/{containerName}/properties/{propertyName}/{propertyValue}") + @PUT + @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @StatusCodes({ @ResponseCode(code = 201, condition = "Operation successful"), + @ResponseCode(code = 400, condition = "Invalid property parameters"), + @ResponseCode(code = 401, condition = "User not authorized to perform this operation"), + @ResponseCode(code = 404, condition = "The containerName or property is not found"), + @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") }) + public Response setControllerProperty(@Context UriInfo uriInfo, @PathParam("containerName") String containerName, + @PathParam("propertyName") String propertyName, @PathParam("propertyValue") String propertyValue) { + + if (!isValidContainer(containerName)) { + throw new ResourceNotFoundException("Container " + containerName + " does not exist."); + } + + if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) { + throw new UnauthorizedException("User is not authorized to perform this operation on container " + + containerName); + } + + ISwitchManager switchManager = getISwitchManagerService(containerName); + + Property prop = switchManager.createProperty(propertyName, propertyValue); + if (prop == null) { + throw new BadRequestException("Property with name " + propertyName + " cannot be created."); + } + + Status status = switchManager.setControllerProperty(prop); + + if (status.isSuccess()) { + NorthboundUtils.auditlog("Controller Property", username, "updated", propertyName); + return Response.created(uriInfo.getRequestUri()).build(); + } + return NorthboundUtils.getResponse(status); + } + + /** + * Delete a property of the controller + * + * @param containerName + * Name of the Container (Eg. 'default') + * @param propertyName + * Name of the Property specified by + * {@link org.opendaylight.controller.sal.core.Property} and its + * extended classes + * @return Response as dictated by the HTTP Response Status code + * + * Example: + * + * Request URL: + * http://localhost:8080/controller/nb/v2/controllermanager/default/properties/description + */ + @Path("/{containerName}/properties/{propertyName}") + @DELETE + @StatusCodes({ @ResponseCode(code = 204, condition = "Property removed successfully"), + @ResponseCode(code = 401, condition = "User not authorized to perform this operation"), + @ResponseCode(code = 404, condition = "The containerName is not found"), + @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") }) + public Response removeControllerProperty(@PathParam("containerName") String containerName, + @PathParam("propertyName") String propertyName) { + + if (!isValidContainer(containerName)) { + throw new ResourceNotFoundException("Container " + containerName + " does not exist."); + } + + if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) { + throw new UnauthorizedException("User is not authorized to perform this operation on container " + + containerName); + } + + ISwitchManager switchManager = getISwitchManagerService(containerName); + + Status status = switchManager.removeControllerProperty(propertyName); + + if (status.isSuccess()) { + NorthboundUtils.auditlog("Controller Property", username, "removed", propertyName); + + return Response.noContent().build(); + } + return NorthboundUtils.getResponse(status); + } + + /** + * Save controller configuration + * + * Request URL: + * http://localhost:8080/controller/nb/v2/controllermanager/configuration + * + * Request body is empty + */ + @Path("/configuration") + @PUT + @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) + @StatusCodes({ + @ResponseCode(code = 204, condition = "Operation successful"), + @ResponseCode(code = 401, condition = "User not authorized to perform this operation"), + @ResponseCode(code = 503, condition = "Configuration service is unavailable.") + }) + public Response saveConfiguration() { + + if (!NorthboundUtils.isAuthorized(getUserName(), "default", Privilege.WRITE, this)) { + throw new UnauthorizedException("User is not authorized to perform this operation"); + } + + IConfigurationService configService = (IConfigurationService) + ServiceHelper.getGlobalInstance(IConfigurationService.class, this); + + if (configService == null) { + throw new ServiceUnavailableException("Configuration Service " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + Status status = configService.saveConfigurations(); + if (status.isSuccess()) { + NorthboundUtils.auditlog("Controller Configuration", username, + "save", "configuration"); + return Response.noContent().build(); + } + return NorthboundUtils.getResponse(status); + } + + private boolean isValidContainer(String containerName) { + if (containerName.equals(GlobalConstants.DEFAULT.toString())) { + return true; + } + IContainerManager containerManager = (IContainerManager) ServiceHelper.getGlobalInstance( + IContainerManager.class, this); + if (containerManager == null) { + throw new ServiceUnavailableException("Container Manager " + RestMessages.SERVICEUNAVAILABLE.toString()); + } + if (containerManager.getContainerNames().contains(containerName)) { + return true; + } + return false; + } + +}