Skip to content

[BUG] HttpMaid with route config for GET / combined with template.yml function config Path: / SHOULD work with sam local start-api #86

@lestephane

Description

@lestephane

Describe the bug
If i'm a first time user doing something that feels like it should work, it should work.

In this example, the java code configures the / route, and the template.yml mounts the
lambda onto /. Upon invocation, it fails because of AwsLambdaEndpoint's expectation
that there absolutely be a path parameter named "path":

AwsLambdaEndpoint.java:59

final Map<String, String> pathParameters = event.getPathParameters();
final String path = pathParameters.get("path");  // NullPointerException here
  • using /{path+} does not help (see first comment)
  • using a deeper static path such as /hello does not help (see second comment)

HttpMaid should play nice with sam local start-api, or at the very least, we need to have one working workaround. This will otherwise trip first time users, who initially want to try their function locally without creating an AWS Lambda first.

To Reproduce
Main.java

public final class Main implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
  private static final AwsLambdaEndpoint ADAPTER = awsLambdaEndpointFor(httpMaidConfig());

  @Override
  public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent request, Context ctx) {
    return ADAPTER.delegate(request, ctx);
  }

  public static void main(String[] args) {
    final int port = 8080;
    final HttpMaid httpMaid = httpMaidConfig();
    final QuantumMaid quantumMaid = QuantumMaid.quantumMaid()
        .withHttpMaid(httpMaid)
        .withLocalHostEndpointOnPort(port);
    quantumMaid.runAsynchronously();
  }

  private static HttpMaid httpMaidConfig() {
    final HttpMaid httpMaid = HttpMaid.anHttpMaid()
        .get("/", (request, response) -> response.setBody("Hello World!"))
        .build();
    return httpMaid;
  }
}

template.yml

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: .
      Handler: de.quantummaid.tutorials.Main::handleRequest
      Runtime: java11
      MemorySize: 512
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /
            Method: get
$ curl -vS localhost:3000
* Rebuilt URL to: localhost:3000/
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.47.0
> Accept: */*
> 
* HTTP 1.0, assume close after body
< HTTP/1.0 502 BAD GATEWAY
< Content-Type: application/json
< Content-Length: 36
< Server: Werkzeug/0.16.0 Python/3.7.4
< Date: Sat, 06 Jun 2020 10:47:50 GMT
< 
{"message":"Internal server error"}
* Closing connection 0

sam local

$ sam local start-api --skip-pull-image
Mounting HelloWorldFunction at http://127.0.0.1:3000/ [GET]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2020-06-06 13:47:42  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
Invoking de.quantummaid.tutorials.Main::handleRequest (java11)
Requested to skip pulling images ...

Mounting /home/lestephane/GitRepos/quantummaid-tutorials/aws-lambda/step3/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container
START RequestId: 0d2b3e27-d10a-1f13-fb78-ae306620dc8a Version: $LATEST
10:47:50.182 [main] ERROR de.quantummaid.httpmaid.HttpMaid - Exception in endpoint request handling
java.lang.NullPointerException: null
	at de.quantummaid.httpmaid.awslambda.AwsLambdaEndpoint.lambda$delegate$0(AwsLambdaEndpoint.java:59)
	at de.quantummaid.httpmaid.HttpMaid.handleRequest(HttpMaid.java:77)
	at de.quantummaid.httpmaid.HttpMaid.handleRequestSynchronously(HttpMaid.java:66)
	at de.quantummaid.httpmaid.awslambda.AwsLambdaEndpoint.delegate(AwsLambdaEndpoint.java:54)
	at de.quantummaid.tutorials.Main.handleRequest(Main.java:18)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at lambdainternal.EventHandlerLoader$PojoMethodRequestHandler.handleRequest(EventHandlerLoader.java:280)
	at lambdainternal.EventHandlerLoader$PojoHandlerAsStreamHandler.handleRequest(EventHandlerLoader.java:197)
	at lambdainternal.EventHandlerLoader$2.call(EventHandlerLoader.java:897)
	at lambdainternal.AWSLambda.startRuntime(AWSLambda.java:228)
	at lambdainternal.AWSLambda.startRuntime(AWSLambda.java:162)
	at lambdainternal.AWSLambda.main(AWSLambda.java:157)
object must not be null: de.quantummaid.httpmaid.util.CustomTypeValidationException
de.quantummaid.httpmaid.util.CustomTypeValidationException: object must not be null
	at de.quantummaid.httpmaid.util.CustomTypeValidationException.customTypeValidationException(CustomTypeValidationException.java:32)
	at de.quantummaid.httpmaid.util.Validators.validateNotNull(Validators.java:33)
	at de.quantummaid.httpmaid.endpoint.SynchronizationWrapper.getObject(SynchronizationWrapper.java:42)
	at de.quantummaid.httpmaid.HttpMaid.handleRequestSynchronously(HttpMaid.java:70)
	at de.quantummaid.httpmaid.awslambda.AwsLambdaEndpoint.delegate(AwsLambdaEndpoint.java:54)
	at de.quantummaid.tutorials.Main.handleRequest(Main.java:18)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)

END RequestId: 0d2b3e27-d10a-1f13-fb78-ae306620dc8a
REPORT RequestId: 0d2b3e27-d10a-1f13-fb78-ae306620dc8a	Init Duration: 1286.63 ms	Duration: 52.19 ms	Billed Duration: 100 ms	Memory Size: 512 MB	Max Memory Used: 86 MB	
Lambda returned empty body!
Invalid API Gateway Response Keys: {'errorType', 'stackTrace', 'errorMessage'} in {'errorType': 'de.quantummaid.httpmaid.util.CustomTypeValidationException', 'errorMessage': 'object must not be null', 'stackTrace': ['de.quantummaid.httpmaid.util.CustomTypeValidationException.customTypeValidationException(CustomTypeValidationException.java:32)', 'de.quantummaid.httpmaid.util.Validators.validateNotNull(Validators.java:33)', 'de.quantummaid.httpmaid.endpoint.SynchronizationWrapper.getObject(SynchronizationWrapper.java:42)', 'de.quantummaid.httpmaid.HttpMaid.handleRequestSynchronously(HttpMaid.java:70)', 'de.quantummaid.httpmaid.awslambda.AwsLambdaEndpoint.delegate(AwsLambdaEndpoint.java:54)', 'de.quantummaid.tutorials.Main.handleRequest(Main.java:18)', 'java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)', 'java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)', 'java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)', 'java.base/java.lang.reflect.Method.invoke(Unknown Source)']}
<class 'samcli.local.apigw.local_apigw_service.LambdaResponseParseException'>
2020-06-06 13:47:50 127.0.0.1 - - [06/Jun/2020 13:47:50] "GET / HTTP/1.1" 502 -

Expected behavior
No error, HTTP 200 response with Hello World

Environment description

  • project version used:
        <dependency>
            <groupId>de.quantummaid.quantummaid.packagings</groupId>
            <artifactId>quantummaid-essentials</artifactId>
            <version>1.0.50</version>
        </dependency>
        <dependency>
            <groupId>de.quantummaid.httpmaid.integrations</groupId>
            <artifactId>httpmaid-awslambda</artifactId>
            <version>0.9.61</version>
        </dependency>
  • Java version used: 11

Additional context
Workaround this problem by adding /{path+}.

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions