Search code examples
javadependency-injectionaws-lambdajersey

Supply lambda context to Jersey resource


I'm using aws-serverless-java-container to wrap a Jersey service in a AWS Lambda. I decided to use function alias to have a "test" and "prod" stage that eventually points to different versions of the lambda function.

I need to select some properties in a .properties file based on that alias, basically because I need to talk to a "test" or "prod" DB or use a different endpoint to invoke an external web service.

For such purpose I need to invoke the method getInvokedFunctionArn of the Context object. Unfortunately the Jersey resource is not aware of such context by default.

Below a sample resource:

@Path("/pet")
public class PetResource {

    @POST
    @Path("/")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.WILDCARD)
    public Response createPet() {
        // how to call getInvokedFunctionArn from Lambda context object?
        return Response.status(200).entity("{'result': 'success'}").build();
    }
}

How can I enable the Jersey resource to have the invoked ARN? Can I inject it?

The lambda handler is defined as:

public class PetLambdaHandler implements RequestStreamHandler {

    private static final ResourceConfig jerseyApplication = new ResourceConfig().register(PetResource.class)
            .register(JacksonFeature.class);

    private static final JerseyLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler = JerseyLambdaContainerHandler
            .getAwsProxyHandler(jerseyApplication);

    @Override
    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
        handler.proxyStream(inputStream, outputStream, context);
    }
}

Solution

  • You cannot inject the Lambda context automatically. However, you can retrieve it form the ContainerRequestContext object. The serverless-java-container framework adds it as a request property.

    You can probably do something like this (have not tested the code):

    @GET
    public String testLambdaContext(@Context ContainerRequestContext containerRequest) {
       Context lambdaContext =
           (Context) containerRequest.getProperty(RequestReader.LAMBDA_CONTEXT_PROPERTY);
       return lambdaContext.getInvokedFunctionArn()
    }