node js aws lambda function - node.js

Thank you for your comments. I have written the same code in much simpler way(I think..) In the below code, the ProcessRequest is not getting called.
I am not a developer and I am trying to use lambda-nodejs to fulfill my activity.
here is the code:
function close(sessionAttributes, fulfillmentState, message) {
return {
sessionAttributes,
dialogAction: {
type: 'Close',
fulfillmentState,
message,
},
};
}
function dispatch(intentRequest, callback) {
const sessionAttributes = intentRequest.sessionAttributes;
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var xhr = new XMLHttpRequest();
xhr.open('GET', "http://<server>:8086/query?db=rpt&q=select transactionName,responseTime from healthCheckTestV1 ORDER BY DESC LIMIT 9", true);
console.log("-------before SEND")
xhr.send();
console.log("AFTER SEND---------")
console.log("Inside Dispatch............")
xhr.onreadystatechange = processRequest;
function processRequest(e) {
console.log("processRequest function inside")
if (xhr.readyState == 4 && xhr.status == 200) {
var toDisplay = [];
var response = JSON.parse(xhr.responseText);
//console.log(xhr.responseText);
for (var i = 0; i < response.results.length; i++) {
for (var t = 0; t < response.results[i].series.length; t++) {
for (var j = 0; j < response.results[i].series[t].values.length; j++) {
var toSplit = response.results[i].series[t].values[j].toString() // VALUE
var splitted = toSplit.split(',');
//console.log(splitted[1]+"="+parseInt(splitted[2],10)+" seconds")
toDisplay.push(splitted[1] + "=" + parseInt(splitted[2], 10) + " seconds\n")
toDisplay.join()
//toDisplay.replace(/,/g," ")
}
console.log(toDisplay.toString().trim().replace(/,/g, " "))
}
}
}
}
callback(close(sessionAttributes, 'Fulfilled', {
'contentType': 'PlainText',
'content': `The status of your order is`
}));
}
// --------------- Main handler -----------------------
// Route the incoming request based on intent.
// The JSON body of the request is provided in the event slot.
exports.handler = (event, context, callback) => {
context.callbackWaitsForEmptyEventLoop = false;
try {
dispatch(event,
(response) => {
callback(null, response);
});
} catch (err) {
callback(err);
}
};
But when I run the same code in eclipse, after removing the lambda handler code, it works fine.
OutPUT
-------before SEND
AFTER SEND---------
processRequest function inside
processRequest function inside
processRequest function inside
Security_Question=4 seconds
File_Download=31 seconds
View_File=11 seconds
Open_TEAM=32 seconds
File_Upload=50 seconds
Open_OneDrive=3 seconds
Logout=10 seconds
Login_OKTA=9 seconds
HomePage=5 seconds

Related

Array is empty, no data after for loop added

I'm using redis and nodejs for the first time, without success. Trying to loop insert data but got an empty array.
const redis = require("redis");
const client = redis.createClient({
retry_strategy: function(options) {
if (options.error && options.error.code === "ECONNREFUSED") {
// End reconnecting on a specific error and flush all commands with
// a individual error
return new Error("The server refused the connection");
}
if (options.total_retry_time > 1000 * 60 * 60) {
// End reconnecting after a specific timeout and flush all commands
// with a individual error
return new Error("Retry time exhausted");
}
if (options.attempt > 10) {
// End reconnecting with built in error
return undefined;
}
// reconnect after
return Math.min(options.attempt * 100, 3000);
},
});
var data_value = {
id: '235235',
totalrv: 'WAIT',
product: 'productName2',
url: 'url2',
process: 'proc',
task: 'msg'
};
client.set("key0", JSON.stringify(data_value));
client.set("key1", JSON.stringify(data_value));
client.set("key2", JSON.stringify(data_value));
client.set("key3", JSON.stringify(data_value));
client.set("key4", JSON.stringify(data_value));
//client.get("key2", redis.print);
var logger_data = {
logger: []
};
client.keys('*', function (err, keys) {
if (err) return console.log(err);
for(var i = 0, len = keys.length; i < len; i++) {
var values_v = client.get(keys[i].toString(), function(err, val) {
// console.log(logger_data);
// data is exist ...
logger_data.logger.push(JSON.parse(val));
});
}
});
// empty data
console.log(logger_data);
I wrote 2 print data result, in the loop it's working ok, but end of function, there are no data in array.
you can call a function inside the callback if you want to print the logger_data with values outside the asynchronous callback, like this
function printLoggerData(){
console.log(logger_data);
}
client.keys('*', function (err, keys) {
if (err) return console.log(err);
for(var i = 0, len = keys.length; i < len; i++) {
var values_v = client.get(keys[i].toString(), function(err, val) {
// console.log(logger_data);
// data is exist ...
logger_data.logger.push(JSON.parse(val));
// calling the function here so that it contains the latest values
printLoggerData();
});
}
});
Ok, with help of CertainPerformance, it's now working in asynchronous.
Thank you very much ...
async function getMessage () {
var logger_data = {
logger: []
};
return new Promise(function(resolve, reject) {
client.keys('*', function (err, keys) {
if (err) return console.log(err);
for(var i = 0, len = keys.length; i < len; i++) {
var values_v = client.get(keys[i].toString(), function(err, val) {
logger_data.logger.push(JSON.parse(val));
resolve(logger_data);
});
}
});
});
}
async function main() {
let message = await getMessage();
console.log(message);
}
main();

