Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions src/main/java/co/zeroae/gate/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.amazonaws.xray.AWSXRay;

import gate.*;
import gate.corpora.DocumentImpl;
import gate.util.GateException;
import gate.util.persistence.PersistenceManager;

Expand Down Expand Up @@ -44,6 +45,7 @@ public class App implements RequestHandler<APIGatewayProxyRequestEvent, APIGatew
private static final String CACHE_DIR = System.getenv().getOrDefault(
"CACHE_DIR_PREFIX", "/tmp/lru/" + GATE_APP_NAME );
private static final double CACHE_DIR_USAGE = .9;
private static final String DIGEST_SALT = UUID.randomUUID().toString();

private static final Logger logger = LogManager.getLogger(App.class);
private static final CorpusController application = AWSXRay.createSegment(
Expand All @@ -60,6 +62,7 @@ public class App implements RequestHandler<APIGatewayProxyRequestEvent, APIGatew
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, final Context context) {
final APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent()
.withHeaders(new HashMap<>());
final Map<String, String> queryStringParams = Optional.ofNullable(input.getQueryStringParameters()).orElse(new HashMap<>());
try {
final String acceptHeader = input.getHeaders().getOrDefault("Accept", "application/json");
final String responseType = ((Supplier<String>) () -> {
Expand All @@ -80,19 +83,22 @@ public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent in


final FeatureMap featureMap = Factory.newFeatureMap();
final Integer nextAnnotationId = Integer.parseInt(queryStringParams.getOrDefault("nextAnnotationId", "0"));
final String contentType = input.getHeaders().getOrDefault("Content-Type", "text/plain");
final String contentDigest = AWSXRay.createSubsegment("Message Digest",() -> {
String rv = Utils.computeMessageDigest(contentType, input.getBody());
String rv = Utils.computeMessageDigest(contentType + input.getBody() + nextAnnotationId + DIGEST_SALT);
AWSXRay.getCurrentSubsegment().putMetadata("SHA256", rv);
return rv;
});
featureMap.put("nextAnnotationId", nextAnnotationId);
putRequestBody(featureMap, contentType, contentDigest, input.getBody(), input.getIsBase64Encoded());

response.getHeaders().put("x-zae-gate-cache", "HIT");
final Document doc = cache.computeIfNull(contentDigest, () -> {
response.getHeaders().put("x-zae-gate-cache", "MISS");
return execute(featureMap);
});

AWSXRay.beginSubsegment("Gate Export");
AWSXRay.getCurrentSubsegment().putMetadata("Content-Type", response.getHeaders().get("Content-Type"));
try {
Expand Down Expand Up @@ -136,10 +142,18 @@ private void putRequestBody(FeatureMap featureMap, String mimeType, String conte
private Document execute(FeatureMap docFeatureMap) throws GateException {
AWSXRay.beginSubsegment("Gate Execute");
try {
final Document rv = (Document) Factory.createResource("gate.corpora.DocumentImpl", docFeatureMap);
application.getCorpus().add(rv);
final DocumentImpl rvImpl;

// Note: The DocumentImpl API does not conform to JavaBeans for the nextAnnotationId method.
// Paragraphs may be annotated right away, so we need to handle that issue.
final int nextAnnotationId = (Integer)docFeatureMap.get("nextAnnotationId");
docFeatureMap.remove("nextAnnotationId");
rvImpl = (DocumentImpl) Factory.createResource("gate.corpora.DocumentImpl", docFeatureMap);
rvImpl.setNextAnnotationId(Math.max(nextAnnotationId, rvImpl.getNextAnnotationId()));

application.getCorpus().add(rvImpl);
application.execute();
return rv;
return rvImpl;
} catch (GateException e) {
AWSXRay.getCurrentSubsegment().addException(e);
throw e;
Expand Down
7 changes: 2 additions & 5 deletions src/main/java/co/zeroae/gate/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,11 @@ static Map<String, DocumentExporter> loadExporters() {
return Collections.unmodifiableMap(rv);
}

static String computeMessageDigest(String mimeType, String bodyContent) {
static String computeMessageDigest(String message) {
try {
final String rv;
final MessageDigest md = MessageDigest.getInstance("SHA-256");
if (mimeType != null)
md.update(mimeType.getBytes());
if (bodyContent != null)
md.update(bodyContent.getBytes());
md.update(message.getBytes());
rv = Hex.encode(md.digest());
return rv;
} catch (NoSuchAlgorithmException e) {
Expand Down
15 changes: 15 additions & 0 deletions src/test/java/co/zeroae/gate/AppTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,21 @@ public void testGateXMLToDocument() throws Exception {
assertEquals(input.getBody(), doc.getContent().toString());
}

@Test
public void testNextAnnotationId() {
final int nextAnnotationId = 1000 + new Random().nextInt(1000);
input.withQueryStringParameters(new HashMap<>())
.getQueryStringParameters()
.put("nextAnnotationId", String.valueOf(nextAnnotationId));

final APIGatewayProxyResponseEvent result = app.handleRequest(input, context);

assertEquals("application/gate+xml", result.getHeaders().get("Content-Type"));
final String resultBody = result.getBody();
assertNotNull(resultBody);
assertTrue(resultBody.contains("<Annotation Id=\"" + (nextAnnotationId+1) + "\""));
}

@Test
public void testMissingContentType() {
input_headers.remove("Content-Type", "text/plain");
Expand Down