Connect Lambda to mLab - aws-lambda

I would like to read a collection in mLab(mongoDB) and get result document based on the request from AWS LAMBDA function.
I could write a nodeJS function code snippet and whatever timeout I set it results in
Task timed out after *** seconds
Any solution, link or thoughts will be helpful. Either JAVA or NODE
'use strict';
const MongoClient = require('mongodb').MongoClient;
exports.handler = (event, context, callback) => {
console.log('=> connect to database');
MongoClient.connect('mongodb://test:test123#ds.xyx.fleet.mlab.com:1234', function (err, client) {
if (err) {
console.log("ERR ",err );
throw err;
}
var db = client.db('user');
db.collection('sessions').findOne({}, function (findErr, result) {
if (findErr){
console.log("findErr ",findErr);
throw findErr;
} else {
console.log("#",result);
console.log("##",result.name);
context.succeed(result);
}
client.close();
});
});
};
P.S : Referred all related stack questions.

Lambda function returned success after adding db name in
MongoClient.connect('mongodb://test:test123#ds.xyx.fleet.mlab.com:1234/dbNAME')
Apart from declaring db name in
var db = client.db('dbNAME');
It should also be added in mLab connection URI.

Related

ThrottlerGuard not working on Websocket in Nestjs

I'm creating an application that is using Nestjs with websockets, but now I need to add rate limit on the sockets, but analyzing the documentation documentation link and implementing what it says in it, when I use #UseGuards(MyGuard) an error occurs in the application.
My Guard:
#Injectable()
export class NewThrottlerGuard extends ThrottlerGuard {
protected async handleRequest(
context: ExecutionContext,
limit: number,
ttl: number,
): Promise<boolean> {
console.log('Request');
const client = context.switchToWs().getClient();
const ip = client.conn.remoteAddress;
const key = this.generateKey(context, ip);
const ttls = await this.storageService.getRecord(key);
if (ttls.length >= limit) {
throw new ThrottlerException();
}
await this.storageService.addRecord(key, ttl);
return true;
}
}
Websocket:
#UseGuards(NewThrottlerGuard)
#SubscribeMessage('sendMessage')
sendMessage(
#ConnectedSocket() client: Socket,
#MessageBody() message: string,
) {
client.rooms.forEach((room) => {
if (room !== client.id) {
client.broadcast.to(room).emit('message', message);
}
});
}
Error in console:
/node_modules/#nestjs/common/utils/validate-each.util.js:22
throw new InvalidDecoratorItemException(decorator, item, context.name);
^
Error: Invalid guard passed to #UseGuards() decorator (ChatGateway).
at validateEach
The file in: #nestjs/common/utils/validate-each.util.js:22
function validateEach(context, arr, predicate, decorator, item) {
if (!context || !context.name) {
return true;
}
console.log(context, arr)
const errors = arr.some(str => !predicate(str));
if (errors) {
throw new InvalidDecoratorItemException(decorator, item, context.name);
}
return true;
}
i put some console.log then in the terminal it show:
[Function: ChatGateway] [ undefined ]
In Github Throttler documentation they say: You cannot bind the guard with APP_GUARD or app.useGlobalGuards() due to how Nest binds global guards.
So, im using #UseGuards()
The guard itself was written correctly, but it was put in a location that importing it made a circular reference between files, so when #UseGuards() was used it became #UseGuards(undefined) which caused the cryptic error message. Moving the guard to a dedicated file will fix the error
I follow your github reference settings and it doesn't work,The following is my code, where is my setting wrong, and the request to ws is not intercepted(In the handleRequest method)

REST API insert is not working using node-oracledb

I try to make RESTFUL API with node js and oracle database for my first time
I make a table in the database named "EMPLOYEES" and I add some data there
I make my backend file and I try to get the information in the database and it's worked successfuly
but when I try to make POST to add a new employee I don't get an error and the employee is not added to the database
when I try to test it with POSTMAN I got this result a null object like this {}
I know that I'm missing something
const express = require('express')
const oracledb = require('oracledb');
const bodyPerser=require("body-parser")
const app = express();
const port = 3000;
var password = 'mypassword';
app.use(bodyPerser.json());
async function selectAllEmployees(req, res) {
try {
connection = await oracledb.getConnection({
user: "system",
password: password,
connectString: "localhost:1521/XE"
});
console.log('connected to database');
// run query to get all employees
result = await connection.execute(`SELECT * FROM EMPLOYEES`);
} catch (err) {
//send error message
return res.send(err.message);
} finally {
if (connection) {
try {
// Always close connections
await connection.close();
console.log('close connection success');
} catch (err) {
console.error(err.message);
}
}
if (result.rows.length == 0) {
//query return zero employees
return res.send('query send no rows');
} else {
//send all employees
//return res.send(result.rows);
console.log(JSON.stringify(result.rows));
console.log(result.metaData[0].name);
let list=[]
result.rows.forEach(element => {
let agent = {
"ID": element[0],
"EMPNAME": element[1],
"EMPLASTNAME": element[2],
"AGE":element[3]
}
list.push(agent)
});
return res.send(JSON.stringify(list));
}
}
}
//get /employess
app.get('/employees', function (req, res) {
selectAllEmployees(req, res);
})
//////////////////post//////////////////////
app.post("/addNewEmployee", async (req, res) => {
try {
connection = await oracledb.getConnection({
user: "system",
password: password,
connectString: "localhost:1521/XE"
});
console.log('connected to database');
// I don't know what i'm missing here
result=connection.execute(`INSERT INTO EMPLOYEES VALUES ('${req.body.ID}','${req.body.EMPNAME}','${req.body.EMPLASTNAME}','${req.body.AGE}')`);
res.send(result)
} catch (err) {
//send error message
return res.send(err.message);
}
})
app.listen(port, () => console.log("nodeOracleRestApi app listening on port %s!", port))
Review node-oracledb examples and make sure you have basic techniques covered e.g. using bind variables. (The way you build your INSERT is open to SQL injection security attacks). Look at how webapp.js uses a connection pool - which you'll need if you have more than one person accessing your service.
Make sure you commit the data after inserting.
Add an 'await' before your connection.execute() for INSERT, something like:
result = await connection.execute(`INSERT INTO EMPLOYEES VALUES (:id, :empname, :emplastname, :age)`,
[req.body.ID, req.body.EMPNAME, req.body.EMPLASTNAME, req.body.AGE],
{autoCommit: true}
);
Do some debugging and see what is not working.
Avoid using SYSTEM for testing. Create a 'normal' (non privileged) user:
https://blogs.oracle.com/sql/how-to-create-users-grant-them-privileges-and-remove-them-in-oracle-database
Finally check out this series on creating a REST service with node-oracledb:
https://blogs.oracle.com/oraclemagazine/build-rest-apis-for-nodejs-part-1
https://github.com/oracle/oracle-db-examples/tree/master/javascript/rest-api

