Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to process an SNS message in AWS Lambda written in Java?

I have a few lambdas working together through SNS. One lambda receives a request and send data to SNS. Another lambda is subscribed to SNS. It was easy to do in JavaScript as the incoming message just an JS object. Now I am rewriting the lambda to Java. I am looking for the type to use in the handler.

Here's what the lambda looks like. SNSMessage is the placeholder for the type.

public class ArchiveRequestHandler implements RequestHandler<SNSMessage?, Void> {

    @Override public Void handleRequest(SNSMessage? input, Context context) {
        // do something with the message
        return null;
    }
}

This is how an example message looks like:

{
  "Records": [
    {
      "EventVersion": "1.0",
      "EventSubscriptionArn": "arn:aws:sns:EXAMPLE",
      "EventSource": "aws:sns",
      "Sns": {
        "SignatureVersion": "1",
        "Timestamp": "1970-01-01T00:00:00.000Z",
        "Signature": "EXAMPLE",
        "SigningCertUrl": "EXAMPLE",
        "MessageId": "1234567-ee98-5cb9-9903-4c221d41eb5e",
        "Message": "Hello from SNS!",
        "MessageAttributes": {
          "Test": {
            "Type": "String",
            "Value": "TestString"
          },
          "TestBinary": {
            "Type": "Binary",
            "Value": "TestBinary"
          }
        },
        "Type": "Notification",
        "UnsubscribeUrl": "EXAMPLE",
        "TopicArn": "arn:aws:sns:EXAMPLE",
        "Subject": "TestInvoke"
      }
    }
  ]
}

Now I am sure I can create my own type to parse this, but I was hoping there is a more standard way of doing this. However I haven't found anything in the lambda nor SNS SDK dependencies that looks like this object.

like image 617
MartinTeeVarga Avatar asked Mar 22 '17 21:03

MartinTeeVarga


2 Answers

Thanks to the comments by @dnault and @notionquest I found that this object is part of the aws-lambda-java-events library. I added the dependency:

compile 'com.amazonaws:aws-lambda-java-events:1.3.0'

And now I can do:

public class ArchiveRequestHandler implements RequestHandler<SNSEvent, Void> {

    @Override public Void handleRequest(SNSEvent input, Context context) {
        // do something with the message
        return null;
    }
}
like image 106
MartinTeeVarga Avatar answered Nov 09 '22 21:11

MartinTeeVarga


The following Lambda code processes the SNS input message/s:

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

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

public class LogEvent implements RequestHandler<SNSEvent, Object> {

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss");

    public Object handleRequest(SNSEvent request, Context context){

        String timeStamp = sdf.format(new Date());
        LambdaLogger logger = context.getLogger();

        logger.log("-------------------------Invocation started: --------------" + timeStamp);
        List<SNSEvent.SNSRecord> snsRecordList = request.getRecords();
        if ( snsRecordList != null ){
            SNSEvent.SNS recordSNS = null;
            for ( SNSEvent.SNSRecord snsRecord : snsRecordList ) {
                recordSNS = snsRecord.getSNS();
                logger.log(
                     "Subject:[" + recordSNS.getSubject() + "]" +
                            "Arn:[" + recordSNS.getTopicArn() + "]" +
                             "attribs:[" + recordSNS.getMessageAttributes() + "]" +
                             "message:[" + recordSNS.getMessage() + "]" );
            }//for
        }

        timeStamp = sdf.format(new Date());
        logger.log("-------------------------Invocation completed: -------------" + timeStamp);
        return null;
    }
}
like image 20
ylev Avatar answered Nov 09 '22 20:11

ylev