diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f69f244 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.project +.settings +.classpath +target diff --git a/readability-metrics-core/.project b/readability-metrics-core/.project index dd89794..2dd897d 100644 --- a/readability-metrics-core/.project +++ b/readability-metrics-core/.project @@ -15,8 +15,14 @@ + + org.springframework.ide.eclipse.core.springbuilder + + + + org.springframework.ide.eclipse.core.springnature org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature diff --git a/readability-metrics-webapp/.project b/readability-metrics-webapp/.project index 27bd8fa..ca5cc8a 100644 --- a/readability-metrics-webapp/.project +++ b/readability-metrics-webapp/.project @@ -15,8 +15,14 @@ + + org.springframework.ide.eclipse.core.springbuilder + + + + org.springframework.ide.eclipse.core.springnature org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature diff --git a/readability-metrics-webapp/readability-metrics-configuration.xml b/readability-metrics-webapp/readability-metrics-configuration.xml new file mode 100644 index 0000000..1d4d67d --- /dev/null +++ b/readability-metrics-webapp/readability-metrics-configuration.xml @@ -0,0 +1,167 @@ + + + + /debug + See https://github.com/ipeirotis/ReadabilityMetrics/wiki/REST-API:-Diagnostics + + + + + /text/{id} + See https://github.com/ipeirotis/ReadabilityMetrics/wiki/REST-API:-Managing-Texts + + + + 2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18 + + + + + + Text Not Found + + + + + /text/{id}/metrics/{name} + See https://github.com/ipeirotis/ReadabilityMetrics/wiki/REST-API:-Retrieving-Text-Metrics + + + Text Id + o8m0zyetzixyml6g8buhv8vydpag3i:6e048c8dceff8f5591829c39900504e83e6b9179a092a09adb3e5212328c07fc + + + Metric Name + ARI + + + + + + Not Found + + + + + /text/{id}/metrics + See https://github.com/ipeirotis/ReadabilityMetrics/wiki/REST-API:-Retrieving-Text-Metrics + + + Text Id + o8m0zyetzixyml6g8buhv8vydpag3i:6e048c8dceff8f5591829c39900504e83e6b9179a092a09adb3e5212328c07fc + + + + + + /text/{id} + See https://github.com/ipeirotis/ReadabilityMetrics/wiki/REST-API:-Managing-Texts + + + SHA-256 Hex Hash of Content (Lowercase) + 2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18 + + + + + + /text + See https://github.com/ipeirotis/ReadabilityMetrics/wiki/REST-API:-Managing-Texts + + + Body Text + Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + + + + + + Entity Not Found + + + + + /text + List All Texts - See https://github.com/ipeirotis/ReadabilityMetrics/wiki/REST-API:-Managing-Texts + + + + + + { + "Host": [ + "ipeirotis-hrd.appspot.com:80" + ], + "Accept": [ + "application/json" + ], + "X-Forwarded-For": [ + "23.23.3.43, 23.21.68.63" + ], + "x-forwarded-port": [ + "443" + ], + "x-forwarded-proto": [ + "https" + ], + "X-Mashape-Version": [ + "2.3.5" + ], + "X-Mashape-User-PublicKey": [ + "o8m0zyetzixyml6g8buhv8vydpag3i" + ], + "X-Mashape-User": [ + "aldrinleal" + ], + "User-Agent": [ + "mashape-java/2.0" + ], + "X-AppEngine-Country": [ + "US" + ], + "X-AppEngine-Region": [ + "ny" + ], + "X-AppEngine-City": [ + "new york" + ], + "X-AppEngine-CityLatLong": [ + "40.714353,-74.005973" + ] +} + + + + See https://github.com/ipeirotis/ReadabilityMetrics/wiki/REST-API:-Retrieving-Text-Metrics + { + "id": "o8m0zyetzixyml6g8buhv8vydpag3i:6e048c8dceff8f5591829c39900504e83e6b9179a092a09adb3e5212328c07fc", + "metrics": { + "ARI": 39.201 + } +} + + + o8m0zyetzixyml6g8buhv8vydpag3i:6e048c8dceff8f5591829c39900504e83e6b9179a092a09adb3e5212328c07fc + + + + + Represents a Stored Text + { + "id": "o8m0zyetzixyml6g8buhv8vydpag3i:6e048c8dceff8f5591829c39900504e83e6b9179a092a09adb3e5212328c07fc", + "content": "Lorem+ipsum+dolor+sit+amet%2C+consectetur+adipisicing+elit%2C+sed+do+eiusmod+tempor+incididunt+ut+labore+et+dolore+magna+aliqua.+Ut+enim+ad+minim+veniam%2C+quis+nostrud+exercitation+ullamco+laboris+nisi+ut+aliquip+ex+ea+commodo+consequat.+Duis+aute+irure+dolor+in+reprehenderit+in+voluptate+velit+esse+cillum+dolore+eu+fugiat+nulla+pariatur.+Excepteur+sint+occaecat+cupidatat+non+proident%2C+sunt+in+culpa+qui+officia+deserunt+mollit+anim+id+est+laborum.", + "owner": "o8m0zyetzixyml6g8buhv8vydpag3i" +} + + + Lorem+ipsum+dolor+sit+amet%2C+consectetur+adipisicing+elit%2C+sed+do+eiusmod+tempor+incididunt+ut+labore+et+dolore+magna+aliqua.+Ut+enim+ad+minim+veniam%2C+quis+nostrud+exercitation+ullamco+laboris+nisi+ut+aliquip+ex+ea+commodo+consequat.+Duis+aute+irure+dolor+in+reprehenderit+in+voluptate+velit+esse+cillum+dolore+eu+fugiat+nulla+pariatur.+Excepteur+sint+occaecat+cupidatat+non+proident%2C+sunt+in+culpa+qui+officia+deserunt+mollit+anim+id+est+laborum. + + + o8m0zyetzixyml6g8buhv8vydpag3i:6e048c8dceff8f5591829c39900504e83e6b9179a092a09adb3e5212328c07fc + + + o8m0zyetzixyml6g8buhv8vydpag3i + + + + diff --git a/readability-metrics-webapp/src/main/java/com/ipeirotis/readability/web/v1/BaseResource.java b/readability-metrics-webapp/src/main/java/com/ipeirotis/readability/web/v1/BaseResource.java index 3f9d693..5774bea 100644 --- a/readability-metrics-webapp/src/main/java/com/ipeirotis/readability/web/v1/BaseResource.java +++ b/readability-metrics-webapp/src/main/java/com/ipeirotis/readability/web/v1/BaseResource.java @@ -26,6 +26,11 @@ abstract class BaseResource { @Autowired UserService userService; + /** + * Retrieves or creates (if supplied) the User Entity + * + * @return User object + */ Key getOwner() { if (null == user) return null; diff --git a/readability-metrics-webapp/src/main/java/com/ipeirotis/readability/web/v1/TextResource.java b/readability-metrics-webapp/src/main/java/com/ipeirotis/readability/web/v1/TextResource.java index 7c232fc..10f7d08 100644 --- a/readability-metrics-webapp/src/main/java/com/ipeirotis/readability/web/v1/TextResource.java +++ b/readability-metrics-webapp/src/main/java/com/ipeirotis/readability/web/v1/TextResource.java @@ -27,6 +27,12 @@ import com.ipeirotis.readability.service.TextMetricService; import com.ipeirotis.readability.service.TextService; +/** + * Represents the Text Manipulation Resource + * + * @author aldrin + * + */ @Component @Scope("request") @Produces(MediaType.APPLICATION_JSON_VALUE) @@ -40,7 +46,12 @@ public class TextResource extends BaseResource { @Autowired ReadabilityService readabilityService; - + + /** + * Handler needed for CORS support + * + * @return CORS Response + */ @OPTIONS @Path(".*") public Response getOptionsForUpdateText() throws Exception { @@ -53,6 +64,13 @@ public Response getOptionsForUpdateText() throws Exception { .build(); } + /** + * Updates (read: stores) a Text + * + * @param contents + * Body Context (Form Method) + * @return Created Text Object + */ @POST public Text updateText(String contents) throws Exception { @SuppressWarnings("unused") @@ -61,7 +79,7 @@ public Text updateText(String contents) throws Exception { if (contents.startsWith("body=")) { contents = contents.substring("body=".length()); } - + t = new Text(user, contents); if (null == (o = textService.findFirstByPrimaryKey(t.getId()))) { @@ -72,6 +90,14 @@ public Text updateText(String contents) throws Exception { return t; } + /** + * Given an Id, returns the Text + * + * @param id + * id, in the form <userid>:<sha1hash> + * + * @return Text Object + */ @Path("/{id : [^/]+}") @GET public Text findById(@PathParam("id") String id) throws Exception { @@ -83,6 +109,13 @@ public Text findById(@PathParam("id") String id) throws Exception { return t; } + /** + * Returns the text metrics for given id + * + * @param id + * id, in the form <userid>:<sha1hash> + * @return Json Array of Object Id + Metrics + */ @Path("/{id : [^/]+}/metrics") @GET public Map findMetricsById(@PathParam("id") String id) @@ -103,6 +136,15 @@ public Map findMetricsById(@PathParam("id") String id) return result; } + /** + * Returns a Named Metric + * + * @param id + * id, in the form <userid>:<sha1hash> + * @param metricType + * metric type (ARI, CHARACTERS, SYLLABLES, ...) + * @return Named Metric (just like the example in findMetricsById + */ @Path("/{id : [^/]+}/metrics/{metricType : \\w+}") @GET public Map findNamedMetricsById(@PathParam("id") String id, @@ -114,7 +156,8 @@ public Map findNamedMetricsById(@PathParam("id") String id, Map metrics = new LinkedHashMap(); - TextMetric m = textMetricService.findFirstByPrimaryKey(String.format("%s:%s", t.getId(), metricType)); + TextMetric m = textMetricService.findFirstByPrimaryKey(String.format( + "%s:%s", t.getId(), metricType)); metrics.put(m.getMetricType(), m.getValue()); @@ -123,6 +166,13 @@ public Map findNamedMetricsById(@PathParam("id") String id, return result; } + /** + * Deletes a Text + * + * @param id + * id, in the form <userid>:<sha1hash> + * @return Text Data, prior to removal + */ @Path("/{id : [^/]+}") @DELETE public Text deleteById(@PathParam("id") String id) throws Exception { @@ -136,6 +186,11 @@ public Text deleteById(@PathParam("id") String id) throws Exception { return t; } + /** + * Returns all texts which belongs to this user + * + * @return array of Text Objects + */ @GET public Collection findAll() { return Lists.newArrayList(textService.findAllByParentKey(user.getId())); diff --git a/readability-metrics-webapp/src/test/java/com/ipeirotis/readability/web/v1/MashapeTextResourceIT.java b/readability-metrics-webapp/src/test/java/com/ipeirotis/readability/web/v1/MashapeTextResourceIT.java new file mode 100644 index 0000000..d8d5e82 --- /dev/null +++ b/readability-metrics-webapp/src/test/java/com/ipeirotis/readability/web/v1/MashapeTextResourceIT.java @@ -0,0 +1,130 @@ +package com.ipeirotis.readability.web.v1; + +import static com.jayway.restassured.RestAssured.basePath; +import static com.jayway.restassured.RestAssured.given; + +import org.hamcrest.core.StringContains; +import org.junit.Before; +import org.junit.Test; + +import com.jayway.restassured.builder.RequestSpecBuilder; +import com.jayway.restassured.specification.RequestSpecification; + +public class MashapeTextResourceIT { + private static final String MASHAPE_AUTH_HEADER_VALUE = "bWpjNGM1Y2p1bXpmaTJqc3Bha2t3NHpieW1sanFlOjJlNDg2ODNjYjQxNThkYjc1MzNiZTFkNzAxYTMwMzMwZGQyMWJjMzU="; + + private static final String MASHAPE_PUBLIC_USER_ID = "mjc4c5cjumzfi2jspakkw4zbymljqe"; + + private static final String PHIL_SPACE = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; + + private RequestSpecification requestSpec; + + @Before + public void before() throws Exception { + basePath = "https://readabilitymetrics.p.mashape.com"; + + this.requestSpec = new RequestSpecBuilder().addHeader( + "X-Mashape-Authorization", MASHAPE_AUTH_HEADER_VALUE).build(); + } + + @Test + public void testSaveText() throws Exception { + given().spec(requestSpec) + .// + body(PHIL_SPACE) + .// + expect() + .statusCode(200) + .body(StringContains + .containsString(MASHAPE_PUBLIC_USER_ID + + ":2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18")) + .when().post("/text"); + } + + @Test + public void testFindAll() throws Exception { + testSaveText(); + given().spec(requestSpec) + .// + expect() + .statusCode(200) + .body(StringContains + .containsString(MASHAPE_PUBLIC_USER_ID + + ":2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18")) + .when().get("/text"); + } + + @Test + public void testGetNamed() throws Exception { + testSaveText(); + given().spec(requestSpec) + .// + expect() + .statusCode(200) + .body(StringContains + .containsString(MASHAPE_PUBLIC_USER_ID + + ":2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18")) + .when() + .get("/text/" + + MASHAPE_PUBLIC_USER_ID + + ":2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18"); + } + + @Test + public void testGetMetrics() throws Exception { + testSaveText(); + given().spec(requestSpec) + .// + expect() + .statusCode(200) + .body(StringContains + .containsString(MASHAPE_PUBLIC_USER_ID + + ":2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18")) + .body(StringContains.containsString("370.00")) + .when() + .get("/text/" + + MASHAPE_PUBLIC_USER_ID + + ":2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18/metrics"); + } + + @Test + public void testGetNamedMetrics() throws Exception { + testSaveText(); + given().spec(requestSpec) + .// + expect() + .statusCode(200) + .body(StringContains.containsString("370.00")) + .when() + .get("/text/" + + MASHAPE_PUBLIC_USER_ID + + ":2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18/metrics/CHARACTERS"); + } + + @Test + public void testDelete() throws Exception { + testSaveText(); + + given().spec(requestSpec) + .// + expect() + .statusCode(200) + .body(StringContains + .containsString(MASHAPE_PUBLIC_USER_ID + + ":2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18")) + .when() + .delete("/text/" + + MASHAPE_PUBLIC_USER_ID + + ":2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18"); + + given().spec(requestSpec) + .// + expect() + .statusCode(404) + .when() + .get("/text/" + + MASHAPE_PUBLIC_USER_ID + + ":2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18"); + } + +} diff --git a/readability-metrics-webapp/src/test/java/com/ipeirotis/readability/web/v1/TextResourceIT.java b/readability-metrics-webapp/src/test/java/com/ipeirotis/readability/web/v1/TextResourceIT.java index 40b7e31..9211fcb 100644 --- a/readability-metrics-webapp/src/test/java/com/ipeirotis/readability/web/v1/TextResourceIT.java +++ b/readability-metrics-webapp/src/test/java/com/ipeirotis/readability/web/v1/TextResourceIT.java @@ -7,22 +7,30 @@ import org.junit.Before; import org.junit.Test; +import com.jayway.restassured.builder.RequestSpecBuilder; +import com.jayway.restassured.specification.RequestSpecification; + public class TextResourceIT { + private static final String MASHAPE_PUBLIC_USER_ID = "mjc4c5cjumzfi2jspakkw4zbymljqe"; + private static final String PHIL_SPACE = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; + + private RequestSpecification requestSpec; @Before public void before() throws Exception { basePath = "http://127.0.0.1:8080/api/v1"; + this.requestSpec = new RequestSpecBuilder().addHeader("x-mashape-publickey", MASHAPE_PUBLIC_USER_ID).build(); } @Test public void testSaveText() throws Exception { given(). + spec(requestSpec).// body(PHIL_SPACE).// - header("x-mashape-user-publickey", "o8m0zyetzixyml6g8buhv8vydpag3i").// expect(). statusCode(200). - body(StringContains.containsString("o8m0zyetzixyml6g8buhv8vydpag3i:2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18")). + body(StringContains.containsString(MASHAPE_PUBLIC_USER_ID + ":2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18")). when(). post("/text"); } @@ -31,10 +39,10 @@ public void testSaveText() throws Exception { public void testFindAll() throws Exception { testSaveText(); given(). - header("x-mashape-user-publickey", "o8m0zyetzixyml6g8buhv8vydpag3i").// + spec(requestSpec).// expect(). statusCode(200). - body(StringContains.containsString("o8m0zyetzixyml6g8buhv8vydpag3i:2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18")). + body(StringContains.containsString(MASHAPE_PUBLIC_USER_ID + ":2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18")). when(). get("/text"); } @@ -43,57 +51,57 @@ public void testFindAll() throws Exception { public void testGetNamed() throws Exception { testSaveText(); given(). - header("x-mashape-user-publickey", "o8m0zyetzixyml6g8buhv8vydpag3i").// + spec(requestSpec).// expect(). statusCode(200). - body(StringContains.containsString("o8m0zyetzixyml6g8buhv8vydpag3i:2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18")). + body(StringContains.containsString(MASHAPE_PUBLIC_USER_ID + ":2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18")). when(). - get("/text/o8m0zyetzixyml6g8buhv8vydpag3i:2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18"); + get("/text/" + MASHAPE_PUBLIC_USER_ID + ":2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18"); } @Test public void testGetMetrics() throws Exception { testSaveText(); given(). - header("x-mashape-user-publickey", "o8m0zyetzixyml6g8buhv8vydpag3i").// + spec(requestSpec).// expect(). statusCode(200). - body(StringContains.containsString("o8m0zyetzixyml6g8buhv8vydpag3i:2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18")). + body(StringContains.containsString(MASHAPE_PUBLIC_USER_ID + ":2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18")). body(StringContains.containsString("370.00")). when(). - get("/text/o8m0zyetzixyml6g8buhv8vydpag3i:2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18/metrics"); + get("/text/" + MASHAPE_PUBLIC_USER_ID + ":2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18" + "/metrics"); } @Test public void testGetNamedMetrics() throws Exception { testSaveText(); - given(). - header("x-mashape-user-publickey", "o8m0zyetzixyml6g8buhv8vydpag3i").// + given().// + spec(requestSpec).// expect(). statusCode(200). body(StringContains.containsString("370.00")). when(). - get("/text/o8m0zyetzixyml6g8buhv8vydpag3i:2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18/metrics/CHARACTERS"); + get("/text/" + MASHAPE_PUBLIC_USER_ID + ":2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18" + "/metrics/CHARACTERS"); } @Test public void testDelete() throws Exception { testSaveText(); - given(). - header("x-mashape-user-publickey", "o8m0zyetzixyml6g8buhv8vydpag3i").// + given().// + spec(requestSpec).// expect(). statusCode(200). - body(StringContains.containsString("o8m0zyetzixyml6g8buhv8vydpag3i:2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18")). + body(StringContains.containsString(MASHAPE_PUBLIC_USER_ID + ":2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18")). when(). delete("/text/o8m0zyetzixyml6g8buhv8vydpag3i:2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18"); - given(). - header("x-mashape-user-publickey", "o8m0zyetzixyml6g8buhv8vydpag3i").// + given().// + spec(requestSpec).// expect(). statusCode(404). when(). - get("/text/o8m0zyetzixyml6g8buhv8vydpag3i:2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18"); + get("/text/" + MASHAPE_PUBLIC_USER_ID + ":2c7c3d5f244f1a40069a32224215e0cf9b42485c99d80f357d76f006359c7a18"); } }