How do you use a nodejs Lambda in AWS as a producer to send messages to MSK topic without creating EC2 client server?

I am trying to create a Lambda in AWS that serves as a producer to an MSK topic. All the AWS docs say to create a new EC2 instance, but as my Lambda is in the same VPC I feel like this should work. I am very new to this and I notice my log statement never hits in my producer.on function.
I am using nodejs and the kafka-node module. The code can be found below.
Essentially, I am just wondering if anyone knows how to do this and why the producer.on function is never hit when I run test through the Lambda? This is just some test code to see if I can get it to send, but if any more data is needed oy help please let me know and thanks in advance.
exports.handler = async (event, context,callback) => {
const kafka = require('kafka-node');
const bp = require('body-parser');
const kafka_topic = 'MyTopic';
const Producer = kafka.Producer;
var KeyedMessage = kafka.KeyedMessage;
const Client = kafka.Client;
const client = new kafka.KafkaClient({kafkaHost: 'myhost:9094'});
console.log('client :: '+JSON.stringify(client));
const producer = new Producer(client);
console.log('about to hit producer code');
producer.on('ready', function() {
console.log('Hello there!')
let message = 'my message';
let keyedMessage = new KeyedMessage('keyed', 'me keyed message');
producer.send([
{ topic: kafka_topic, partition: 0, messages: [message, keyedMessage], attributes: 0 }
], function (err, result) {
console.log(err || result);
process.exit();
});
});
producer.on('error', function (err) {
console.log('error', err);
});
}
return "success";
What you need is to be able to produce messages on your MSK cluster using REST API. Why not setup a REST proxy for MSK as detailed here and then call this API to produce your messages to MSK.

How to fetch data from a REST API in serverless?

I am new to serverless. I want to fetch data from google. I am using Google Custom Search engine. Although I got results when I run locally. But when I deploy to AWS Lambda I am getting "Internal Server Error". Can anyone help me to fix the issue?
'use strict';
var request = require('request');
module.exports.get = (event, context, callback) => {
request('https://www.googleapis.com/customsearch/v1?q=Serverless+AWS+Lambda&cx=xxxxxxxxxxx&key=API_key&num=10', function (error, response, body) {
if (!error && response.statusCode == 200) {
callback(null, response);
console.log(body);
} else {
console.warn(error);
}
});
};
I want a json output. I would like to save that result
Internal Server Error mostly points out that your lambda code could not be executed correctly. Did you pack all your dependencies (node_modules) within the ZIP file you provide to AWS lambda (e.g. request ?)

How to create and read .txt file with fs.writeFile to AWS Lambda

​Hello,
Does someone know how I can write a .txt to AWS Lambda? I'm using Node.js, Alexa Skills Kit and Lambda.
My code:
var fs = require('fs');
const handlers = {
'SetOrderIntent': function() {
if (this.event.request.intent) {
var test = this.event.request.intent.slots.Items.value;
fs.writeFile('/tmp/log.txt', test, function (err) {
if (err) throw err;
});
this.emit(':ask', 'This is your item: ' + test, "Test");
}
},
'RetrieveOrderIntent': function() {
if (this.event.request.intent) {
fs.readFile('/tmp/log.txt', function (err, content) {
if (err) return callback(err)
callback(null, content)
})
this.emit(':ask', content);
}
},
}
thing is, that your /tmp folder is only guaranteed to be persistent during the execution of your lambda function. So; if SetOrderIntent is called and executed in one lambda call and RetrieveOrderIntent in another lambda call, these are two separate lambda executions and it is not guaranteed that /tmp is still available.
To make sure the data you saved in one lambda execution is still there when the read function is called, you should store your data on S3 or so.

Resources