How to get code to execute in order in node.js

I am trying to finish my script, but for some reason i don't know, it refuses to execute in the order i put it in.
I've tried placing a 'wait' function between the JoinRequest update function and the following code, but when run, it acts as if the function call and wait function were the other way round, countering the point of the wait().
const Roblox = require('noblox.js')
var fs = require('fs');
var joinRequests = []
...
function wait(ms) {
var d = new Date();
var d2 = null;
do { d2 = new Date(); }
while(d2-d < ms*1000);
};
...
function updateJReqs() {
Roblox.getJoinRequests(4745601).then((array) => {
var i;
var final = [];
for(i = 0; i < array.length; i++) {
final.push(array[i].username);
};
if(final === '') {
final = '-None';
};
joinRequests = final
console.log('Updated join requests.')
});
}
function check() {
setTimeout(() => {
fs.readFile('Request.txt',encoding = 'utf-8', function(err, data) {
if (err) {
check();
} else {
updateJReqs(); //for some reason this function is executed alongside the below, not before it.
// Tried putting wait(x) in here.
console.log('Request received: ' + data)
var solution = joinRequests
console.log('Fuffiling request with ' + solution)
fufillRequest(solution)
fs.unlink('Request.txt', function(err) {
if(err) throw err;
});
check();
}
});
}, 400)
}
check();
The script is supposed to wait until a file is created (accomplished), update the list of join requests (accomplished) and then create a new file with the list of join requests in(not accomplished).
if I understand your code you work with async code, you need to return a promise in updateJReqs and add a condition of leaving from the function because you have an infinite recursion
function updateJReqs() {
return new Promise(resolve => {
Roblox.getJoinRequests(4745601).then((array) => {
var i;
var final = [];
for(i = 0; i < array.length; i++) {
final.push(array[i].username);
};
if(final === '') {
final = '-None';
};
joinRequests = final
console.log('Updated join requests.')
resolve();
});
}
}
async function check() {
setTimeout(() => {
fs.readFile('Request.txt',encoding = 'utf-8', function(err, data) {
if (err) {
await check();
} else {
await updateJReqs();
// Tried putting wait(x) in here.
console.log('Request received: ' + data)
var solution = joinRequests
console.log('Fuffiling request with ' + solution)
fufillRequest(solution)
fs.unlink('Request.txt', function(err) {
if(err) throw err;
});
// you dont have an exit from your function check();
return 'Success';
}
});
}, 400)
}
check().then(res => console.log(res));

Polling a URL until certain value is set in JSON response : Mocha, Integration testing

I am working on automating an End to end scenario using Mocha.
I have a url endpoint which is to be polled until a certain value is obtained in the resulting response. Is there any way to do it ?
Example with request and callback approach:
const request = require('request');
describe('example', () => {
it('polling', function (done) {
this.timeout(5000);
let attemptsLeft = 10;
const expectedValue = '42';
const delayBetweenRequest = 100;
function check() {
request('http://www.google.com', (error, response, body) => {
if (body === expectedValue) return done();
attemptsLeft -= 1;
if (!attemptsLeft) return done(new Error('All attempts used'));
setTimeout(check, delayBetweenRequest);
});
}
check();
});
});
Example with got and async/await approach:
const utils = require('util');
const got = require('got');
const wait = utils.promisify(setTimeout);
describe('example', () => {
it('polling', async function (done) {
this.timeout(5000);
const expectedValue = '42';
const delayBetweenRequest = 100;
for (let attemptsLeft = 10; attemptsLeft; attemptsLeft -= 1) {
const resp = await got.get('http://www.google.com');
if (resp.body === expectedValue) return done();
await wait(delayBetweenRequest);
}
done(new Error('All attempts used'));
});
});
This is how I was able to do it with WebdriverIO and Mocha
describe("wait for value in content of page", () => {
it("should be able to wait to value in url", () => {
var max_seconds_to_wait = 10;
var seconds_counter = 0;
var should_continue = true;
while (should_continue) {
browser.url('http://your.url.com');
var response = JSON.parse(browser.getText("body"));
console.log(response)
if (response == 'something') {
should_continue = false;
}
browser.pause(1000);
seconds_counter++;
if (seconds_counter > max_seconds_to_wait) {
throw 'Waiting for json from url timeout error';
}
}
});
});

Return Multiple Promises From For Loop

I'm creating a scraper using Express and Request.
An array of URL's is passed to request which is then iterated through a for loop. Once all the data is parsed and all data is resolved the callback calls res.send.
I'm trying to convert this into promises but I believe the for loop I am using will not allow me. If the loop is causing the issue, is there another way I can code this and achieve the same result?
Callback Method
function scrape(callback){
for(var i = 0; i < urls.length; i++){
request(urls[i], function(error, response, html){
if(!error && response.statusCode == 200){
// LOAD Cherio (jQuery) on the webpage
var $ = cheerio.load(html);
try{
var name = $(".name").text();
var mpn = $(".specs.block").contents().get(6).nodeValue.trim();
var jsontemp = {"MPN": "", "Name": "", "PriceList": {}};
jsontemp.MPN = mpn;
jsontemp.Name = name;
// Traverse the DOM to get tr tags and extract info
$(".wide-table tbody tr").each(function (i, row) {
var $row = $(row),
merchant = $row. attr("class").trim(),
total = $row.children(".total").text();
jsontemp.PriceList[merchant] = merchant;
jsontemp.PriceList[merchant] = total;
});
}
catch(err){
console.log('Error occured during data scraping:');
}
list.push(jsontemp);
}
else{
console.log(error);
}
count++;
callback();
});
}
}
});
scrape(() => {
console.log(count);
if(count == urls.length){res.send(list)}
});
Promise Implementation Attempt
var urls = [
"http://test.com/",
"http://test.com/2"
];
var list = [];
var count = 0;
scrape().then((data) => {
list.push(data)
if(count == urls.length){res.send(list)}
})
.catch(error => console.log(error))
function scrape(){
for(var i = 0; i < urls.length; i++){
return new Promise(function (resolve, reject) {
request(urls[i], function(error, response, html){
if(!error && response.statusCode == 200){
var $ = cheerio.load(html);
try{
var name = $(".name").text();
var mpn = $(".specs.block").contents().get(6).nodeValue.trim();
var jsontemp = {"MPN": "", "Name": "", "PriceList": {}};
jsontemp.MPN = mpn;
jsontemp.Name = name;
// TRAVERSING DOM FOR DATA //
$(".wide-table tbody tr").each(function (i, row) {
var $row = $(row),
merchant = $row. attr("class").trim(),
total = $row.children(".total").text();
jsontemp.PriceList[merchant] = merchant;
jsontemp.PriceList[merchant] = total;
});
}
catch(err){
console.log('Error occured during data scraping:');
}
resolve(jsontemp);
}
else{
console.log(error);
return reject(error);
}
count++;
});
}
}
You need to store these promises in a list, and then call Promise.all to get a single promise for everything:
function scrape() {
var promises = []; // array of promises
for(var i = 0; i < urls.length; i++) {
var url = urls[i];
var promise = new Promise(function(resolve, reject) {
// ...
};
// add to array
promises.push(promise);
}
// return a single promise with an array of the results
// by using Promise.all
return Promise.all(promises);
}
Also, don't use loop variables (like i) inside a function inside a loop when using var. Instead, you should declare a url variable outside the promise callback function, or replace var with the newer let.

Nodejs loop http requests in a function

I have been able to use bluebird to run an array of http get requests in parallel within a function that returns the responses of each requests after they have all finished. However, I would like to chain the requests in sequence to run one after another without effecting the asynchronous behavior of the promises in my current function shown below.
var Promise = require('bluebird');
function buildCartWithItems(cartID,requests, cookie) {
var promises = [];
for (idx in requests) {
var request = requests[idx]; // requests is an array containing the json records of each request parameter
request["id"] = cartID;
promises.push(new Promise(function(resolve, reject) {
var options = {
host: 'example.com',
path: "/example/addToCart?"+param(request),
headers: {'Cookie': cookie, 'Connection': 'keep-alive'}
};
https.get(options, function (response) {
var body = '';
response.on('data', function(d) {
body += d;
});
response.on('end', function() {
console.log("jsonservicesPostRequest response: " + body);
var parsed = JSON.parse(body);
if (parsed["STATUS"] == "success") {
resolve(parsed.RESULT.itemGroup.id);
} else
resolve("error");
});
response.on('error', function(exception) {
console.log("auth error: " + exception);
resolve(exception);
});
});
}));
}
return Promise.all(promises);
}
Use:
var cart = 12345; // cart ID
var itemsParams = [];
for (idx in products) {
var parms = {
'guid' : prod["_id"]["GUID"],
'count': prod["deficit"],
};
itemsParams.push(parms);
}
buildCartWithItems(cart,itemsParams,newcookie).then(function(results) {
// results -> array of all of the cart.id's
console.log("Build Cart Results: " + JSON.stringify(results));
});

Resources