diff --git a/build.gradle b/build.gradle index 3e01976..7969e43 100644 --- a/build.gradle +++ b/build.gradle @@ -37,8 +37,8 @@ targetCompatibility = JavaVersion.VERSION_1_8 dependencies { implementation 'com.amazonaws:aws-lambda-java-core:1.1.0' - // 2.2.2 is earliest version that has all needed event sources - implementation 'com.amazonaws:aws-lambda-java-events:2.2.2' + // 2.2.7 is earliest version that has all needed event sources + implementation 'com.amazonaws:aws-lambda-java-events:2.2.7' implementation 'com.amazonaws:aws-java-sdk-s3:1.11.163' implementation 'com.amazonaws:aws-java-sdk-kinesis:1.11.163' implementation 'com.amazonaws:aws-java-sdk-dynamodb:1.11.163' diff --git a/src/main/java/com/newrelic/opentracing/aws/EventSourceParser.java b/src/main/java/com/newrelic/opentracing/aws/EventSourceParser.java index b7bc09c..7c0faf4 100644 --- a/src/main/java/com/newrelic/opentracing/aws/EventSourceParser.java +++ b/src/main/java/com/newrelic/opentracing/aws/EventSourceParser.java @@ -6,6 +6,7 @@ package com.newrelic.opentracing.aws; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; +import com.amazonaws.services.lambda.runtime.events.APIGatewayV2ProxyRequestEvent; import com.amazonaws.services.lambda.runtime.events.CodeCommitEvent; import com.amazonaws.services.lambda.runtime.events.DynamodbEvent; import com.amazonaws.services.lambda.runtime.events.KinesisEvent; @@ -49,6 +50,8 @@ static String parseEventSourceArn(Object object) { return parseCodeCommitEventSourceArn(object); } else if (object instanceof APIGatewayProxyRequestEvent) { return parseAPIGatewayProxyRequestEventUserArn(object); + } else if (object instanceof APIGatewayV2ProxyRequestEvent) { + return parseAPIGatewayV2ProxyRequestEventUserArn(object); } return null; } @@ -221,4 +224,22 @@ private static String parseAPIGatewayProxyRequestEventUserArn(Object object) { return identity.getUserArn(); } + + private static String parseAPIGatewayV2ProxyRequestEventUserArn(Object object) { + APIGatewayV2ProxyRequestEvent apiGatewayV2ProxyRequestEvent = + (APIGatewayV2ProxyRequestEvent) object; + + APIGatewayV2ProxyRequestEvent.RequestContext requestContext = + apiGatewayV2ProxyRequestEvent.getRequestContext(); + if (requestContext == null) { + return null; + } + + APIGatewayV2ProxyRequestEvent.RequestIdentity identity = requestContext.getIdentity(); + if (identity == null) { + return null; + } + + return identity.getUserArn(); + } } diff --git a/src/main/java/com/newrelic/opentracing/aws/ResponseParser.java b/src/main/java/com/newrelic/opentracing/aws/ResponseParser.java index db1dbf2..87ca902 100644 --- a/src/main/java/com/newrelic/opentracing/aws/ResponseParser.java +++ b/src/main/java/com/newrelic/opentracing/aws/ResponseParser.java @@ -6,6 +6,7 @@ package com.newrelic.opentracing.aws; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; +import com.amazonaws.services.lambda.runtime.events.APIGatewayV2ProxyResponseEvent; import io.opentracing.Span; import java.util.Map; @@ -34,6 +35,12 @@ public static void parseResponse(Output response, Span span) { if (response != null) { statusCode = apiGatewayProxyResponseEvent.getStatusCode() + ""; } + } else if (response instanceof APIGatewayV2ProxyResponseEvent) { + final APIGatewayV2ProxyResponseEvent apiGatewayV2ProxyResponseEvent = + (APIGatewayV2ProxyResponseEvent) response; + if (response != null) { + statusCode = apiGatewayV2ProxyResponseEvent.getStatusCode() + ""; + } } if (statusCode != null && !statusCode.isEmpty()) { diff --git a/src/test/java/com/newrelic/opentracing/aws/TracingRequestHandlerTest.java b/src/test/java/com/newrelic/opentracing/aws/TracingRequestHandlerTest.java index 9eb1b36..c3b3a06 100644 --- a/src/test/java/com/newrelic/opentracing/aws/TracingRequestHandlerTest.java +++ b/src/test/java/com/newrelic/opentracing/aws/TracingRequestHandlerTest.java @@ -10,6 +10,9 @@ import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.LambdaLogger; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; +import com.amazonaws.services.lambda.runtime.events.APIGatewayV2ProxyRequestEvent; +import com.amazonaws.services.lambda.runtime.events.APIGatewayV2ProxyResponseEvent; import com.amazonaws.services.lambda.runtime.events.CloudFrontEvent; import com.amazonaws.services.lambda.runtime.events.CloudWatchLogsEvent; import com.amazonaws.services.lambda.runtime.events.CodeCommitEvent; @@ -253,6 +256,74 @@ public void testAPIGatewayProxyRequestEvent() { "APIGatewayProxyRequestEventUserARN", span.tags().get("aws.lambda.eventSource.arn")); } + @Test + public void testAPIGatewayProxyRequestResponseEvent() { + int expectedStatusCode = 200; + final MyApiGatewayProxyRequestResponseHandler myApiGatewayProxyRequestHandler = + new MyApiGatewayProxyRequestResponseHandler(expectedStatusCode); + + final APIGatewayProxyRequestEvent apiGatewayProxyRequestEvent = + new APIGatewayProxyRequestEvent(); + final APIGatewayProxyRequestEvent.RequestIdentity requestIdentity = + new APIGatewayProxyRequestEvent.RequestIdentity(); + requestIdentity.setUserArn("APIGatewayProxyRequestEventUserARN"); + final APIGatewayProxyRequestEvent.ProxyRequestContext proxyRequestContext = + new APIGatewayProxyRequestEvent.ProxyRequestContext(); + proxyRequestContext.setIdentity(requestIdentity); + apiGatewayProxyRequestEvent.setRequestContext(proxyRequestContext); + + myApiGatewayProxyRequestHandler.handleRequest(apiGatewayProxyRequestEvent, createContext()); + final MockSpan span = mockTracer.finishedSpans().get(0); + Assert.assertEquals( + "APIGatewayProxyRequestEventUserARN", span.tags().get("aws.lambda.eventSource.arn")); + Assert.assertEquals(Integer.toString(expectedStatusCode), span.tags().get("http.status_code")); + } + + @Test + public void testAPIGatewayV2ProxyRequestEvent() { + final MyApiGatewayV2ProxyRequestHandler myApiGatewayV2ProxyRequestHandler = + new MyApiGatewayV2ProxyRequestHandler(); + + final APIGatewayV2ProxyRequestEvent apiGatewayV2ProxyRequestEvent = + new APIGatewayV2ProxyRequestEvent(); + final APIGatewayV2ProxyRequestEvent.RequestIdentity requestIdentity = + new APIGatewayV2ProxyRequestEvent.RequestIdentity(); + requestIdentity.setUserArn("APIGatewayV2ProxyRequestEventUserARN"); + final APIGatewayV2ProxyRequestEvent.RequestContext proxyRequestContext = + new APIGatewayV2ProxyRequestEvent.RequestContext(); + proxyRequestContext.setIdentity(requestIdentity); + apiGatewayV2ProxyRequestEvent.setRequestContext(proxyRequestContext); + + myApiGatewayV2ProxyRequestHandler.handleRequest(apiGatewayV2ProxyRequestEvent, createContext()); + final MockSpan span = mockTracer.finishedSpans().get(0); + Assert.assertEquals( + "APIGatewayV2ProxyRequestEventUserARN", span.tags().get("aws.lambda.eventSource.arn")); + Assert.assertFalse(span.tags().containsKey("http.status_code")); + } + + @Test + public void testAPIGatewayV2ProxyRequestResponseEvent() { + int expectedStatusCode = 200; + final MyApiGatewayV2ProxyRequestResponseHandler myApiGatewayV2ProxyRequestHandler = + new MyApiGatewayV2ProxyRequestResponseHandler(expectedStatusCode); + + final APIGatewayV2ProxyRequestEvent apiGatewayV2ProxyRequestEvent = + new APIGatewayV2ProxyRequestEvent(); + final APIGatewayV2ProxyRequestEvent.RequestIdentity requestIdentity = + new APIGatewayV2ProxyRequestEvent.RequestIdentity(); + requestIdentity.setUserArn("APIGatewayV2ProxyRequestEventUserARN"); + final APIGatewayV2ProxyRequestEvent.RequestContext proxyRequestContext = + new APIGatewayV2ProxyRequestEvent.RequestContext(); + proxyRequestContext.setIdentity(requestIdentity); + apiGatewayV2ProxyRequestEvent.setRequestContext(proxyRequestContext); + + myApiGatewayV2ProxyRequestHandler.handleRequest(apiGatewayV2ProxyRequestEvent, createContext()); + final MockSpan span = mockTracer.finishedSpans().get(0); + Assert.assertEquals( + "APIGatewayV2ProxyRequestEventUserARN", span.tags().get("aws.lambda.eventSource.arn")); + Assert.assertEquals(Integer.toString(expectedStatusCode), span.tags().get("http.status_code")); + } + @Test @Ignore("We would like this but there doesn't seem to be an available arn currently") public void testCloudWatchLogsEvent() { @@ -373,6 +444,55 @@ public Object doHandleRequest( } } + static class MyApiGatewayProxyRequestResponseHandler + implements TracingRequestHandler { + + private int statusCode; + + public MyApiGatewayProxyRequestResponseHandler(int statusCode) { + this.statusCode = statusCode; + } + + @Override + public APIGatewayProxyResponseEvent doHandleRequest( + APIGatewayProxyRequestEvent apiGatewayV2ProxyRequestEvent, Context context) { + APIGatewayProxyResponseEvent responseEvent = new APIGatewayProxyResponseEvent(); + responseEvent.setStatusCode(statusCode); + responseEvent.setBody("null"); + return responseEvent; + } + } + + static class MyApiGatewayV2ProxyRequestHandler + implements TracingRequestHandler { + + @Override + public Object doHandleRequest( + APIGatewayV2ProxyRequestEvent apiGatewayV2ProxyRequestEvent, Context context) { + return "null"; + } + } + + static class MyApiGatewayV2ProxyRequestResponseHandler + implements TracingRequestHandler< + APIGatewayV2ProxyRequestEvent, APIGatewayV2ProxyResponseEvent> { + + private int statusCode; + + public MyApiGatewayV2ProxyRequestResponseHandler(int statusCode) { + this.statusCode = statusCode; + } + + @Override + public APIGatewayV2ProxyResponseEvent doHandleRequest( + APIGatewayV2ProxyRequestEvent apiGatewayV2ProxyRequestEvent, Context context) { + APIGatewayV2ProxyResponseEvent responseEvent = new APIGatewayV2ProxyResponseEvent(); + responseEvent.setStatusCode(statusCode); + responseEvent.setBody("null"); + return responseEvent; + } + } + // Cloud Front static class MyCloudFrontRequestHandler implements TracingRequestHandler {