|
5 | 5 |
|
6 | 6 | package io.opentelemetry.instrumentation.awslambdaevents.v2_2;
|
7 | 7 |
|
| 8 | +import com.amazonaws.services.lambda.runtime.Context; |
| 9 | +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; |
| 10 | +import io.opentelemetry.instrumentation.awslambdacore.v1_0.AwsLambdaRequest; |
| 11 | +import io.opentelemetry.instrumentation.awslambdacore.v1_0.TracingRequestStreamWrapper; |
| 12 | +import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.ApiGatewayProxyRequest; |
| 13 | +import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.MapUtils; |
8 | 14 | import io.opentelemetry.instrumentation.awslambdacore.v1_0.internal.WrappedLambda;
|
| 15 | +import io.opentelemetry.instrumentation.awslambdaevents.v2_2.internal.SerializationUtil; |
9 | 16 | import io.opentelemetry.sdk.OpenTelemetrySdk;
|
10 |
| -import java.util.function.BiFunction; |
| 17 | +import java.io.ByteArrayInputStream; |
| 18 | +import java.io.ByteArrayOutputStream; |
| 19 | +import java.io.IOException; |
| 20 | +import java.io.InputStream; |
| 21 | +import java.io.OutputStream; |
| 22 | +import java.lang.reflect.InvocationTargetException; |
| 23 | +import java.lang.reflect.Method; |
| 24 | +import java.util.Collections; |
| 25 | +import java.util.Map; |
11 | 26 |
|
12 | 27 | /**
|
13 |
| - * Wrapper for {@link io.opentelemetry.instrumentation.awslambdacore.v1_0.TracingRequestHandler}. |
14 |
| - * Allows for wrapping a regular lambda, not proxied through API Gateway. Therefore, HTTP headers |
15 |
| - * propagation is not supported. |
| 28 | + * Wrapper for {@link com.amazonaws.services.lambda.runtime.RequestHandler} based Lambda handlers. |
16 | 29 | */
|
17 |
| -public class TracingRequestWrapper extends TracingRequestWrapperBase<Object, Object> { |
| 30 | +public class TracingRequestWrapper extends TracingRequestStreamWrapper { |
18 | 31 | public TracingRequestWrapper() {
|
19 |
| - super(TracingRequestWrapper::map); |
| 32 | + super(); |
20 | 33 | }
|
21 | 34 |
|
22 | 35 | // Visible for testing
|
23 |
| - TracingRequestWrapper( |
24 |
| - OpenTelemetrySdk openTelemetrySdk, |
25 |
| - WrappedLambda wrappedLambda, |
26 |
| - BiFunction<Object, Class<?>, Object> mapper) { |
27 |
| - super(openTelemetrySdk, wrappedLambda, mapper); |
| 36 | + TracingRequestWrapper(OpenTelemetrySdk openTelemetrySdk, WrappedLambda wrappedLambda) { |
| 37 | + super(openTelemetrySdk, wrappedLambda); |
| 38 | + } |
| 39 | + |
| 40 | + @Override |
| 41 | + protected final AwsLambdaRequest createRequest( |
| 42 | + InputStream inputStream, Context context, ApiGatewayProxyRequest proxyRequest) { |
| 43 | + Method targetMethod = wrappedLambda.getRequestTargetMethod(); |
| 44 | + Object input = LambdaParameters.toInput(targetMethod, inputStream, TracingRequestWrapper::map); |
| 45 | + return AwsLambdaRequest.create(context, input, extractHeaders(input)); |
| 46 | + } |
| 47 | + |
| 48 | + protected Map<String, String> extractHeaders(Object input) { |
| 49 | + if (input instanceof APIGatewayProxyRequestEvent) { |
| 50 | + return MapUtils.emptyIfNull(((APIGatewayProxyRequestEvent) input).getHeaders()); |
| 51 | + } |
| 52 | + return Collections.emptyMap(); |
| 53 | + } |
| 54 | + |
| 55 | + @Override |
| 56 | + protected final void doHandleRequest( |
| 57 | + InputStream input, OutputStream output, Context context, AwsLambdaRequest request) { |
| 58 | + Method targetMethod = wrappedLambda.getRequestTargetMethod(); |
| 59 | + Object[] parameters = LambdaParameters.toParameters(targetMethod, request.getInput(), context); |
| 60 | + try { |
| 61 | + Object result = targetMethod.invoke(wrappedLambda.getTargetObject(), parameters); |
| 62 | + SerializationUtil.toJson(output, result); |
| 63 | + } catch (IllegalAccessException e) { |
| 64 | + throw new IllegalStateException("Method is inaccessible", e); |
| 65 | + } catch (InvocationTargetException e) { |
| 66 | + throw (e.getCause() instanceof RuntimeException |
| 67 | + ? (RuntimeException) e.getCause() |
| 68 | + : new IllegalStateException(e.getTargetException())); |
| 69 | + } |
| 70 | + } |
| 71 | + |
| 72 | + @SuppressWarnings({"unchecked", "TypeParameterUnusedInFormals"}) |
| 73 | + // Used for testing |
| 74 | + <INPUT, OUTPUT> OUTPUT handleRequest(INPUT input, Context context) throws IOException { |
| 75 | + byte[] inputJsonData = SerializationUtil.toJsonData(input); |
| 76 | + ByteArrayInputStream inputStream = new ByteArrayInputStream(inputJsonData); |
| 77 | + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); |
| 78 | + |
| 79 | + super.handleRequest(inputStream, outputStream, context); |
| 80 | + |
| 81 | + byte[] outputJsonData = outputStream.toByteArray(); |
| 82 | + return (OUTPUT) |
| 83 | + SerializationUtil.fromJson( |
| 84 | + new ByteArrayInputStream(outputJsonData), |
| 85 | + wrappedLambda.getRequestTargetMethod().getReturnType()); |
28 | 86 | }
|
29 | 87 |
|
30 | 88 | // Visible for testing
|
31 |
| - static <T> T map(Object jsonMap, Class<T> clazz) { |
| 89 | + static <T> T map(InputStream inputStream, Class<T> clazz) { |
32 | 90 | try {
|
33 |
| - return OBJECT_MAPPER.convertValue(jsonMap, clazz); |
| 91 | + return SerializationUtil.fromJson(inputStream, clazz); |
34 | 92 | } catch (IllegalArgumentException e) {
|
35 | 93 | throw new IllegalStateException(
|
36 | 94 | "Could not map input to requested parameter type: " + clazz, e);
|
|
0 commit comments