Refactoring and enabling AclWebResourceTest

JIRA ID : ONOS-7961
1. Removed @Ignore and enabled the tests
2. Refactored the code in order to extract json string as seperate files
3. Added additional tests

Change-Id: Ic08128575e7a37a9a7dcdc08a6a8eec0e7e19f68
diff --git a/apps/acl/BUILD b/apps/acl/BUILD
index 58e48ae..57963c7 100644
--- a/apps/acl/BUILD
+++ b/apps/acl/BUILD
@@ -6,6 +6,8 @@
 
 TEST_DEPS = TEST_REST + [
     "@jersey_server//jar",
+    "@minimal_json//jar",
+    "//web/api:onos-rest-tests",
 ]
 
 osgi_jar_with_tests(
diff --git a/apps/acl/src/main/java/org/onosproject/acl/AclWebResource.java b/apps/acl/src/main/java/org/onosproject/acl/AclWebResource.java
index 972c1d9..21c3939 100644
--- a/apps/acl/src/main/java/org/onosproject/acl/AclWebResource.java
+++ b/apps/acl/src/main/java/org/onosproject/acl/AclWebResource.java
@@ -40,7 +40,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
-import java.net.URISyntaxException;
 import java.util.List;
 
 import static org.onlab.util.Tools.readTreeFromStream;
@@ -50,6 +49,7 @@
  */
 @Path("rules")
 public class AclWebResource extends AbstractWebResource {
+    private static final int  MULTI_STATUS_RESPONSE = 207;
 
     /**
      * Get all ACL rules.
@@ -113,16 +113,19 @@
      * Add a new ACL rule.
      *
      * @param stream JSON data describing the rule
-     * @return 200 OK
-     * @throws URISyntaxException uri syntax exception
+     * @return 200 OK for successful aclRule application
      */
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
-    public Response addAclRule(InputStream stream) throws URISyntaxException {
-        AclRule newRule = jsonToRule(stream);
-        return get(AclService.class).addAclRule(newRule) ?
-                Response.created(new URI(newRule.id().toString())).build() :
-                Response.serverError().build();
+    public Response addAclRule(InputStream stream) {
+        try {
+            AclRule newRule = jsonToRule(stream);
+            return get(AclService.class).addAclRule(newRule) ?
+                    Response.created(new URI(newRule.id().toString())).build() :
+                    Response.serverError().build();
+        } catch (Exception e) {
+            return Response.status(MULTI_STATUS_RESPONSE).entity(e.getMessage()).build();
+        }
     }
 
     /**
diff --git a/apps/acl/src/test/java/org/onosproject/acl/AclWebResourceTest.java b/apps/acl/src/test/java/org/onosproject/acl/AclWebResourceTest.java
index 003cf8c..c3693cb 100644
--- a/apps/acl/src/test/java/org/onosproject/acl/AclWebResourceTest.java
+++ b/apps/acl/src/test/java/org/onosproject/acl/AclWebResourceTest.java
@@ -22,32 +22,34 @@
 package org.onosproject.acl;
 
 import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.onlab.junit.TestUtils;
 import org.onlab.osgi.ServiceDirectory;
 import org.onlab.osgi.TestServiceDirectory;
 import org.onlab.rest.BaseResource;
 import org.onosproject.core.IdGenerator;
+import org.onosproject.rest.resources.ResourceTest;
 
 import javax.ws.rs.client.Entity;
 import javax.ws.rs.client.WebTarget;
-import java.io.IOException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicLong;
 
 import static org.easymock.EasyMock.*;
 import static org.hamcrest.Matchers.containsString;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertThat;
 
 /**
  * Test class for ACL application REST resource.
  */
-public class AclWebResourceTest extends JerseyTest {
+public class AclWebResourceTest extends ResourceTest {
 
     final AclService mockAclService = createMock(AclService.class);
     final AclStore mockAclStore = createMock(AclStore.class);
@@ -66,8 +68,8 @@
         ServiceDirectory testDirectory = new TestServiceDirectory()
                 .add(AclService.class, mockAclService)
                 .add(AclStore.class, mockAclStore);
+        setServiceDirectory(testDirectory);
         TestUtils.setField(BaseResource.class, "services", testDirectory);
-
         AclRule.idGenerator = new MockIdGenerator();
     }
 
@@ -89,61 +91,89 @@
     }
 
     @Test
-    @Ignore("FIXME: This needs to get reworked")
-    public void addRule() throws IOException {
+    public void addInvalidRule() {
         WebTarget wt = target();
         String response;
-        String json;
+        InputStream jsonStream;
 
         replay(mockAclService);
 
-        // FIXME: following code snippet requires refactoring by extracting
-        // json string as a separated file
-
         // input a invalid JSON string that contains neither nw_src and nw_dst
-        json = "{\"ipProto\":\"TCP\",\"dstTpPort\":\"80\"}";
-        response = wt.request().post(Entity.json(json), String.class);
-        assertThat(response, containsString("Failed! Either srcIp or dstIp must be assigned."));
+        jsonStream = AclWebResourceTest.class
+                .getResourceAsStream("post-invalid-acl.json");
+        response = wt.path("rules").request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream), String.class);
+        assertThat(response.toString(), containsString("Either srcIp or dstIp must be assigned."));
+
 
         // input a invalid JSON string that doesn't contain CIDR mask bits
-        json = "{\"ipProto\":\"TCP\",\"srcIp\":\"10.0.0.1\",\"dstTpPort\":\"80\",\"action\":\"DENY\"}";
-        response = wt.request().post(Entity.json(json), String.class);
+        jsonStream = AclWebResourceTest.class
+                .getResourceAsStream("post-invalid-ip-1.json");
+        response = wt.path("rules").request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream), String.class);
         assertThat(response, containsString("Malformed IPv4 prefix string: 10.0.0.1. " +
                                                     "Address must take form \"x.x.x.x/y\""));
 
         // input a invalid JSON string that contains a invalid IP address
-        json = "{\"ipProto\":\"TCP\",\"srcIp\":\"10.0.0.256/32\",\"dstTpPort\":\"80\",\"action\":\"DENY\"}";
-        response = wt.request().post(Entity.json(json), String.class);
+        jsonStream = AclWebResourceTest.class
+                .getResourceAsStream("post-invalid-ip-2.json");
+        response = wt.path("rules").request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream), String.class);
         assertThat(response, containsString("Invalid IP address string: 10.0.0.256"));
 
         // input a invalid JSON string that contains a invalid IP address
