Not able to fetch data from dynamodb from lambda function - node.js

I am trying to fetch data from dynamodb from my lambda.I have written this code
exports.handler = async (event) => {
// TODO implement
var AWS = require('aws-sdk');
AWS.config.update({region: 'ap-south-1'});
var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
var params = {
TableName: 'my_table',
Key: {
'serial_number': {S: '17AB-574C-C1'}
},
};
ddb.getItem(params, function(err, data) {
if (err) {
console.log("Error", err);
} else {
console.log("Success", data.Item);
console.log(data);
}
});
};
This code works fine when I run locally but I get a null response when I run it on lambda.My lambda has dynamoDbfullAccess policy attached to it. Can anyone tell me what could be the reason?

Related

How to get data from an json file in aws-lambda using node js

I am trying to read data from an json file in a lambda function using node js. Unable to retrieve the data. getting null response. My lambda function code as follows:
var AWS = require('aws-sdk');
AWS.config.update({region: 'us-east-2'});
const s3 = new AWS.S3({apiVersion: '2006-03-01'});
exports.handler = async function(event, context, callback) {
var bucketParams = {
Bucket : 'sample-bucket',
Key: 'employee.json'
};
s3.getObject(bucketParams, function(err, data) {
if (err) {
console.log("Error", err);
} else {
callback(null, data.Body.toString());
}
});
};
Response:
null
Since you are returning using callback, you should not use asnyc:
var AWS = require('aws-sdk');
AWS.config.update({region: 'us-east-2'});
const s3 = new AWS.S3({apiVersion: '2006-03-01'});
exports.handler = function(event, context, callback) {
var bucketParams = {
Bucket : 'sample-bucket',
Key: 'employee.json'
};
s3.getObject(bucketParams, function(err, data) {
if (err) {
console.log("Error", err);
} else {
callback(null, data.Body.toString());
}
});
};
Also make sure that function has proper permissions an time to access S3.

AWS Lambda to list S3 buckets with listBuckets() has no effect

I am new to writing Lambda in JS. I want to be able to list the S3 buckets I have, however, below lambda doesn't return what I expect, ie. list of buckets.
What have I done wrong? The only thing I am aware of is the line "console.log('hihi')" didn't print in my Cloudwatch log, so something going on when listBuckets() is invoked but I can't see any relevant logs... Tks in advance for any help !!
var AWS = require('aws-sdk');
AWS.config.update({region: 'us-east-1'});
exports.handler = async (event) => {
// Create S3 service object
var s3 = new AWS.S3({apiVersion: '2006-03-01'});
var params = {};
// Call S3 to list the buckets
s3.listBuckets(params, function(err, data) {
console.log('hihi')
if (err) {
console.log("Error", err);
} else {
console.log("Success", data.Buckets);
}
});
// TODO implement
const response = {
statusCode: 200,
body: JSON.stringify('Hello from Lambda!'),
};
return response;
};
You are using async handler. Therefore, to your lambda does return before listBucket has a chance to execute. One way to overcome is through a Promise as shown in AWS docs.
Therefore, you could modify your code as follows:
var AWS = require('aws-sdk');
AWS.config.update({region: 'us-east-1'});
exports.handler = async (event) => {
const promise = new Promise(function(resolve, reject) {
// Create S3 service object
var s3 = new AWS.S3({apiVersion: '2006-03-01'});
var params = {};
// Call S3 to list the buckets
s3.listBuckets(params, function(err, data) {
console.log('hihi')
if (err) {
console.log("Error", err);
} else {
console.log("Success", data.Buckets);
}
});
})
return promise
};

Unable to return result when using AWS Lambda NodeJS

