2015-09-24 15 views
6

Si è tentato di inviare questo messaggio ai forum di AWS, ma sembra che il mio account sia "non ancora pronto", qualunque cosa significhi.AWS La pubblicazione SNS su una funzione Lambda registrata registra campi null

Ho impostato una funzione AWS Lambda (scritta in Java) che accetta un POJO per consentire la deserializzazione automatica di JSON. Il test JSON che sto usando è sotto e rappresenta la stringa JSON che verrà inviata dalla fonte principale del messaggio una volta che tutto è attivo e funzionante.

{"sender":"Joe", "id":1, "event":"started", "ticks":2, "time":"20150623T214256Z", "version":"1.0"} 

Questo ha funzionato perfettamente quando l'ho testato pubblicandolo dalla console "test" Lambda.

Ora sto provando ad agganciare SNS sottoscrivendo la funzione Lambda a un argomento e lo sto testando dalla console SNS. Ho provato a inviare lo stesso messaggio esatto di entrambi con "dati grezzi" (che non hanno mostrato risultati) e il JSON generato utilizzando l'opzione dati "JSON Generator" e sto correndo in un problema in cui sembra quando SNS invia il messaggio alla funzione Lambda, il POJO viene istanziato, ma viene chiamato il costruttore predefinito o il costruttore parametrizzato viene chiamato con tutti i valori nulli. In entrambi i casi, quando la funzione Lambda registra il messaggio chiamando un metodo toString() sovrascritto nel POJO, stampa nullo per tutte le variabili senza messaggi di errore. Allo stesso modo, l'argomento SNS è configurato per accedere a Cloudwatch e anch'esso non segnala alcun errore. Ottiene uno stato HTTP 202.

Ecco il messaggio JSON appena generato.

{ 
"default": "{\"sender\":\"Joe\", \"id\":1, \"event\":\"started\", \"ticks\":2, \"time\":\"20150623T214256Z\", \"version\":\"1.0\"}", 
"lambda": "{\"sender\":\"Joe\", \"id\":1, \"event\":\"started\", \"ticks\":2, \"time\":\"20150623T214256Z\", \"version\":\"1.0\"}", 
} 

Di seguito sono riportati i messaggi di registro.

tronchi di Lambda:

START RequestId: 238a0546-627d-11e5-b228-817bf2a1219a  
Received the following :: We have the following Message{sender=null, id=null, event=null, ticks=null, time=null, version=null}  
END RequestId: 238a0546-627d-11e5-b228-817bf2a1219a 
REPORT RequestId: 238a0546-627d-11e5-b228-817bf2a1219a Duration: 26.23 ms Billed Duration: 100 ms  Memory Size: 1536 MB Max Memory Used: 69 MB 

SNS tronchi:

{ "status": "SUCCESS", "notification": { "timestamp": "2015-09-24 05:28:51.079", "topicArn": "arn:aws:sns:us-east-1:256842276575:App", "messageId": "3f5c0fa1-8a50-5ce3-b7c9-41dc060212c8", "messageMD5Sum": "65a5cb6d53616bd385f72177fe98ecc2" }, "delivery": { "statusCode": 202, "dwellTimeMs": 92, "attempts": 1, "providerResponse": "{\"lambdaRequestId\":\"238a0546-627d-11e5-b228-817bf2a1219a\"}", "destination": "arn:aws:lambda:us-east-1:256842276575:function:App-Lambda-Trigger" } } 

Di seguito è riportato il codice funzione Lambda applicabile:

package com.mycompany; 

import com.amazonaws.services.lambda.runtime.Context; 
import com.amazonaws.services.lambda.runtime.LambdaLogger; 

public class LambdaHandler { 

    public void Handler(Message msg, Context context) { 
     LambdaLogger logger = context.getLogger(); 
     logger.log("Received the following :: " + msg.toString()); 
    } 
} 

.

