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;
*
* 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>
*    </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"
+ * ]
+ * }
+ * ]
+ * }
* </pre>
*/
@Path("/{containerName}")
*
* 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>
*    </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"
+ * ]
+ * }
+ * ]
+ * }
* </pre>
*/
@Path("/{containerName}/node/{nodeType}/{nodeId}")
*
* 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>
*    <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"
+ * ]
+ * }
*
* </pre>
*/
}
/**
- * 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')
*
* 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>
*    <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"
+ * ]
+ * }
* </pre>
*/
@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"),
@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) {
.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);
}
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);
}
@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"),