1

我试图使用携带S3事件负载的SNS事件调用Lambda函数(即S3 Put - >触发发布到SNS主题的事件 - >传递给订阅Lambda函数),但似乎我能够获得实际的S3事件信息的唯一方法是以JsonNode的身份访问它,并且我知道必须有更好的(例如反序列化)。通过SNS接收空S3事件对象的Lambda函数

我真的以为我可以有我的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

代表一个强类型S3项目通知项目发送 给助手类SQS,SNS或Lambda。

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

以下是我已经尝试了各种方式:

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刚刚返回杰克逊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。

回答

1

您应该处理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()); 
     } 
    ); 
} 
+1

从打印出包含序列化S3Event对象的SNSMessage中可以明显看出。无论如何,我试图将它反序列化为一个POJO,并且因为它应该与S3Event匹配,所以我认为它应该可以工作,但这不是出于我上面概述的原因。 – Brooks

+0

你的第一个拉巴达功能导致了结论,实际上我刚刚在2天前弄错了。上面的代码适用于我。 –