首页 > 解决方案 > 在 java 中使用 s3 事件手动调用 lambda

问题描述

有一个实现 RequestHandler<S3Event, Void> 并拥有处理程序的 lambdaVoid handleRequest(S3Event event, Context context) {log.info(" Event => " + event)....}

S3Event这是类型com.amazonaws.services.lambda.runtime.events.S3Event;

尝试手动调用 lambda 而不将任何数据上传到 s3。因此使用LambdaInvokerFactory创建 lambda 客户端和 lambda 接口为:

public interface Lambdas {

        @LambdaFunction(functionName = "Foo)
        Void bar(S3Event event);
    }

S3EventNotification.S3EventNotificationRecord ( of type com.amazonaws.services.lambda.runtime.events.S3EventNotification) 使用参考手动创建。创建后在本地记录S3Event打印如下:

{
    "Records": [
        {
            "records": [
                {
                    "awsRegion": "us-west-2",
                    "eventName": "ObjectCreated:Put",
                    "eventSource": "aws:s3",
                    "eventTime": {
                        "era": 1,
                        "dayOfYear": 71,
                        "year": 2021,
                        "dayOfMonth": 12,
                        "dayOfWeek": 5,
                        "weekyear": 2021,
                        "weekOfWeekyear": 10,
                        "monthOfYear": 3,
                        "millisOfDay": 0,
                        "yearOfCentury": 21,
                        "centuryOfEra": 20,
                        "millisOfSecond": 0,
                        "yearOfEra": 2021,
                        "secondOfMinute": 0,
                        "secondOfDay": 0,
                        "minuteOfHour": 0,
                        "minuteOfDay": 0,
                        "hourOfDay": 0,
                        "millis": 1615536000000,
                        "zone": {
                            "fixed": false,
                            "uncachedZone": {
                                "fixed": false,
                                "cachable": true,
                                "id": "America/Los_Angeles"
                            },
                            "id": "America/Los_Angeles"
                        },
                        "chronology": {
                            "zone": {
                                "fixed": false,
                                "uncachedZone": {
                                    "fixed": false,
                                    "cachable": true,
                                    "id": "America/Los_Angeles"
                                },
                                "id": "America/Los_Angeles"
                            }
                        },
                        "afterNow": false,
                        "beforeNow": true,
                        "equalNow": false
                    },
                    "eventVersion": "2.0",
                    "requestParameters": {
                        "sourceIPAddress": "127.0.0.1"
                    },
                    "responseElements": {
                        "xAmzId2": "Foo",
                        "xAmzRequestId": "Bar"
                    },
                    "s3": {
                        "configurationId": "Foo",
                        "bucket": {
                            "name": "Foo",
                            "ownerIdentity": {
                                "principalId": "arn:aws:iam::Foo"
                            },
                            "arn": "arn:aws:s3::Foo"
                        },
                        "object": {
                            "key": "FooBar.txt",
                            "size": 10,
                            "eTag": "Foo",
                            "versionId": "Foo",
                            "sequencer": "Foo",
                            "urlDecodedKey": "FooBar.txt",
                            "sizeAsLong": 10
                        },
                        "s3SchemaVersion": "1.0"
                    },
                    "userIdentity": {
                        "principalId": "arn:aws:iam::Foo"
                    }
                }
            ]
        }
    ]
}

但是在调用 bar(S3Event) 时,它会调用 lambda 但日志将其显示为空:

Event => {[]} 

我尝试过的事情

An error occurred during JSON parsing: java.lang.RuntimeException
java.lang.RuntimeException: An error occurred during JSON parsing
Caused by: lambdainternal.util.ReflectUtil$ReflectException: java.lang.reflect.InvocationTargetException
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
Caused by: java.lang.IllegalArgumentException: Invalid format: "{"year":2021,"dayOfYear":71,"equ..."
    at org.joda.time.format.DateTimeFormatter.parseDateTime(Unknown Source)
    at org.joda.time.DateTime.parse(Unknown Source)
    at org.joda.time.DateTime.parse(Unknown Source)
    at com.amazonaws.services.s3.event.S3EventNotification$S3EventNotificationRecord.<init>(S3EventNotification.java:386)
    at com.amazonaws.services.s3.event.S3EventNotification$S3EventNotificationRecord.<init>(S3EventNotification.java:355)
    ... 4 more

这是创建记录的方式:

return new S3EventNotification.S3EventNotificationRecord(
            region,
            EVENT_NAME,
            EVENT_SOURCE,
            DateTime.now().toString(),
            EVENT_VERSION,
            new S3EventNotification.RequestParametersEntity(SOURCE_IP_ADDRESS),
            new S3EventNotification.ResponseElementsEntity(
                RandomStringUtils.randomAlphanumeric(SIZE),
                RandomStringUtils.randomAlphanumeric(SIZE)
            ),
            s3Entity,
            getUserIdentityEntity(accountId)

不知道这里出了什么问题?

标签: javaamazon-web-servicesamazon-s3aws-lambda

解决方案


这里有几件事,

  1. 正如Balu Vyamajala提到的以匹配记录格式。
  2. 使用3.5作为依赖项,它将字段创建为对象,而不是在调用 lambda 时eventTime抛出的字符串。com.amazonaws.services.lambda.invoke.LambdaFunctionException: Invalid format: "{"year":2019,"dayOfYear":246,"eq...使用 创建的2.8eventTime:2019-09-03T19:37:27.192Z解决了该问题。

当前界面。

@LambdaFunction(functionName = Foo)
        Void Bar(S3Event payload);

但是,S3EventNotificationRecord不推荐使用构造函数。您可以以这种格式创建json文档并用于获取记录。S3EventNotification.parseJson


推荐阅读