Unable to access dynamodb from nodejs code through lambda - node.js

I have been trying to test this from lambda but unable to proceed.
var Alexa = require("alexa-sdk");
var dynamoDBConfiguration = {
"accessKeyId": "useraccess",
"secretAccessKey": "usersecretkey",
"region": "us-east-1"
};
var AWS = require("aws-sdk");
AWS.config.update(dynamoDBConfiguration);
var promisify = require("es6-promisify");
var dynClient = new AWS.DynamoDB.DocumentClient({"region":"us-east-
1"});
//convert callback style functions to promises
const dbGet = promisify(dynClient.get,dynClient);
const dbPut = promisify(dynClient.put,dynClient);
const dbDelete = promisify(dynClient.delete,dynClient);
var startStateHandlers = (GAME_STATES.STARt, {
"StartGame": function (isNewGame,context) {
const dynamoParams = {
TableName: "Userdata",
Key: {
"UserId":"test"
}
}
dbGet(dynamoParams)
.then(data => {
console.log('Get user succeeded', data);
const userId = data.UserId;
if (userId != null) {
console.log(data.UserName);
}
else {
// no match, add the user
return dbPut(dynamoParams);
}
})
.then(data => {
console.log('Add user succeeded', data);
})
.catch(err => {
console.error(err);
});
this.emit(":tell", speechOutput, speechOutput);
}
});
var handlers = {
"LaunchRequest": function () {
var speechOutput = "hello";
this.emit(":tell", speechOutput, speechOutput);
}
};
var handler = (function () {
function handler(event, context, callback) {
var alexa = Alexa.handler(event, context);
alexa.appId = "appid";
alexa.registerHandlers(handlers, startStateHandlers);
alexa.execute();
}
return handler;
})();
exports.handler = handler;
It doesnt throw any error in the lamda logs and not able to see any log in Cloudwatch. It just executes the other lines of code.
I have attached all permission policy to the user and setup the lamda function as lambda_dynamo.
Unable to understand what is the issue with it.
Appreciate your help.

var dynamoDBConfiguration = {
"accessKeyId": "useraccess",
"secretAccessKey": "usersecretkey",
"region": "us-east-1"
};
var AWS = require("aws-sdk");
// update the AWS.Config global configuration object
AWS.config.update(dynamoDBConfiguration)
// Create DynamoDB document client
var dynClient = new AWS.DynamoDB.DocumentClient()

Related

s3.listObjectsV2 is not a function NodeJs

I've following lambda function for fetching list of all the keys from S3, however, it ends up in error message as s3.listObjectsV2 is not a function. Not sure what's wrong. The code is taken from another SO post, however it doesn't seem to be working.
Code:
const AWS = require('aws-sdk');
var request=true;
const awsOptions = {
region: "us-east-1"
};
const s3 = new AWS.S3(awsOptions);
exports.handler = async (event, context, callback) => {
const SrcBucket = event.Records[0].s3.bucket.name;
const trigger_file = event.Records[0].s3.object.key;
var bucketParams = {
Bucket: SrcBucket,
Prefix: 'Temp/',
};
var allKeys = [];
listAllKeys();
function listAllKeys()
{
s3.listObjectsV2(bucketParams, function (err, data)
{
if (err)
{
console.log(err, err.stack); // an error occurred
}
else
{
var contents = data.Contents;
contents.forEach(function (content) {
allKeys.push(content.Key);
});
if (data.IsTruncated) {
bucketParams.ContinuationToken = data.NextContinuationToken;
console.log("get further list...");
listAllKeys();
}
}
});
}
console.log(allKeys.length);
}

context.hasRole is not a function in Nodejs sinon testing issue

I had made function to fetch cloudwatch details from AWS.I trying to create a testcase in node.js and using sinon but i am getting a context.hasRole is not defined because i am checking this in my function file which is cloudwatch.js.
Can you please help me to fake this test
"-----cloudwatch.spec.js-------"
describe('cloudwatch', () => {
let sandbox = null;
beforeEach(() => {
sandbox = sinon.createSandbox(AWS.config);
})
afterEach(() => {
sandbox.restore()
})
it('Should return queryid', async () => {
let queryId = {
queryId: "12ab3456-12ab-123a-789e-1234567890ab"
};
const body = {
endTime: 34568765,
queryString: 'filter #message like /Audit/',
startTime: 34565678,
limit: 100,
logGroupName: '/aws/lambda/dev-api--service-sandbox-api'
};
let params = {}
let queryid = {
queryId: 6786971301298309123
};
await cloudwatch.startQuery(context, params, body, callback);
sinon.match(queryId)
})
})
"------Cloudwatch.js----"
let cloudwatch = module.exports = {};
const AWS = require('aws-sdk');
const nconf = require('nconf');
const {
HttpResult,
HttpUnauthorizedError,
AmazonCloudWatchLogsClient
} = require('api-lib');
AWS.config = nconf.get('amazonCloudWatchLogsClient');
cloudwatch.startQuery = async function(context, params, body,
callback) {
body.startTime = new Date(body.startTime).valueOf();
body.endTime = new Date(body.endTime).valueOf();
if (!context.hasRole("read:cloudwatch"))
return callback(new HttpUnauthorizedError("context missing role
read:cloudwatch"));
const amazonCloudWatchLogsClient = new
AmazonCloudWatchLogsClient(AWS.config);
let result = await amazonCloudWatchLogsClient.startQuery(body,
function(err) {
console.log("Error", err);
});
callback(null, new HttpResult(result));
};
cloudwatch.getQueryResults = async function(context, params,
requestBody, callback) {
console.log(requestBody)
let test = requestBody.queryId;
test = test.toString();
requestBody.queryId = test;
if (!context.hasRole("read:cloudwatch"))
return callback(new HttpUnauthorizedError("context missing role
read:cloudwatch"));
const amazonCloudWatchLogsClient = new
AmazonCloudWatchLogsClient(AWS.config);
let result2 = await
amazonCloudWatchLogsClient.getQueryResults(requestBody.queryId,
function(err) {
console.log("Error", err);
});
callback(null, new HttpResult(result2));
};
I am using eslint and except from chai for comparing the output to the sample output.

Not able to test Stepfunction Execution via Lambda

I am trying to test my lambda function which invokes Step Function using AWS mock, but it is giving UnknownEndpoint: Inaccessible host: states.local-env.amazonaws.com
Here is my sample lambda function:
const AWS = require("aws-sdk");
const stepFunctions = new AWS.StepFunctions({region: 'local-env'});
exports.handler = async (event, context, config) => {
const response = {
statusCode: 200,
body: event,
};
var params = {
stateMachineArn: process.env.StateMachineARN,
input: JSON.stringify(event.body),
name: 'Testing2'
};
stepFunctions.startExecution(params, function(err, data) {
if (err) console.log(err, err.stack);
});
return response;
};
and there is my test file:
const index = require('./index')
var AWS = require('aws-sdk-mock');
const AWS_SDK = require('aws-sdk');
AWS.mock('StepFunctions', 'startExecution', function (params, callback){
callback(null, "successfully started the execution");
});
const isTest = process.env.JEST_WORKER_ID;
const config = {
convertEmptyValues: true,
...(isTest && {endpoint: 'localhost:8000', sslEnabled: false,region:'local-env'})
};
describe('Test Step Function Invocation', function () {
it('verifies successful response', async () => {
process.env.StateMachineARN = 'arn:aws:states:us-east-1:12345678:stateMachine:Testing';
var event = {
"payload": "my_payload",
"data": "some-data",
"MVId": "00156"
};
const result = await index.handler(event,{},config);
expect(result.statusCode).toEqual(200);
expect(result.body).toBe(event);
});
});
AWS.restore('StepFunctions');
I've been searching about this in the documentation and other resources but haven't found any solutions yet.

Retrieve data from S3 bucket with Lambda function link to an alexa skill in node.js

What i'm trying to do here is to retrieve a basic CSV file in a S3 Bucket but i'm having hard time getting it.
I try first to only get the data from the bucket in a basic lambda function (not linked to an alexa skill) like that :
console.log('Loading function');
const aws = require('aws-sdk');
const s3 = new aws.S3({ apiVersion: '2006-03-01' });
exports.handler = async (event, context) => {
const bucket = 'mybucket';
const key = 'myfile';
const params = {
Bucket: bucket,
Key: key,
};
try {
const data = await s3.getObject(params).promise();
var content = data.Body.toString();
var lines = content.split('\r\n');
var headers = lines[0].split(',');
var result = {};
for(var i=1;i<lines.length;i++){
var currentline = lines[i].split(',');
var obj2 = {};
for(var j=2;j<headers.length;j++){
obj2[headers[j]] = currentline[j];
}
result[currentline[0]+currentline[1]] = obj2;
}
return result;
} catch (err) {
console.log(err);
const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`;
console.log(message);
throw new Error(message);
}
};
And it worked perfectly but then i tried to put it inside a lambda function linked to my alexa skill and i'm not receiving anything from the getObject function :
const Alexa = require('alexa-sdk');
const aws = require('aws-sdk');
const s3 = new aws.S3({ apiVersion: '2006-03-01' });
var data;
function getData(){
// Setting the bucket and files parameters
const bucket = 'mybucket';
const key = 'myfile';
const params = {
Bucket: bucket,
Key: key,
};
try {
const data = s3.getObject(params);
// Getting the Body of the response
var content = data.Body.toString();
// Splitting into a proper data structure
var result = {};
var lines = content.split("\r\n");
var headers = lines[0].replace('\r','').split(",");
for(var i=1;i<lines.length;i++){
var currentline = lines[i].split(",");
var obj2 = {};
for(var j=2;j<headers.length;j++){
obj2[headers[j]] = currentline[j];
}
result[currentline[0].toLowerCase()+currentline[1].toLowerCase()] = obj2;
}
} catch (err) {
console.log(err);
const message = `Error getting object ${key} from bucket ${bucket}.`;
console.log(message);
throw new Error(message);
}
// Sending the response back
return result;
}
const handlers = {
'LaunchRequest': function () {
// GETTING THE DATA SET
data = getData();
// Stuff here
this.emit(':responseReady');
},
'getLocalisation': function () {
//Stuff here
},
'AMAZON.HelpIntent': function () {
this.response.speak(messages.HELP);
this.emit(':responseReady');
},
'AMAZON.CancelIntent': function () {
this.response.speak(messages.STOP);
this.emit(':responseReady');
},
'AMAZON.StopIntent': function () {
this.emit(':tell', 'Bye');
},
'AMAZON.FallbackIntent': function () {
this.response.speak(messages.ERROR);
this.emit(':responseReady');
},
};
exports.handler = (event, context, callback) => {
const alexa = Alexa.handler(event, context, callback);
alexa.APP_ID = APP_ID;
alexa.registerHandlers(handlers);
alexa.execute();
};
I'm running everything directly from the AWS Lambda IDE.
I think i'm missing something with Async/Await/Promise thing but i don't truely understand it.
I just had to put
async function getData()
and
exports.handler = async (event, context, callback) => {
// code here
};

Not able to mock S3 download request using proxyquire

const awsSdk = require('aws-sdk');
module.exports = {
downloadFile(bucketName, fileName, callback) {
var s3 = new awsSdk.S3();
var params = { Bucket: bucketName, Key: fileName };
var file = require('fs').createWriteStream('abcd.jpg');
var stream = s3.getObject(params).on('error', function (err) {
console.log(' download.on');
callback('error', null);
})
.createReadStream()
stream.pipe(file);
}
}
Above, is the code i need to mock in my Test class using proxyquire. The issue is, im not able to mock methods like getObject,on,createReadStream. Also after mocking i need to emit the error event from test class that will trigger the above on method which will call the callback in my test class where exception is tested.
Below is my test class code.
const proxyquire = require('proxyquire').noCallThru().noPreserveCache();
const sinon = require('sinon');
const emitter = require('events').EventEmitter;
function Download() {
emitter.call(this);
this.error = function () {
this.emit('error');
}
}
describe('S3 download test', () => {
awsSdkMock = {}
awsSdkMock.config = {};
awsSdkMock.config.region = { };
var s3Instance = {};
awsSdkMock.S3 = function (){
return s3Instance;
};
var object = {};
s3Instance.getObject = function (params){
return object;
};
var request = {};
const errorCallBack = sinon.spy();
var err = 'error';
object.on = function (err, errorCallBack) {
console.log('object.on');
errorCallBack();
return request;
};
var stream = {};
request.createReadStream = function(){
console.log('createReadStream');
return stream
};
stream.pipe = function(file){
console.log('download.error');
// download.error();
};
Download.prototype.__proto__ = emitter.prototype;
var download = new Download();
const s3 = proxyquire('./../../../modules/s3', {
'aws-sdk': awsSdkMock
})
it('Error in download test', (done) => {
const errorCallBack = sinon.spy();
s3.downloadFile('123', 'abcd', errorCallBack);
sinon.assert.calledWith(errorCallBack, 'error', null);
done();
});
})
Any help is appreciated.

Resources