-        json = "{\"ipProto\":\"TCP\",\"srcIp\":\"10.0.01/32\",\"dstTpPort\":\"80\",\"action\":\"DENY\"}";
-        response = wt.request().post(Entity.json(json), String.class);
+
+        jsonStream = AclWebResourceTest.class
+                .getResourceAsStream("post-invalid-ip-3.json");
+        response = wt.path("rules").request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream), String.class);
         assertThat(response, containsString("Invalid IP address string: 10.0.01"));
 
         // input a invalid JSON string that contains a invalid CIDR mask bits
-        json = "{\"ipProto\":\"TCP\",\"srcIp\":\"10.0.0.1/a\",\"dstTpPort\":\"80\",\"action\":\"DENY\"}";
-        response = wt.request().post(Entity.json(json), String.class);
-        assertThat(response, containsString("Failed! For input string: \"a\""));
+        jsonStream = AclWebResourceTest.class
+                .getResourceAsStream("post-invalid-cidr-1.json");
+        response = wt.path("rules").request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream), String.class);
+        assertThat(response, containsString("For input string: \"a\""));
 
         // input a invalid JSON string that contains a invalid CIDR mask bits
-        json = "{\"ipProto\":\"TCP\",\"srcIp\":\"10.0.0.1/33\",\"dstTpPort\":\"80\",\"action\":\"DENY\"}";
-        response = wt.request().post(Entity.json(json), String.class);
+        jsonStream = AclWebResourceTest.class
+                .getResourceAsStream("post-invalid-cidr-2.json");
+        response = wt.path("rules").request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream), String.class);
         assertThat(response, containsString("Invalid prefix length 33. The value must be in the interval [0, 32]"));
 
         // input a invalid JSON string that contains a invalid ipProto value
-        json = "{\"ipProto\":\"ARP\",\"srcIp\":\"10.0.0.1/32\",\"dstTpPort\":\"80\",\"action\":\"DENY\"}";
-        response = wt.request().post(Entity.json(json), String.class);
-        assertThat(response, containsString("ipProto must be assigned to TCP, UDP, or ICMP."));
-
-        // input a invalid JSON string that contains a invalid dstTpPort value
-        json = "{\"ipProto\":\"TCP\",\"srcIp\":\"10.0.0.1/32\",\"dstTpPort\":\"a\",\"action\":\"DENY\"}";
-        response = wt.request().post(Entity.json(json), String.class);
-        assertThat(response, containsString("dstTpPort must be assigned to a numerical value."));
+        jsonStream = AclWebResourceTest.class
+                .getResourceAsStream("post-invalid-proto.json");
+        response = wt.path("rules").request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream), String.class);
+        assertThat(response, containsString("ipProto must be assigned to TCP, UDP, or ICMP"));
 
         // input a invalid JSON string that contains a invalid action value
