java - 在 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 => {[]}
我尝试过的事情
- 将接口的输入更改为
Void bar(Map<String, Object> event)
并调用 lambda 这样bar(ImmutableMap.of("Records", event.getRecords())
它会调用 lambda,但会出现以下错误:
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)
不知道这里出了什么问题?
解决方案
这里有几件事,
- 正如Balu Vyamajala提到的以匹配记录格式。
- 使用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
推荐阅读
- python - TensorFlow中是否有任何功能相当于python reduce?
- c# - 如何在 C# 中将空格/空值分配给二维数组
- azure - Azure Web App For Linux 的文件夹权限
- ssas - MDX 中的案例陈述
- php - 到达 PHP 对象子元素
- javascript - 我们可以处理 adf 托管 bean 中的引发应用程序错误吗
- python - 如何在 Pandas 中加载由键:值对组成的 CSV 文件
- c# - MethodInterceptionAspect 的替代方案
- python - 允许使用护身符从烧瓶中的单条路线中获取 iframe
- java - 3层数据库。如何将 3 个实体相互关联?