2
votes

I have a use case of pushing SNS notifications from Amazon lambda. I have written the following code, with the IAM role having the permission to invoke SNS. Even with the Kenesis trigger, this Lambda function is unable to send any notification to SNS. I confirmed this by, subscribing my email id to the SNS.

[EDIT]: Just a follow up question. I now need to query DynamoDB and based on the output, need to call different end point of SNS. Now, when I query DynamoDB, the execution stops after DynamoDB query and not even progressing for SNS checks.

Following is my lambda function code.

console.log('Loading function');
var AWS = require('aws-sdk');
exports.handler = function(event, context) {
event.Records.forEach(function(record) {
    //var payload = new Buffer(record.kinesis.data, 'base64').toString('ascii');
    var payload = record.kinesis.data;
    console.log('Decoded payload:', payload);

    var dynamodb = new AWS.DynamoDB();
    var dynamodb_params = {
        Key: {
            dataSource: { 
                S: payload
            }
        },
        TableName: 'TableName',
        AttributesToGet: [
            'attribute' // ...
        ],
        ConsistentRead: false,
    };
    var sns_endpoint = null;
    dynamodb.getItem(dynamodb_params, function(err, data) {
        if (err) {
            console.log(err.stack);
            context.done(err, 'Errors while querying dynamodb!');  
        } else {
            console.log(data);
            sns_endpoint = data.Item.sns.S;
            console.log("Result= " + data);
            console.log("Item= " + data.Item);
            console.log("sns= " + data.Item.sns);
            console.log("value= " + data.Item.sns.S);
            console.log("sns_endpoint= " + sns_endpoint);
            context.done(null, 'Querying dynamodb succeeded!');
        }
    });
    if( sns_endpoint != null ) {
        console.log("sns_endpoint= " + sns_endpoint);
        var sns_params = {
            Message: payload,
            Subject: 'Event Notification From Lambda',
            TopicArn: sns_endpoint
        };
        var sns = new AWS.SNS();
        sns.publish(sns_params, function(err, data) {
            if (err) {
                console.log(err.stack);
                context.done(err, 'Errors while putting to SNS!');  
            } else {
                console.log(data);
                context.done(null, 'Putting to SNS succeeded!');
            }
        });
    }
});

};

1
Would you please share the log output?James

1 Answers

4
votes

You are calling an asynchronous function, sns.publish(), within a forEach loop. Then you are immediately calling context.succeed(). As soon as context.succeed, context.fail or context.done are called, your Lambda function will exit. You need to modify your code to only call one of those after all asynchronous function calls have completed.