-        json = "{\"ipProto\":\"TCP\",\"srcIp\":\"10.0.0.1/32\",\"dstTpPort\":\"80\",\"action\":\"PERMIT\"}";
-        response = wt.request().post(Entity.json(json), String.class);
-        assertThat(response, containsString("action must be assigned to ALLOW or DENY."));
+        jsonStream = AclWebResourceTest.class
+                .getResourceAsStream("post-invalid-action.json");
+        response = wt.path("rules").request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream), String.class);
+        assertThat(response, containsString("action must be ALLOW or DENY"));
     }
+
+    @Test
+    public void addRule() {
+        mockAclService.addAclRule(anyObject());
+        expectLastCall().andReturn(true).anyTimes();
+        replay(mockAclService);
+
+        WebTarget wt = target();
+        InputStream jsonStream;
+
+        jsonStream = AclWebResourceTest.class
+                .getResourceAsStream("post-valid-acl.json");
+        Response response = wt.path("rules").request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream));
+        assertEquals(response.getLocation().getPath(), "/0x0");
+
+    }
+
+
 }
diff --git a/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-acl.json b/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-acl.json
new file mode 100644
index 0000000..aace96c
--- /dev/null
+++ b/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-acl.json
@@ -0,0 +1,3 @@
+{"ipProto":"TCP",
+"dstTpPort":"80"
+}
\ No newline at end of file
diff --git a/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-action.json b/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-action.json
new file mode 100644
index 0000000..41b594a
--- /dev/null
+++ b/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-action.json
@@ -0,0 +1,5 @@
+{"ipProto":"TCP",
+  "srcIp":"10.0.0.1/32",
+  "dstTpPort":"80",
+  "action":"PERMIT"
+}
\ No newline at end of file
diff --git a/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-cidr-1.json b/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-cidr-1.json
new file mode 100644
index 0000000..f569fc4
--- /dev/null
+++ b/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-cidr-1.json
@@ -0,0 +1,5 @@
+{"ipProto":"TCP",
+  "srcIp":"10.0.0.1/a",
+  "dstTpPort":"80",
+  "action":"DENY"
+}
\ No newline at end of file
diff --git a/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-cidr-2.json b/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-cidr-2.json
new file mode 100644
index 0000000..f51aa96
--- /dev/null
+++ b/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-cidr-2.json
@@ -0,0 +1,5 @@
+{"ipProto":"TCP",
+  "srcIp":"10.0.0.1/33",
+  "dstTpPort":"80",
+  "action":"DENY"
+}
\ No newline at end of file
diff --git a/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-ip-1.json b/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-ip-1.json
new file mode 100644
index 0000000..237bf3c
--- /dev/null
+++ b/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-ip-1.json
@@ -0,0 +1,5 @@
+{"ipProto":"TCP",
+  "srcIp":"10.0.0.1",
+  "dstTpPort":"80",
+  "action":"DENY"
+}
\ No newline at end of file
diff --git a/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-ip-2.json b/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-ip-2.json
new file mode 100644
index 0000000..b1cef9c
--- /dev/null
+++ b/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-ip-2.json
@@ -0,0 +1,5 @@
+{"ipProto":"TCP",
+  "srcIp":"10.0.0.256/32",
+  "dstTpPort":"80",
+  "action":"DENY"
+}
\ No newline at end of file
diff --git a/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-ip-3.json b/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-ip-3.json
new file mode 100644
index 0000000..2fee651
--- /dev/null
+++ b/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-ip-3.json
@@ -0,0 +1,5 @@
+{"ipProto":"TCP",
+  "srcIp":"10.0.01/32",
+  "dstTpPort":"80",
+  "action":"DENY"
+}
\ No newline at end of file
diff --git a/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-proto.json b/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-proto.json
new file mode 100644
index 0000000..b69b89d
--- /dev/null
+++ b/apps/acl/src/test/resources/org/onosproject/acl/post-invalid-proto.json
@@ -0,0 +1,5 @@
+{"ipProto":"ARP",
+  "srcIp":"10.0.0.1/32",
+  "dstTpPort":"80",
+  "action":"DENY"
+}
\ No newline at end of file
diff --git a/apps/acl/src/test/resources/org/onosproject/acl/post-valid-acl.json b/apps/acl/src/test/resources/org/onosproject/acl/post-valid-acl.json
new file mode 100644
index 0000000..9e0ed99
--- /dev/null
+++ b/apps/acl/src/test/resources/org/onosproject/acl/post-valid-acl.json
@@ -0,0 +1,9 @@
+{"ipProto":"TCP",
+  "srcMac":"11:22:33:11:22:33",
+  "dstMac":"22:11:33:22:11:33",
+  "srcIp":"10.0.0.1/32",
+  "dstIp":"10.0.0.2/32",
+  "dstTpPort":20,
+  "srcTpPort":30,
+  "action":"DENY"
+}
\ No newline at end of file