public class Message { 
    private String sender; 
    private Integer id; 
    private String event; 
    private Integer ticks; 
    private String time; 
    private Double version; 

public Message(String sender, Integer id, String event, Integer ticks, String time, Double version) { 
    this.sender = sender; 
    this.id = id; 
    this.event = event; 
    this.ticks = ticks; 
    this.time = time; 
    this.version = version; 
} 

... getters/setters ... 

public Message() { 
} 

@Override 
public String toString() { 
    return "We have the following Message{" + "sender=" + getSender() + ", id=" + id + ", event=" + event + ", ticks=" + ticks + ", time=" + time + ", version=" + version + '}'; 
} 

Dopo aver fatto qualche scavo e guardando alcuni esempi Javascript (io non riesco a trovare alcun esempio Java di funzioni sottoscritto SNS), sembra che tutti ricevono "evento". Ho trovato nel repository Github di AWS una classe Java SNSEvent (https://github.com/aws/aws-lambda-java-libs/blob/master/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/SNSEvent.java), tuttavia non è nel Javadoc ufficiale. Nessuna documentazione di AWS sono stata in grado di trovare il documento con una funzione di Java Lambda impostata per ricevere un POJO deserializzato (che non posso credere sia così raro) e non riesco a trovare nulla che specifica quale tipo di oggetto viene inviato dal Argomento SNS per la funzione Lambda, se così non dovrei aspettarmi il tipo di POJO.

Qualcuno può chiarire, quale tipo di oggetto dovrei avere la mia funzione Lambda si aspetta di ricevere? Qualcuno può fornire qualche codice di esempio?

Qualsiasi aiuto sarebbe apprezzato.

EDIT 1

ho modificato la mia funzione di accettare SNSEvent e il contesto degli oggetti, per un suggerimento e la mia funzione tiri la seguente eccezione:

Error loading method handler on class com.app.LambdaHandler: class java.lang.NoClassDefFoundError java.lang.NoClassDefFoundError: com/amazonaws/services/lambda/runtime/events/SNSEvent 
at java.lang.Class.getDeclaredMethods0(Native Method) 
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) 
at java.lang.Class.privateGetPublicMethods(Class.java:2902) 
at java.lang.Class.getMethods(Class.java:1615) Caused by: java.lang.ClassNotFoundException: com.amazonaws.services.lambda.runtime.events.SNSEvent 
at java.net.URLClassLoader.findClass(URLClassLoader.java:381) 
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) 
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) 

Come se l'ambiente di runtime non riconosce SNSEvent ?

risposta

8

Ci sono due cose che penso si dovrebbe cambiare:

  1. La classe messaggio non segue la prevista Lambda POJO format di GetX di accesso/SETX che Lambda utilizzerà per deserializzare l'oggetto evento.
  2. Se il tuo evento proviene da SNS, seguirà il formato di oggetto SNS generico piuttosto che il tuo formato personalizzato. Dovrai ispezionare l'evento SNS per estrarre i tuoi dati personalizzati nello Message, quindi analizzarlo separatamente. Dai un'occhiata al modello di eventi SNS in Lambda in Azioni> Configura evento di esempio.

Ecco una funzione Lambda di esempio per la gestione di un evento SNS in Java, utilizzando AWS Lambda Java Support Libraries.

package example; 

import com.amazonaws.services.lambda.runtime.Context; 
import com.amazonaws.services.lambda.runtime.LambdaLogger; 
import com.amazonaws.services.lambda.runtime.events.SNSEvent; 

public class SNSEventHandler { 

    public String handleSNSEvent(SNSEvent event, Context context) { 
     LambdaLogger logger = context.getLogger(); 
     for (SNSEvent.SNSRecord record : event.getRecords()) { 
      SNSEvent.SNS sns = record.getSNS(); 
      logger.log("handleSNSEvent received SNS message " + sns.getMessage()); 
     } 
     return "handleSNSEvent finished"; 
    } 

} 

Il SNSEvent data model suggerisce che più eventi potrebbero arrivare al gestore, allo stesso tempo, in modo che il campione di iterazione mostra su di loro piuttosto che assumere uno. Non l'ho ancora visto in pratica, ma il mio utilizzo è stato a basso volume.

+0

Ho trovato la stessa classe SNSEvent anche su github, ma non riuscivo a trovarla da nessuna parte nel Javadoc ....? E non ci sono riferimenti a SNSEvent nei documenti AWS, quindi sono confuso su come qualcuno dovrebbe trovarlo. Farò un tentativo e ti faccio sapere. Grazie! – Brooks

+0

Ho modificato la mia funzione per accettare gli oggetti SNSEvent e Context e, all'esecuzione, registra l'esenzione di seguito. Errore caricamento metodo Gestore sulla classe com.app.LambdaHandler: classe java.lang.NoClassDefFoundError java.lang.NoClassDefFoundError: com/amazonaws/services/lambda/runtime/events/SNSEvent – Brooks

+0

Sembra che il runtime non stia trovando il compilato File .class per i pacchetti com.amazonaws.services.lambda.runtime. * nel tuo file jar. Li stai includendo? – James

Problemi correlati