X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fnorthbound%2Fflowprogrammer%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fflowprogrammer%2Fnorthbound%2FFlowProgrammerNorthbound.java;h=42bd59ea4577ff5c6d40b3ad4e8efaa976c900f5;hb=refs%2Fchanges%2F10%2F7610%2F5;hp=1e88c4430548f6de805ee67c4441f49e6db89f3c;hpb=00a1c2a7297e0d9e00e453c2e8b52471d01dc4c7;p=controller.git diff --git a/opendaylight/northbound/flowprogrammer/src/main/java/org/opendaylight/controller/flowprogrammer/northbound/FlowProgrammerNorthbound.java b/opendaylight/northbound/flowprogrammer/src/main/java/org/opendaylight/controller/flowprogrammer/northbound/FlowProgrammerNorthbound.java index 1e88c44305..42bd59ea45 100644 --- a/opendaylight/northbound/flowprogrammer/src/main/java/org/opendaylight/controller/flowprogrammer/northbound/FlowProgrammerNorthbound.java +++ b/opendaylight/northbound/flowprogrammer/src/main/java/org/opendaylight/controller/flowprogrammer/northbound/FlowProgrammerNorthbound.java @@ -19,10 +19,12 @@ 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.ext.ContextResolver; import org.codehaus.enunciate.jaxrs.ResponseCode; import org.codehaus.enunciate.jaxrs.StatusCodes; @@ -34,10 +36,10 @@ import org.opendaylight.controller.northbound.commons.RestMessages; import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException; import org.opendaylight.controller.northbound.commons.exception.MethodNotAllowedException; import org.opendaylight.controller.northbound.commons.exception.NotAcceptableException; -import org.opendaylight.controller.northbound.commons.exception.ResourceConflictException; 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.Node; @@ -63,6 +65,14 @@ public class FlowProgrammerNorthbound { 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) { @@ -145,10 +155,10 @@ public class FlowProgrammerNorthbound { * * Example: * - * RequestURL: + * Request URL: * http://localhost:8080/controller/nb/v2/flowprogrammer/default * - * Response in XML: + * Response body in XML: * <?xml version="1.0" encoding="UTF-8" standalone="yes"?> * <list> * <flowConfig> @@ -166,10 +176,26 @@ public class FlowProgrammerNorthbound { * </flowConfig> * </list> * - * Response in JSON: - * {"flowConfig":{"installInHw":"true","name":"flow1","node":{"id":"00:00:00:00:00:00:00:01","type":"OF"}, - * "ingressPort":"1","priority":"500","etherType":"0x800","nwSrc":"9.9.1.1","actions":"OUTPUT=2"}} - * + * Response body in JSON: + * { + * "flowConfig": [ + * { + * "installInHw": "true", + * "name": "flow1", + * "node": { + * "type": "OF", + * "id": "00:00:00:00:00:00:00:01" + * }, + * "ingressPort": "1", + * "priority": "500", + * "etherType": "0x800", + * "nwSrc":"9.9.1.1", + * "actions": [ + * "OUTPUT=2" + * ] + * } + * ] + * } * */ @Path("/{containerName}") @@ -179,15 +205,21 @@ public class FlowProgrammerNorthbound { @StatusCodes({ @ResponseCode(code = 200, condition = "Operation successful"), @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 FlowConfigs getStaticFlows(@PathParam("containerName") String containerName) { + @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable"), + @ResponseCode(code = 400, condition = "Incorrect query syntex")}) + public FlowConfigs getStaticFlows(@PathParam("containerName") String containerName, + @QueryParam("_q") String queryString) { if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) { throw new UnauthorizedException("User is not authorized to perform this operation on container " + containerName); } - List flowConfigs = getStaticFlowsInternal(containerName, null); - return new FlowConfigs(flowConfigs); + FlowConfigs result = new FlowConfigs(getStaticFlowsInternal(containerName, null)); + if (queryString != null) { + queryContext.createQuery(queryString, FlowConfigs.class) + .filter(result, FlowConfig.class); + } + return result; } /** @@ -205,10 +237,10 @@ public class FlowProgrammerNorthbound { * * Example: * - * RequestURL: + * Request URL: * http://localhost:8080/controller/nb/v2/flowprogrammer/default/node/OF/00:00:00:00:00:00:00:01 * - * Response in XML: + * Response body in XML: * <?xml version="1.0" encoding="UTF-8" standalone="yes"?> * <list> * <flowConfig> @@ -226,10 +258,26 @@ public class FlowProgrammerNorthbound { * </flowConfig> * </list> * - * Response in JSON: - * {"flowConfig":{"installInHw":"true","name":"flow1","node":{"id":"00:00:00:00:00:00:00:01","type":"OF"}, - * "ingressPort":"1","priority":"500","etherType":"0x800","nwSrc":"9.9.1.1","actions":"OUTPUT=2"}} - * + * Response body in JSON: + * { + * "flowConfig": [ + * { + * "installInHw": "true", + * "name": "flow1", + * "node": { + * "type": "OF", + * "id": "00:00:00:00:00:00:00:01" + * }, + * "ingressPort": "1", + * "priority": "500", + * "etherType": "0x800", + * "nwSrc":"9.9.1.1", + * "actions": [ + * "OUTPUT=2" + * ] + * } + * ] + * } * */ @Path("/{containerName}/node/{nodeType}/{nodeId}") @@ -241,7 +289,8 @@ public class FlowProgrammerNorthbound { @ResponseCode(code = 404, condition = "The containerName or nodeId is not found"), @ResponseCode(code = 503, condition = "One or more of Controller Services are unavailable") }) public FlowConfigs getStaticFlows(@PathParam("containerName") String containerName, - @PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId) { + @PathParam("nodeType") String nodeType, @PathParam("nodeId") String nodeId, + @QueryParam("_q") String queryString) { if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) { throw new UnauthorizedException("User is not authorized to perform this operation on container " + containerName); @@ -250,8 +299,12 @@ public class FlowProgrammerNorthbound { if (node == null) { throw new ResourceNotFoundException(nodeId + " : " + RestMessages.NONODE.toString()); } - List flows = getStaticFlowsInternal(containerName, node); - return new FlowConfigs(flows); + FlowConfigs flows = new FlowConfigs(getStaticFlowsInternal(containerName, node)); + if (queryString != null) { + queryContext.createQuery(queryString, FlowConfigs.class) + .filter(flows, FlowConfig.class); + } + return flows; } /** @@ -272,10 +325,10 @@ public class FlowProgrammerNorthbound { * * Example: * - * RequestURL: + * Request URL: * http://localhost:8080/controller/nb/v2/flowprogrammer/default/node/OF/00:00:00:00:00:00:00:01/staticFlow/flow1 * - * Response in XML: + * Response body in XML: * <?xml version="1.0" encoding="UTF-8" standalone="yes"?> * <flowConfig> * <installInHw>true</installInHw> @@ -291,9 +344,22 @@ public class FlowProgrammerNorthbound { * <actions>OUTPUT=2</actions> * </flowConfig> * - * Response in JSON: - * {"installInHw":"true","name":"flow1","node":{"id":"00:00:00:00:00:00:00:01","type":"OF"}, - * "ingressPort":"1","priority":"500","etherType":"0x800","nwSrc":"9.9.1.1","actions":"OUTPUT=2"} + * Response body in JSON: + * { + * "installInHw":"true", + * "name":"flow1", + * "node":{ + * "id":"00:00:00:00:00:00:00:01", + * "type":"OF" + * }, + * "ingressPort":"1", + * "priority":"500", + * "etherType":"0x800", + * "nwSrc":"9.9.1.1", + * "actions":[ + * "OUTPUT=2" + * ] + * } * * */ @@ -328,8 +394,7 @@ public class FlowProgrammerNorthbound { } /** - * Add a flow configuration. If a flow by the given name already exists, - * this method will respond with a non-successful status response. + * Add or Modify a flow configuration. If the flow exists already, it will replace the current flow. * * @param containerName * Name of the Container (Eg. 'default') @@ -347,10 +412,10 @@ public class FlowProgrammerNorthbound { * * Example: * - * RequestURL: + * Request URL: * http://localhost:8080/controller/nb/v2/flowprogrammer/default/node/OF/00:00:00:00:00:00:00:01/staticFlow/flow1 * - * Request in XML: + * Request body in XML: * <flowConfig> * <installInHw>true</installInHw> * <name>flow1</name> @@ -365,10 +430,22 @@ public class FlowProgrammerNorthbound { * <actions>OUTPUT=2</actions> * </flowConfig> * - * Request in JSON: - * {"installInHw":"true","name":"flow1","node":{"id":"00:00:00:00:00:00:00:01","type":"OF"}, - * "ingressPort":"1","priority":"500","etherType":"0x800","nwSrc":"9.9.1.1","actions":"OUTPUT=2"} - * + * Request body in JSON: + * { + * "installInHw":"true", + * "name":"flow1", + * "node":{ + * "id":"00:00:00:00:00:00:00:01", + * "type":"OF" + * }, + * "ingressPort":"1", + * "priority":"500", + * "etherType":"0x800", + * "nwSrc":"9.9.1.1", + * "actions":[ + * "OUTPUT=2" + * ] + * } * */ @@ -376,6 +453,7 @@ public class FlowProgrammerNorthbound { @PUT @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @StatusCodes({ + @ResponseCode(code = 200, condition = "Static Flow modified successfully"), @ResponseCode(code = 201, condition = "Flow Config processed successfully"), @ResponseCode(code = 400, condition = "Failed to create Static Flow entry due to invalid flow configuration"), @ResponseCode(code = 401, condition = "User not authorized to perform this operation"), @@ -384,7 +462,7 @@ public class FlowProgrammerNorthbound { @ResponseCode(code = 409, condition = "Failed to create Static Flow entry due to Conflicting Name or configuration"), @ResponseCode(code = 500, condition = "Failed to create Static Flow entry. Failure Reason included in HTTP Error response"), @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") }) - public Response addFlow(@PathParam(value = "containerName") String containerName, + public Response addOrModifyFlow(@PathParam(value = "containerName") String containerName, @PathParam(value = "name") String name, @PathParam("nodeType") String nodeType, @PathParam(value = "nodeId") String nodeId, @TypeHint(FlowConfig.class) FlowConfig flowConfig) { @@ -398,7 +476,8 @@ public class FlowProgrammerNorthbound { .build(); } handleResourceCongruence(name, flowConfig.getName()); - handleResourceCongruence(nodeId, flowConfig.getNode().getNodeIDString()); + handleResourceCongruence(nodeType, flowConfig.getNode().getType()); + handleResourceCongruence(nodeId, flowConfig.getNode().getID() == null ? null : flowConfig.getNode().getNodeIDString()); handleDefaultDisabled(containerName); IForwardingRulesManager frm = getForwardingRulesManagerService(containerName); @@ -408,18 +487,24 @@ public class FlowProgrammerNorthbound { } Node node = handleNodeAvailability(containerName, nodeType, nodeId); + Status status; FlowConfig staticFlow = frm.getStaticFlow(name, node); - if (staticFlow != null) { - throw new ResourceConflictException(name + " already exists." + RestMessages.RESOURCECONFLICT.toString()); - } - - Status status = frm.addStaticFlow(flowConfig); - if (status.isSuccess()) { - NorthboundUtils.auditlog("Flow Entry", username, "added", - name + " on Node " + NorthboundUtils.getNodeDesc(node, containerName, this), containerName); - return Response.status(Response.Status.CREATED).entity("Success").build(); + if (staticFlow == null) { + status = frm.addStaticFlow(flowConfig); + if(status.isSuccess()){ + NorthboundUtils.auditlog("Flow Entry", username, "added", + name + " on Node " + NorthboundUtils.getNodeDesc(node, containerName, this), containerName); + return Response.status(Response.Status.CREATED).entity("Success").build(); + } + } else { + status = frm.modifyStaticFlow(flowConfig); + if(status.isSuccess()){ + NorthboundUtils.auditlog("Flow Entry", username, "updated", + name + " on Node " + NorthboundUtils.getNodeDesc(node, containerName, this), containerName); + return NorthboundUtils.getResponse(status); + } } return NorthboundUtils.getResponse(status); } @@ -449,7 +534,6 @@ public class FlowProgrammerNorthbound { @Path("/{containerName}/node/{nodeType}/{nodeId}/staticFlow/{name}") @DELETE - @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @StatusCodes({ @ResponseCode(code = 204, condition = "Flow Config deleted successfully"), @ResponseCode(code = 401, condition = "User not authorized to perform this operation"),