1

Ich versuche, eine Lambda-Funktion mit einem SNS-Ereignis mit einer S3-Ereignisnutzlast aufrufen (dh S3 Put -> löst ein Ereignis veröffentlicht in einem SNS-Thema -> liefert an ein abonniertes Lambda-Funktion), aber es scheint die einzige Möglichkeit zu sein, zu den tatsächlichen S3-Ereignisinformationen zu gelangen, ist, darauf als JsonNode zuzugreifen und ich weiß, dass es eine bessere (z. B. Deserialisierung) geben muss.Lambda-Funktion empfängt Null S3-Ereignisobjekt über SNS

Ich dachte, ich könnte eine S3EventNotification meine Lambda-Funktion übernehmen haben, aufgrund der Kommentare fand ich hier:

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

Ein Helfer-Klasse, die eine stark typisierte S3 EventNotification Element gesendet zu vertritt SQS, SNS oder Lambda.

Also, wie bekomme ich die S3EventNotification als POJO?

Nachfolgend finden Sie die verschiedenen Möglichkeiten, die ich versucht habe:

public class LambdaFunction implements RequestHandler<S3EventNotification, Object>{ 

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

in Resultierende:

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

Ich habe versucht, auch die folgende (Anmerkung: JsonUtil.MAPPER gibt nur einen Jackson ObjectMapper):

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

Dies gibt das gleiche wie zuvor:

Ich kann auf die S3-Ereignisnutzlast zugreifen, indem ich einfach das SNSEvent empfange. Wenn ich jedoch versuche, die MSG-Nutzdaten in S3EventRecord oder S3EventNotification zu deserialisieren, gibt es Unterschiede in den Feldern. Ich möchte wirklich nicht manuell den JsonNode zu Fuß bis haben ...

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; 
} 

Dies gibt die folgende:

{ 
    "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"]) 

Ich bin abhängig von aws-java-sdk-s3-1.11. 77 und aws-java-sdk-sns-1.11.77.

Antwort

1

Sie sollten das SNSEvent statt S3Event behandeln, da das Lambda Ihre SNS-Ereignisse verbraucht. unter Code funktioniert für mich.

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

Beim Ausdruck der SNSMessage wird deutlich, dass sie ein serialisiertes S3Event-Objekt enthält. Egal, ich habe versucht, es zu einem POJO zu deserialisieren und da es mit dem S3Event übereinstimmen sollte, dachte ich, das sollte funktionieren, allerdings nicht aus den oben genannten Gründen. – Brooks

+0

deine erste lambadafunktion führte zum schluss, eigentlich habe ich gerade den fehler vor 2 tagen gemacht. Der obige Code funktioniert für mich. –

Verwandte Themen