gpt4 book ai didi

amazon-web-services - Lambda 函数通过 SNS 接收空 S3 事件对象

转载 作者:行者123 更新时间:2023-12-04 08:13:48 25 4
gpt4 key购买 nike

我正在尝试使用携带 S3 事件负载的 SNS 事件调用 Lambda 函数(即 S3 Put -> 触发发布到 SNS 主题的事件 -> 交付给订阅的 Lambda 函数),但它似乎是唯一的我能够获取实际 S3 事件信息的方法是将其作为 JsonNode 进行访问,我知道必须有更好的方法(例如反序列化)。

我真的认为我可以让我的 Lambda 函数接受 S3EventNotification,因为我在这里找到了评论:

https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-s3/src/main/java/com/amazonaws/services/s3/event/S3EventNotification.java

A helper class that represents a strongly typed S3 EventNotification item sent to SQS, SNS, or Lambda.

那么,我如何接收作为 POJO 的 S3EventNotification?

以下是我尝试过的各种方式:

public class LambdaFunction implements RequestHandler<S3EventNotification, Object>{

@Override
public Object handleRequest(S3EventNotification input, Context context) {
System.out.println(JsonUtil.MAPPER.writeValueAsString(input));
return null;
}
}

导致:

{
"Records": [
{
"awsRegion": null,
"eventName": null,
"eventSource": null,
"eventTime": null,
"eventVersion": null,
"requestParameters": null,
"responseElements": null,
"s3": null,
"userIdentity": null
}
]
}

我还尝试了以下方法(注意:JsonUtil.MAPPER 只返回一个 Jackson ObjectMapper):

public class LambdaFunction {
public Object handleRequest(S3EventNotification records, Context context) throws IOException {
System.out.println(JsonUtil.MAPPER.writeValueAsString(records));
return null;
}
}

这会返回与之前相同的结果:

{
"Records": [
{
"awsRegion": null,
"eventName": null,
"eventSource": null,
"eventTime": null,
"eventVersion": null,
"requestParameters": null,
"responseElements": null,
"s3": null,
"userIdentity": null
}
]
}

我可以通过简单地接收 SNSEvent 来访问 S3 事件负载,但是当我尝试将 msg 负载反序列化为 S3EventRecord 或 S3EventNotification 时,字段存在差异。我真的不想手动遍历 JsonNode...

public class LambdaFunction {
public Object handleRequest(SNSEvent input, Context context) throws IOException {
System.out.println("Records: " + JsonUtil.MAPPER.writeValueAsString(input));

for (SNSEvent.SNSRecord record : input.getRecords()) {
System.out.println("Record Direct: " + record.getSNS().getMessage());
JsonNode node = JsonUtil.MAPPER.readTree(record.getSNS().getMessage());
JsonNode recordNode = ((ArrayNode) node.get("Records")).get(0);
System.out.println(recordNode.toString());
S3EventNotification s3events = JsonUtil.MAPPER.readValue(record.getSNS().getMessage(), new TypeReference<S3EventNotification>() {});
System.out.println(s3events == null);

}
return null;
}

这将返回以下内容:

{
"eventVersion": "2.0",
"eventSource": "aws:s3",
"awsRegion": "us-east-1",
"eventTime": "2017-03-04T05:34:25.149Z",
"eventName": "ObjectCreated:Put",
"userIdentity": {
"principalId": "AWS:XXXXXXXXXXXXX"
},
"requestParameters": {
"sourceIPAddress": "<<IP ADDRESS>>"
},
"responseElements": {
"x-amz-request-id": "XXXXXXXX",
"x-amz-id-2": "XXXXXXXXXXXXX="
},
"s3": {
"s3SchemaVersion": "1.0",
"configurationId": "NotifyNewRawArticle",
"bucket": {
"name": "MYBUCKET",
"ownerIdentity": {
"principalId": "XXXXXXXXXXXXXXX"
},
"arn": "arn:aws:s3:::MYBUCKET"
},
"object": {
"key": "news\/test",
"size": 0,
"eTag": "d41d8cd98f00b204e9800998ecf8427e",
"sequencer": "0058BA51E113A948C3"
}
}
}

Unrecognized field "sequencer" (class com.amazonaws.services.s3.event.S3EventNotification$S3ObjectEntity), not marked as ignorable (4 known properties: "size", "versionId", "eTag", "key"])

我依赖于 aws-java-sdk-s3-1.11.77 和 aws-java-sdk-sns-1.11.77。

最佳答案

您应该处理 SNSEvent 而不是 S3Event,因为 lambda 会消耗您的 SNS 事件。下面的代码对我有用。

public Object handleRequest(SNSEvent request, Context context) {
request.getRecords().forEach(snsRecord -> {
System.out.println("Record Direct: " +snsRecord.getSNS().getMessage());
S3EventNotification s3eventNotifcation=S3Event.parseJson(snsRecord.getSNS().getMessage());
System.out.println(s3eventNotifcation.toJson());
}
);
}

关于amazon-web-services - Lambda 函数通过 SNS 接收空 S3 事件对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42592726/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com