SNS Trigger Lambda
Amazon Simple Notification Service (Amazon SNS) is a web service that makes it easy to set up, operate, and send notifications from the cloud.
Description

We’ll show how you can invoke an AWS Lambda through an SNS subscription using LocalStack. When Amazon SNS invokes a Lambda function asynchronously, Lambda returns a 202 HTTP status code back to Amazon SNS. The status code shows that Lambda has accepted the message for later processing. For more information, see Asynchronous invocation.
Prerequisites
- JDK 21
- Maven 3.8.5+
- LocalStack
- Docker - for running LocalStack
- AWS CLI and awslocal
Run LocalStack
version: '3.8'
services:
localstack:
image: localstack/localstack
container_name: localstack_main
ports:
- "4566-4599:4566-4599"
environment:
- SERVICES=sns,s3,sqs,dynamodb,ses,lambda,logs,stepfunctions
- DYNAMODB_SHARE_DB=1
- DEBUG=1
- DATA_DIR=/tmp/localstack/data
- DOCKER_HOST=unix:///var/run/docker.sock
volumes:
- "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack"
- "/var/run/docker.sock:/var/run/docker.sock"
Create Lambda
Source Code: https://github.com/ZbCiok/zjc-examples/tree/main/aws/aws/lambda/sns-trigger-lambda
-
Project Structure
.
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ ├── Main.java
│ │ └── SnsRequestHandler.java
│ └── resources
└── test
└── java
-
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>sns-trigger-lambda</artifactId>
<version>0.0.1</version>
<properties>
<encoding>UTF-8</encoding>
<project.build.sourceEncoding>${encoding}</project.build.sourceEncoding>
<project.reporting.outputEncoding>${encoding}</project.reporting.outputEncoding>
<java.version>21</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-events</artifactId>
<version>3.11.4</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.34</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
-
SnsRequestHandler.java
package com.example;
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.util.List;
import com.amazonaws.services.lambda.runtime.events.SNSEvent.SNSRecord;
import lombok.extern.java.Log;
import java.util.Iterator;
@Log
public class SnsRequestHandler implements RequestHandler<SNSEvent, Boolean> {
LambdaLogger logger;
@Override
public Boolean handleRequest(SNSEvent event, Context context) {
log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
logger = context.getLogger();
List<SNSRecord> records = event.getRecords();
if (!records.isEmpty()) {
Iterator<SNSRecord> recordsIter = records.iterator();
while (recordsIter.hasNext()) {
processRecord(recordsIter.next());
}
}
return Boolean.TRUE;
}
public void processRecord(SNSRecord record) {
try {
String message = record.getSNS().getMessage();
logger.log("message: " + message);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
-
Deploy Lambda Function
-
mvn clean package
- Create Function
awslocal lambda create-function \
--region us-east-1 \
--function-name localstack-lambda-sns \
--runtime java21 \
--zip-file fileb://sns-trigger-lambda-0.0.1.jar \
--handler com.example.SnsRequestHandler \
--role arn:aws:iam::000000000000:role/example-lambda-noop-role \
--timeout 120- zip-file fileb://localstack-lambda-sns-0.0.1.jar - generated by mvn clean package
-
SNS Create a topic
awslocal sns create-topic --name example-topic --region us-east-1
awslocal sns list-topics
{
"Topics": [
{
"TopicArn": "arn:aws:sns:us-east-1:000000000000:example-topic"
}
]
}
Creating a subscription
Let’s create a subscription on the example-topic. This will trigger the Lambda when we publish an event to the topic.
awslocal sns subscribe \
--region us-east-1 \
--protocol lambda \
--topic-arn arn:aws:sns:us-east-1:000000000000:example-topic \
--notification-endpoint arn:aws:lambda:us-east-1:000000000000:function:localstack-lambda-sns
awslocal sns list-subscriptions
{
"Subscriptions": [
{
"SubscriptionArn": "arn:aws:sns:us-east-1:000000000000:example-topic:ae242544-2b1a-4ba8-a324-a024b73bc1cf",
"Owner": "000000000000",
"Protocol": "lambda",
"Endpoint": "arn:aws:lambda:us-east-1:000000000000:function:localstack-lambda-sns",
"TopicArn": "arn:aws:sns:us-east-1:000000000000:example-topic"
}
]
}
Publish a SNS event & Invoke the Lambda
Publish an event to the topic:
awslocal sns publish \
--region us-east-1 \
--topic-arn arn:aws:sns:us-east-1:000000000000:example-topic \
--message "Hello Lambda..........!"
Verify if the Lambda was invoked
Docker Log:
...
localstack_main | 2024-09-26T07:24:51.088 DEBUG --- [ns:$LATEST_0] l.s.l.i.version_manager : [localstack-lambda-sns-43f017bb-ee5d-49c4-a5b6-922da7d48ee5] Sep 26, 2024 7:24:51 AM com.example.SnsRequestHandler handleRequest
localstack_main | 2024-09-26T07:24:51.088 DEBUG --- [ns:$LATEST_0] l.s.l.i.version_manager : [localstack-lambda-sns-43f017bb-ee5d-49c4-a5b6-922da7d48ee5] INFO: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
localstack_main | 2024-09-26T07:24:51.088 DEBUG --- [ns:$LATEST_0] l.s.l.i.version_manager : [localstack-lambda-sns-43f017bb-ee5d-49c4-a5b6-922da7d48ee5] message: Hello Lambda..........!END RequestId: 43f017bb-ee5d-49c4-a5b6-922da7d48ee5
...
Notice:
INFO: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
message: Hello Lambda..........!
localstack-main | 2024-09-20T10:38:43.258 INFO --- [et.reactor-1] localstack.request.http /
: POST /_localstack_lambda/537e999fe486e7d46879e3fafcf1dc73/invocations/bb479d30-62d8-40b9-8798-5f393c2a9644/response => 202
response => 202
For asynchronous invocation, Lambda places the event in a queue and returns a success response without additional information. A separate process reads events from the queue and sends them to your function.
📄️ Lambda Handler
(example)
📄️ The First Lambda Example
lamdba-handler
📄️ SNS Trigger Lambda
Amazon Simple Notification Service (Amazon SNS) is a web service that makes it easy to set up, operate, and send notifications from the cloud.
📄️ S3 Trigger Lambda
Description
📄️ Lambda Person Request DynamoDB
Description