Lambda和SNS与Spring的集成

4

这是我在Lambda中处理SNS事件的方式:

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.SNSEvent;

public class SnsHandler implements RequestHandler<SNSEvent, Object> {

    public Object handleRequest(SNSEvent event, Context context) {
        System.out.println("sns event");
        System.out.println(event.getRecords().get(0).getSNS().getMessage());
        return null;
    }
}

我已经有了一个使用API网关HTTP请求与SpringLambdaContainerHandler配合工作的Spring应用程序。这是我如何将其与lambda集成:

import com.amazonaws.serverless.exceptions.ContainerInitializationException;
import com.amazonaws.serverless.proxy.internal.model.AwsProxyRequest;
import com.amazonaws.serverless.proxy.internal.model.AwsProxyResponse;
import com.amazonaws.serverless.proxy.spring.SpringLambdaContainerHandler;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.maciejsobala.aws.webpush.AwsWebPushApp;

public class HttpHandler implements RequestHandler<AwsProxyRequest, AwsProxyResponse> {

    SpringLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;
    public AwsProxyResponse handleRequest(AwsProxyRequest awsProxyRequest, Context context) {

        awsProxyRequest.setPath("/" + awsProxyRequest.getPathParameters().get("proxy")); //because I am using {proxy} in my API gateway
        if (handler == null) {
            try {
                handler = SpringLambdaContainerHandler.getAwsProxyHandler(AwsWebPushApp.class);
            } catch (ContainerInitializationException e) {
                e.printStackTrace();
                return null;
            }
        }
        return handler.proxy(awsProxyRequest, context);
    }
}

现在我希望能够在SnsHandler中重用我的Spring应用程序(其中包含一些存储库和其他逻辑)。
我的第一种方法是重用与HttpHandler类似的代码(如果可以的话,我想创建一个单独的端点用于sns操作,并以某种方式保护它,只能从SnsHandler中执行)。
public class SnsHandler implements RequestHandler<SNSEvent, Object> {

    SpringLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;
    AwsProxyRequest awsProxyRequest = new AwsProxyRequest();
    ApiGatewayRequestContext requestContext = new ApiGatewayRequestContext();
    ApiGatewayRequestIdentity identity = new ApiGatewayRequestIdentity();

    {
        awsProxyRequest.setPath("/ping");
        awsProxyRequest.setHttpMethod("GET");
        identity.setSourceIp("someIp");
        requestContext.setIdentity(identity);
        awsProxyRequest.setRequestContext(requestContext);
    }

    public Object handleRequest(SNSEvent event, Context context) {
        System.out.println("sns event");
        System.out.println(event.getRecords().get(0).getSNS().getMessage());


        AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
        applicationContext.register(AwsWebPushApp.class);


        if (handler == null) {
            try {
                handler = SpringLambdaContainerHandler.getAwsProxyHandler(AwsWebPushApp.class);
            } catch (ContainerInitializationException e) {
                e.printStackTrace();
                return null;
            }
        }
        handler.proxy(awsProxyRequest, context);
        return null;
    }
}

不幸的是,我得到了

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
... some stack trace...
Caused by: java.lang.NullPointerException
at org.springframework.web.util.UrlPathHelper.getRemainingPath(UrlPathHelper.java:245)
...rest of the stack trace...

我有两个问题:

  1. 如何正确地将SNS与Spring应用程序集成到Lambda函数中(我正在尝试实现的只是一个解决方法)?
  2. 如果没有更好的方法,如何获取给定异常的原始信息。换句话说:如何适当地伪造http请求?

我查看了http://cloud.spring.io/spring-cloud-aws/spring-cloud-aws.html,但据我所知,它不适用于Lambda环境。


{btsdaf} - Sanjeev Dhiman
如果你最终解决了这个问题,欢迎分享!谢谢。 - ImtiazeA
1个回答

0
要在AWS Lambda中从非HTTP触发器运行Spring应用程序,我建议查看Spring Cloud Functions项目。
这将为您提供带有Lambda函数的Spring支持,该函数可以通过SNS事件触发。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接