Adding ability to push flow rule batches via REST API.

Change-Id: I60a9b121cd9cc35a9704e59b8f1fde413af0a72f
diff --git a/web/api/src/main/java/org/onosproject/rest/resources/FlowsWebResource.java b/web/api/src/main/java/org/onosproject/rest/resources/FlowsWebResource.java
index 0404967..b90f0a4 100644
--- a/web/api/src/main/java/org/onosproject/rest/resources/FlowsWebResource.java
+++ b/web/api/src/main/java/org/onosproject/rest/resources/FlowsWebResource.java
@@ -41,6 +41,7 @@
 import javax.ws.rs.core.UriInfo;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.List;
 import java.util.stream.StreamSupport;
 
 /**
@@ -54,10 +55,11 @@
     UriInfo uriInfo;
 
     public static final String DEVICE_NOT_FOUND = "Device is not found";
+    public static final String FLOWS = "flows";
 
     final FlowRuleService service = get(FlowRuleService.class);
     final ObjectNode root = mapper().createObjectNode();
-    final ArrayNode flowsNode = root.putArray("flows");
+    final ArrayNode flowsNode = root.putArray(FLOWS);
 
     /**
      * Get all flow entries. Returns array of all flow rules in the system.
@@ -81,6 +83,34 @@
     }
 
     /**
+     * Create new flow rules. Creates and installs a new flow rules.<br>
+     * Instructions description:
+     * https://wiki.onosproject.org/display/ONOS/Flow+Rule+Instructions
+     * <br>
+     * Criteria description:
+     * https://wiki.onosproject.org/display/ONOS/Flow+Rule+Criteria
+     *
+     * @onos.rsModel FlowsBatchPost
+     * @param stream   flow rules JSON
+     * @return status of the request - CREATED if the JSON is correct,
+     * BAD_REQUEST if the JSON is invalid
+     */
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response createFlows(InputStream stream) {
+        try {
+            ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
+            ArrayNode flowsArray = (ArrayNode) jsonTree.get(FLOWS);
+            List<FlowRule> rules = codec(FlowRule.class).decode(flowsArray, this);
+            service.applyFlowRules(rules.toArray(new FlowRule[rules.size()]));
+        } catch (IOException ex) {
+            throw new IllegalArgumentException(ex);
+        }
+        return Response.ok().build();
+    }
+
+    /**
      * Get flow entries of a device. Returns array of all flow rules for the
      * specified device.
      * @onos.rsModel Flows
diff --git a/web/api/src/main/resources/definitions/Flows.json b/web/api/src/main/resources/definitions/Flows.json
index e3fa3f0..ad2d214 100644
--- a/web/api/src/main/resources/definitions/Flows.json
+++ b/web/api/src/main/resources/definitions/Flows.json
@@ -8,7 +8,7 @@
     "flows": {
       "type": "array",
       "xml": {
-        "name": "hosts",
+        "name": "flows",
         "wrapped": true
       },
       "items": {
diff --git a/web/api/src/main/resources/definitions/FlowsBatchPost.json b/web/api/src/main/resources/definitions/FlowsBatchPost.json
new file mode 100644
index 0000000..ff9471d
--- /dev/null
+++ b/web/api/src/main/resources/definitions/FlowsBatchPost.json
@@ -0,0 +1,115 @@
+{
+  "type": "object",
+  "title": "flows",
+  "required": [
+    "flows"
+  ],
+  "properties": {
+    "flows": {
+      "type": "array",
+      "xml": {
+        "name": "flows",
+        "wrapped": true
+      },
+      "items": {
+        "type": "object",
+        "title": "flow",
+        "required": [
+          "priority",
+          "timeout",
+          "isPermanent",
+          "deviceId"
+        ],
+        "properties": {
+          "priority": {
+            "type": "integer",
+            "format": "int64",
+            "example": 400000
+          },
+          "timeout": {
+            "type": "integer",
+            "format": "int64",
+            "example": 0
+          },
+          "isPermanent": {
+            "type": "boolean",
+            "example": true
+          },
+          "deviceId": {
+            "type": "string",
+            "example": "of:0000000000000001"
+          },
+          "treatment": {
+            "type": "object",
+            "title": "treatment",
+            "required": [
+              "instructions",
+              "deferred"
+            ],
+            "properties": {
+              "instructions": {
+                "type": "array",
+                "title": "treatment",
+                "required": [
+                  "properties",
+                  "port"
+                ],
+                "items": {
+                  "type": "object",
+                  "title": "instructions",
+                  "required": [
+                    "type",
+                    "port"
+                  ],
+                  "properties": {
+                    "type": {
+                      "type": "string",
+                      "example": "OUTPUT"
+                    },
+                    "port": {
+                      "type": "string",
+                      "example": "CONTROLLER"
+                    }
+                  }
+                }
+              }
+            }
+          },
+          "selector": {
+            "type": "object",
+            "title": "selector",
+            "required": [
+              "criteria"
+            ],
+            "properties": {
+              "criteria": {
+                "type": "array",
+                "xml": {
+                  "name": "criteria",
+                  "wrapped": true
+                },
+                "items": {
+                  "type": "object",
+                  "title": "criteria",
+                  "properties": {
+                    "type": {
+                      "type": "string",
+                      "description": "Ethernet field name",
+                      "example": "ETH_TYPE"
+                    },
+                    "ethType": {
+                      "type": "int64",
+                      "format": "int64",
+                      "example": "0x88cc",
+                      "description": "Ethernet frame type"
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
\ No newline at end of file