I am trying to implement a simple Node Js function on AWS Lambda to query data from dynamoDB.
I hooked this lambda function to my API gateway, but I don't see any results when i access the API url.
//Load the AWS SDK for Node.js
var AWS = require('aws-sdk');
// Set the region
AWS.config.update({region: 'us-east-1'});
// Create DynamoDB service object
var b = new AWS.DynamoDB({apiVersion: '2012-08-10'});
var params = {
ExpressionAttributeNames: {
"#devicetimestamp": "timestamp"
},
ExpressionAttributeValues: {
':unitID': {S: 'arena-MXHGMYzBBP5F6jztnLUdCL'},
':dtimestamp' : {S: '1582920096000'}
},
KeyConditionExpression: 'id = :unitID and #devicetimestamp > :dtimestamp',
TableName: 'IoTdata2'
};
b.query(params, function(err, results) {
if (err) {
console.error("Unable to query. Error:", JSON.stringify(err, null, 2));
} else {
console.log("Query succeeded.");
console.log(JSON.stringify(results));
}
});
Code works fine as i see the results from console.log(JSON.stringify(results));
when i use event handler
//Load the AWS SDK for Node.js
var AWS = require('aws-sdk');
// Set the region
AWS.config.update({region: 'us-east-1'});
// Create DynamoDB service object
var b = new AWS.DynamoDB({apiVersion: '2012-08-10'});
exports.handler = (event, context, callback) => {
var params = {
ExpressionAttributeNames: {
"#devicetimestamp": "timestamp"
},
ExpressionAttributeValues: {
':unitID': {S: 'arena-MXHGMYzBBP5F6jztnLUdCL'},
':dtimestamp' : {S: '1582920096000'}
},
KeyConditionExpression: 'id = :unitID and #devicetimestamp > :dtimestamp',
TableName: 'IoTdata2'
};
b.query(params, function(err, results) {
if (err) {
console.error("Unable to query. Error:", JSON.stringify(err, null, 2));
callback(err);
} else {
console.log("Query succeeded.");
console.log(JSON.stringify(results));
callback(null, results);
}
});
};
```i don't see any response in API URL.I am new to nodeJS, Any suggestions will be greatly appreciated. Thanks
since you're going through API gateway, there's a specific response contract from lambda you need to meet, try doing it like this:
const response = {
statusCode: 200, // need a status code
body: JSON.stringify(results) // and a string body
}
callback(null, response)
a bit more info here: TUTORIAL: Build a Hello World API with Lambda Proxy Integration - Amazon API Gateway

DynamoDB, Lambda function / custom module Timeout

I have the following two JS file. My problem is when i call the Calls.js which calls the Archive.js for archiving logs into DynamoDB the request times out.
I have tried out, many things, read about many things, tried in local/AWS environment without luck. What am i missing?
Link1, Link2, Link3, Link4, Link5,
Archive.js
module.exports.archive = archive;
...
function archive(input, callback){
AWS.config.update({
region: "eu-west-1",
endpoint: "http://localhost:8000"
});
var documentClient = new AWS.DynamoDB.DocumentClient({
httpOptions: {
agent: new https.Agent({
rejectUnauthorized: true,
secureProtocol: "TLSv1_method",
ciphers: "ALL"
})
}
});
...
var paramsPUT = {
TableName: "Logging",
Item: {
HashKey: dbID,
archiveEntry: archiveEntry
}
};
...
documentClient.put(paramsPUT, function(err, data) {
if (err) console.log(err);
if (data) console.log(data);
...
callback(data);
});
}
Calls.js
exports.handler(event, context, callback) => {
const archive = require("./..path..").archive;
...
context.callbackWaitsForEmptyEventLoop = false;
...
archive(input, callback);
...
}
I can not reproduce a timeout condition with your code. Your code is talking to an AWS endpoint at http://localhost:8000, so I assume you have DynamoDB local up and running, don't you ? Failling to have local DynamoDB running would cause the timeout.
That being said, I would strongly suggest to refactor your code to use Promise and the new async/await provided by NodeJS 8 instead of passing the Lambda callback around.
Here is the modified code.
const AWS = require("aws-sdk");
async function archive(input) {
return new Promise( (resolve, reject) => {
AWS.config.update({
region: "eu-west-1",
endpoint: 'http://localhost:8000'
});
//use client specific AWS configuration instead of the global one
const documentClient = new AWS.DynamoDB.DocumentClient();
var paramsPUT = {
TableName: "Logging",
Item: {
HashKey: "123",
archiveEntry: input
}
};
documentClient.put(paramsPUT, function (err, data) {
if (err) {
console.log("ERROR " + err);
reject(err);
}
console.log("Returned from DDB " + JSON.stringify(data, null,2));
resolve(data);
});
});
}
exports.handler = async (event, context, callback) => {
const result = await archive("abc");
callback(result);
}
// stuffs to test locally
callback = function (data) {
console.log("callback called with " + JSON.stringify(data,null,2));
}
event = context = {}
exports.handler(event, context, callback);

Cant insert data into DynamoDB using new nodejs 8.10

I want to use new nodejs 8.10 for developing my lambdas. A simple piece of code when written in node 6.10 style works but the same(similar) code doesn't work when I use node 8.10.
Below is working code which successfully inserts data into dynamodb table(nodejs 6.10)
var AWS = require('aws-sdk');
// Set the region
AWS.config.update({region: 'us-east-1'});
var documentClient = new AWS.DynamoDB.DocumentClient({apiVersion: '2012-08-10'});
exports.handler = (event, context, callback) => {
// TODO implement
var params = {
Item: {
client: 'client_'+Math.random(),
Type: 1,
Status: true,
json: { foo: 'bar', address:{ city:'Pune', street: 'ABC Nagar', pin:'411099'} }
},
TableName: 'clients'
};
documentClient.put(params, function(err, data) {
if (err) {
console.log("Error", err);
callback(err, null);
} else {
console.log("Success", data);
// return "Hi, insert data completed";
callback(null, data);
}
});
};
And below one which is node 8.10 style which doesn't work(means doesn't insert data into dynamodb table). I keep getting null as return value.
var AWS = require('aws-sdk');
// Set the region
AWS.config.update({region: 'us-east-1'});
var documentClient = new AWS.DynamoDB.DocumentClient({apiVersion: '2012-08-10'});
exports.handler = async (event) => {
// TODO implement
var params = {
Item: {
client: 'client_'+Math.random(),
Type: 1,
Status: true,
json: { foo: 'bar', address:{ city:'Pune', street: 'ABC Nagar', pin:'411099'} }
},
TableName: 'clients'
};
documentClient.put(params, function(err, data) {
if (err) {
console.log("Error", err);
} else {
console.log("Success", data);
return "Hi, insert data completed";
}
});
};
I spent searching 2-3 hours searching.. couldn't find any article or any question similar. Can anyone tell me what am I doing wrong?
Async / Await is a syntactical sugar for promise, Your documentClient.put should be wraped with promise. Since documentClient.put is based on callback appoach, you have to wrap it with promise
var AWS = require('aws-sdk');
// Set the region
AWS.config.update({region: 'us-east-1'});
var documentClient = new AWS.DynamoDB.DocumentClient({apiVersion: '2012-08-10'});
exports.handler = async (event) => {
// TODO implement
var params = {
Item: {
client: 'client_'+Math.random(),
Type: 1,
Status: true,
json: { foo: 'bar', address:{ city:'Pune', street: 'ABC Nagar', pin:'411099'} }
},
TableName: 'clients'
};
let putItem = new Promise((res, rej) => {
documentClient.put(params, function(err, data) {
if (err) {
console.log("Error", err);
rej(err);
} else {
console.log("Success", data);
res("Hi, insert data completed");
}
});
});
const result = await putItem;
console.log(result);
return result
};
Note: Its advisable to use DB operations in separate file,rather than using in handler function itself
Did you look in your table to see if it's inserting data? I think it is.
The problem with your async-style code is that you aren't returning a value. Returning "Hi, insert data completed" from the put callback doesn't return a value from handler.
You could manually create a promise and return that from handler, but I'd try using promisify.
This code is untested but should be close:
...
const util = require('util');
...
documentClient.putPromise = util.promisify(documentClient.put);
...
try {
const data = await documentClient.putPromise(params);
console.log("Success", data);
return "Hi, insert data completed";
}
catch (err) {
console.log("Error", err);
}
Here's more on promisify: http://2ality.com/2017/05/util-promisify.html
Calling await dynamo.put(params).promise(); is how I solved this issue after some googling. Specifically, it seems like calling foo.promise(); in the aws sdk is supported now.

Resources