Merge "Eradicate exificient from the repository"
[controller.git] / opendaylight / northbound / flowprogrammer / src / main / java / org / opendaylight / controller / flowprogrammer / northbound / FlowProgrammerNorthbound.java
index 1e88c4430548f6de805ee67c4441f49e6db89f3c..4928ddef3b0296b8525531791dfe4272064dfaa1 100644 (file)
@@ -34,7 +34,6 @@ 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;
@@ -145,10 +144,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 +165,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"
+     *         ]
+     *      }
+     *    ]
+     * }
      * </pre>
      */
     @Path("/{containerName}")
@@ -205,10 +220,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:
      * &lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;
      * &lt;list&gt;
      *     &#x20;&#x20;&#x20;&lt;flowConfig&gt;
@@ -226,10 +241,26 @@ public class FlowProgrammerNorthbound {
      *     &#x20;&#x20;&#x20;&lt;/flowConfig&gt;
      * &lt;/list&gt;
      *
-     * 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}")
@@ -272,10 +303,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:
      * &lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;
      * &lt;flowConfig&gt;
      *     &#x20;&#x20;&#x20;&lt;installInHw&gt;true&lt;/installInHw&gt;
@@ -291,9 +322,22 @@ public class FlowProgrammerNorthbound {
      *     &#x20;&#x20;&#x20;&lt;actions&gt;OUTPUT=2&lt;/actions&gt;
      * &lt;/flowConfig&gt;
      *
-     * 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>
      */
@@ -328,8 +372,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 +390,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:
      * &lt;flowConfig&gt;
      *         &#x20;&#x20;&#x20;&lt;installInHw&gt;true&lt;/installInHw&gt;
      *         &#x20;&#x20;&#x20;&lt;name&gt;flow1&lt;/name&gt;
@@ -365,10 +408,22 @@ public class FlowProgrammerNorthbound {
      *         &#x20;&#x20;&#x20;&lt;actions&gt;OUTPUT=2&lt;/actions&gt;
      * &lt;/flowConfig&gt;
      *
-     * 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>
      */
 
@@ -376,6 +431,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 +440,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 +454,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 +465,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 +512,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"),