Trying to create a lambda function that lists tagged ec2 and tagged rds and performs an action thereafter. This is the first time i have used javascript and would appreciate some help.
Please see my example below
var aws = require('aws-sdk');
var ec2 = new aws.EC2();
var rds = new aws.RDS();
aws.config.region = 'us-east-1';
exports.handler = function(event,context) {
if (event) {
console.log(event.id);
}
//setup params for rds call
var rdsparams = {
DBInstanceIdentifier: 'master',
};
//setup params for ec2 call
var ec2params = {
Filters: [
{
Name: 'tag:role',
Values: [
'app'
],
}
]
};
//Get ec2 instances with app tag, may need to add a condition on running so pulled it into hash
ec2.describeInstances(ec2params, function(err, appdata) {
if (err) {
console.log(err);
return;
}
else {
var apparray={};
for(var i = 0; i < appdata.Reservations.length; i++) {
var ins = appdata.Reservations[i].Instances[0];
var id = ins.InstanceId;
var state = ins.State.Name;
apparray[id]=state;
}
console.log(apparray);
context.succeed(apparray);
}
});
rds.describeDBInstances(rdsparams, function(err, data) {
if (err) {
console.log(err, err.stack);
return;
}
else {
var rdsarray={};
var rdsarray=(data);
console.log(rdsarray);
var ins=rdsarray[0];
var name = ins.ReadReplicaDBInstanceIdentifiers[0];
rdsarray[replicant]=name;
}
context.succeed(rdsarray);
});
//context.done();
};
I want to return my filtered (apparray) and (rdsarray) back from my functions and perform a calculation on this within the main body of the script. Any ideas on how to do this.
something like
var replicas = rdsarray.length for example
Thanks in advance
var aws = require('aws-sdk');
var ec2 = new aws.EC2();
var rds = new aws.RDS();
aws.config.region = 'us-east-1';
exports.handler = function(event, context) {
if (event) {
console.log(event.id);
}
//setup params for rds call
var rdsparams = {
DBInstanceIdentifier: 'master',
};
//setup params for ec2 call
var ec2params = {
Filters: [{
Name: 'tag:role',
Values: [
'app'
],
}]
};
//Get ec2 instances with app tag, may need to add a condition on running so pulled it into hash
ec2.describeInstances(ec2params, function(err, appdata) {
if (err)
return context.done(err, null);
var apparray = {};
for (var i = 0; i < appdata.Reservations.length; i++) {
var ins = appdata.Reservations[i].Instances[0];
var id = ins.InstanceId;
var state = ins.State.Name;
apparray[id] = state;
}
console.log(apparray);
var resultData = {};
resultData.apparray = apparray;
rds.describeDBInstances(rdsparams, function(err, data) {
if (err)
return context.done(err, null);
var rdsarray = {};
var rdsarray = (data);
console.log(rdsarray);
var ins = rdsarray[0];
var name = ins.ReadReplicaDBInstanceIdentifiers[0];
rdsarray[replicant] = name;
resultData.rdsarray = rdsarray;
context.done(null, resultData);
});
});
};
and back in the code from you are calling the lambda function
var lambda = new sdk.Lambda();
var params = {
FunctionName: 'arn:aws:lambda:us-west-2:1541546477777:function:MyFunction',
Payload: JSON.stringify(/*your params here*/)
};
lambda.invoke(params, function(err, data) {
if (err) {
console.log('error ===', err);
return ;
}
var lambdaData = JSON.parse(data.Payload);
// do your stuff here
});
Is this what you needed? It may be broken but I hope you get the idea of it
I have created WebSocket.js but unfortunately I am unable to test it due to unavailability of data. The requirement is the data comes from various sources so I have multiple sockets for that. Note: I want to particularly test my socket.onMessage behaves for different sockets. Please find the code snippet below:
var webSocket;
var txQueue = [];
var defaultReconnectTimeout = 1000; //will be multiplied by 2 and saved into reconnectTimeout on each try
var reconnectTimeout = defaultReconnectTimeout;
var registerWebSocketHandlers = function(webSocket) {
webSocket.onclose = function(){
setTimeout(service.reopen, reconnectTimeout *= 2);
};
webSocket.onopen = function(e) {
reconnectTimeout = defaultReconnectTimeout; //reset this
deferredSend();
};
webSocket.onerror = function(e) {
throw new Error("[WebSocket] An error occured " + e);
};
}
var uniqid = function() {
return (new Date().getTime()).toString(16);
}
var deferredSend = function() {
if(!service.isOpen()) {
$timeout(deferredSend, 100);
return;
}
while(txQueue.length && service.isOpen()) {
var payload = txQueue.shift();
webSocket.send(typeof payload === 'string' ? payload : JSON.stringify(payload));
}
};
var createNewWebSocketInstance = function(apiUrl){
var websocket = new $window.WebSocket(apiUrl);
websocket.id = uniqid();
return websocket;
}
// TODO: this is a bit hacky since we directly bind it to the raw window event
$window.onbeforeunload = function(e) {
service.close();
};
var service = {};
service.setMessageEventHandler = function(name,cb) {
instances[name].onmessage = function(msg) {
if(msg.data.indexOf('Status: connected') === 0)
{
return;
}
var jsonObj = JSON.parse(msg.data);
cb(jsonObj);
};
};
service.isOpen = function() {
return webSocket.readyState === 1;
};
service.send = function(msg) {
txQueue.push(msg);
deferredSend();
};
service.close = function() {
return webSocket.close();
};
service.reopen = function() {
// get old message handler
var msgHandler = webSocket.onmessage;
// try closing the previous WebSocket
service.close();
// open new WebSocket
openConnection();
// re-attach old handler to new WebSocket
webSocket.onmessage = msgHandler;
};
service.getId = function() {
return webSocket.id;
}
// Returns an already existing instance of the socket, if unavailable then creates a new one.
service.getInstance = function(name, config) {
if(!(name in instances)) {
instances[name] = createNewWebSocketInstance(config);
}
registerWebSocketHandlers(instances[name]);
return instances[name];
};
return service;
You can test WebSocket using websocket.html at websocket.org Echo Test Creating your own test
Using a text editor, copy the following code and save it as
websocket.html somewhere on your hard drive. Then simply open it in a browser. The page will automatically connect, send a message,
display the response, and close the connection.
See Linux - WebSocket test error.
I am writing a chrome extension using indexedDB and want to use sendMessage to pass data from the background page to the popup.
If the button is pressed, a message is sent from popup to background, and a response should be written to the 'results' div.
the logging messages are all ok, but no response is sent from within the 'openRequest.onsuccess' block.
I am not sure why the response is not received from openRequest.onsuccess yet the console message just after it is written.
output from console.log;
popup;
processMessage() - 2
background;
processMessage() - 2
processMessage() - 1
content of 'results';
processMessage() - 2
popup.js
var popupInst;
var popupPage = function() {
var mThis = this;
this.msg;
this.init = function() {
document.querySelector('#btnAdd').addEventListener('click', this.add);
};
this.add = function() {
chrome.extension.sendMessage({ add: { keyName: 'key', valueName: 'value' }}, function(response) {
mThis.msg = (response.msg)
console.log(mThis.msg);
$('#results').empty().append(mThis.msg);
});
};
}
document.addEventListener('DOMContentLoaded', function(){popupInst = new popupPage(); popupInst.init();});
background.js
var bgInst;
var backgroundPage = function()
{
var mThis = this;
this.dbName = 'test-db';
this.db;
this.init = function() {
var openRequest = window.indexedDB.open(mThis.dbName,1);
openRequest.onsuccess = function(evt) {
this.db = openRequest.result;
};
openRequest.onupgradeneeded = function(evt) {
var objStore = evt.target.result.createObjectStore(this.dbName,{keyPath:"keyName"});
objStore.createIndex("keyName","keyName",{unique:true});
objStore.createIndex("valueName","valueName",{unique:false});
};
chrome.extension.onMessage.addListener(this.processMessage);
};
this.processMessage = function(msgRequest,msgSender,msgCallback) {
if(msgRequest.add) {
var openRequest = window.indexedDB.open(mThis.dbName);
openRequest.onsuccess = function(evt) {
var str1 = 'processMessage() - 1';
msgCallback({ msg: str1 }); -> this message is never received in popup.js
console.log(str1); -> but this message is written to the log
};
var str2 = 'processMessage() - 2';
msgCallback({ msg: str2 });
console.log(str2);
}
};
}
document.addEventListener('DOMContentLoaded', function(){bgInst = new backgroundPage(); bgInst.init();});
So, I'm developing a javascript + api forum software. My point in this is so that you can read a forum while offline -- this involves HTML5's offline-storage. In particular, I would like to use IndexedDB as it seems to be the most promising for the future. I've gotten a good service/factory for fetching / temporarily storing the data, but IDDB is broken majorly. Does anybody have advice on how to go about this?
edit Also, for anybody who would like a hosted version, here it is on cloud9.
var angular = angular || {};
(function(w){
w.localStorage = w.localStorage||{};
w.indexedDB = w.indexedDB || w.mozIndexedDB || w.webkitIndexedDB || w.msIndexedDB || null;
w.IDBTransaction = w.IDBTransaction || w.webkitIDBTransaction || w.msIDBTransaction || null;
w.IDBKeyRange = w.IDBKeyRange || w.webkitIDBKeyRange || w.msIDBKeyRange || null;
})(this);
angular.module("JSForumServices",[],function($provide){
$provide.factory('ForumStorage',(function(){
var service = {
post:null,
thread:null,
board:null,
cache:{},
pending:{}
};
var fetch = (function(baseFunction,path,callback){
if(path in service.pending)
return service.pending[path];
var r=baseFunction();
service.pending[path] = r;
var ajaxRequest = new XMLHttpRequest();
var cancelled = false;
var dateRegex =
/^(?:(Sun|Mon|Tue|Wed|Thu|Fri|Sat),\s+)?(0[1-9]|[1-2]?[0-9]|3[01])\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+(19[0-9]{2}|[2-9][0-9]{3})\s+(2[0-3]|[0-1][0-9]):([0-5][0-9])(?::(60|[0-5][0-9]))?\s+([-\+][0-9]{2}[0-5][0-9]|(?:UT|GMT|(?:E|C|M|P)(?:ST|DT)|[A-IK-Z]))(\s+|\(([^\(\)]+|\\\(|\\\))*\))*$/;
ajaxRequest.onreadystatechange = (function(){
var readyState = ajaxRequest.readyState;
if(readyState==4&&(!cancelled)){
// Store the copy locally!
// Also, initiate the callback.
// This way if the storage fails,
// The application continues to work
// As expected.
var data = JSON.parse(ajaxRequest.responseText);
for(var k in data)
r[k] = data[k];
service.cache[path]={obj:r,modified:new Date()};
delete service.pending[path];
callback(r);
}
else if((path in service.cache)&&readyState>=2){
var oldDate = service.cache[path].modified;
console.log("Cache'd copy for",path,"exists.",oldDate.toString());
var isMoreRecent = false;//Is the server-copy more recent?
var serverModifiedString = ajaxRequest.getResponseHeader("Last-Modified");
console.log(serverModifiedString);
var match = dateRegex.exec(serverModifiedString);
var serverModified = new Date();
serverModified.setDate(parseInt(match[2],10));
serverModified.setMonth({
"jan":0,
"feb":1,
"mar":2,
"apr":3,
"may":4,
"jun":5,
"jul":6,
"aug":7,
"sep":8,
"oct":9,
"nov":10,
"dec":11
}[match[3].toLowerCase()]);
serverModified.setYear(parseInt(match[4],10));
serverModified.setHours(parseInt(match[5],10));
serverModified.setMinutes(parseInt(match[6],10));
serverModified.setMilliseconds(parseInt(match[7],10));
isMoreRecent = serverModified > oldDate;
if(!isMoreRecent&&(path in service.pending)){//sometimes this code may be slower than network speeds? Just to be safe, I guess.
cancelled=true;
var oldObject = service.cache[path].obj;
for(var key in oldObject)
r[key]=oldObject[key];
console.log("using a cache'd value.",r);
callback(r);
delete service.pending[path];
ajaxRequest.abort();//No need to waste more bandwidth!
}
}
});
ajaxRequest.open("GET",path,true);
ajaxRequest.send();
return r;
});
var ObjectFetch = (function(base,constr){
var ret = (function(id,cb){
cb = cb||(function(){});
return fetch(constr,base+id+".json",cb);
});
return ret;
});
service.post = ObjectFetch("./post/",(function(){
return {
id:"???",
author:"???",
content:"",
date:""
};
}));
service.thread = ObjectFetch("./thread/",(function(){
return {
id:"???",
title:"???",
posts:[],
tags:""
};
}));
service.board = ObjectFetch("./board/",(function(){
return {
id:"???",
title:"???",
threads:[],
tags:""
};
}));
service.forum = ObjectFetch("./",(function(){
return {
name:"Javascript Forum Software.",
boards:[]
};
}));
if(window.indexedDB!==null){
var postFetch = service.post;
var threadFetch = service.thread;
var boardFetch = service.board;
(function(dbengine){
var boardsLoaded = false;
var threadsLoaded = false;
var postsLoaded = false;
var req = dbengine.open("forum",1);
req.onupgradeneeded = (function(e){
var db = e.target.result;
db.createObjectStore("post",{
keyPath:"id"
});
db.createObjectStore("thread",{
keyPath:"id"
});
db.createObjectStore("board",{
keyPath:"id"
});
});
req.onsuccess = (function(e){
service.database = e.target.result;
var loadData = service.database.transaction([
'board',
'thread',
'post'],'readwrite');
loadData.onsuccess = (function(ee){
var transaction = ee.target.result;
transaction.objectStore("board").openCursor().onsuccess=(function(e){
var cursor = e.target.result;
if(cursor===null){
boardsLoaded = true;
return;
}
var id = cursor.key;
var obj = cursor.value;
var lastModified = new Date();
if("lastModified" in obj){
lastModified = obj.lastModified;
}
service.cache["./board/"+id.toString().toLowerCase()+".json"]={
obj:obj,
modified:lastModified
};
});
transaction.objectStore("thread").openCursor().onsuccess=(function(e){
var cursor = e.target.result;
if(cursor===null){
threadsLoaded = true;
return;
}
var id = cursor.key;
var obj = cursor.value;
var lastModified = new Date();
if("lastModified" in obj){
lastModified = obj.lastModified;
}
service.cache["./thread/"+id.toString().toLowerCase()+".json"]={
obj:obj,
modified:lastModified
};
});
transaction.objectStore("post").openCursor().onsuccess=(function(e){
var cursor = e.target.result;
if(cursor===null){
postsLoaded = true;
return;
}
var id = cursor.key;
var obj = cursor.value;
var lastModified = new Date();
if("lastModified" in obj){
lastModified = obj.lastModified;
}
service.cache["./post/"+id.toString().toLowerCase()+".json"]={
obj:obj,
modified:lastModified
};
});
service.post = (function(id,cb){
console.log("DDDDDAFF");
var trans = service.database.transaction(["post"],"readwrite");
trans.onsuccess = (function(e){
var req = e.target.result.objectStore("post").get(id);
req.onsuccess = (function(ee){
cb(req.result);
});
req.onerror = (function(ee){
console.log("HAAAA?!");
postFetch(id,(function(post){
e.target.result.objcetStore.save(post);
cb(post);
}));
});
});
trans.onerror = (function(e){
console.log("Error with IDDB:",e);
threadFetch(id,cb);
});
});
service.thread = (function(id,cb){
var trans = service.database.transaction(["thread"],"readwrite");
trans.onsuccess = (function(e){
var req = e.target.result.objectStore("thread").get(id);
req.onsuccess = (function(ee){
cb(req.result);
});
req.onerror = (function(ee){
threadFetch(id,(function(post){
e.target.result.objcetStore.save(post);
cb(post);
}));
});
});
trans.onerror = (function(e){
console.log("Error with IDDB:",e);
postFetch(id,cb);
});
});
service.board = (function(id,cb){
var trans = service.database.transaction(["board"],"readwrite");
trans.onsuccess = (function(e){
var req = e.target.result.objectStore("board").get(id);
req.onsuccess = (function(ee){
cb(req.result);
});
req.onerror = (function(ee){
boardFetch(id,(function(post){
e.target.result.objcetStore.save(post);
cb(post);
}));
});
});
trans.onerror = (function(e){
console.log("Error with IDDB:",e);
boardFetch(id,cb);
});
});
});
});
})(window.indexedDB);
}
return service;
}));
});
angular.module('JSForum',["JSForumServices"]).config(
['$routeProvider',
function($routeProvider){
$routeProvider.when('/',{
templateUrl:"forum.html",
controller:ForumController
});
$routeProvider.when('/board/:id',{
templateUrl:"board.html",
controller:BoardController
});
$routeProvider.when('/thread/:id',{
templateUrl:"thread.html",
controller:ThreadController
});
$routeProvider.otherwise({redirectTo:"/"});
}]);
function ThreadController($scope,$routeParams,ForumStorage){
$scope.id = $routeParams.id.toString().toLowerCase();
$scope.thread = null;
ForumStorage.thread($scope.id,(function(thread){
$scope.thread = thread;
$scope.$apply();
var callback = (function(p){
return (function(post){
$scope.thread.posts[p] = post;
$scope.$apply();
});
});
for(var i=0;i<thread.posts.length;i++)
if(typeof(thread.posts[i].id) == 'undefined')
ForumStorage.post(thread.posts[i],callback(i));
$scope.$apply();
}));
}
function BoardController($scope,$routeParams,ForumStorage){
$scope.id = $routeParams.id.toString().toLowerCase();
$scope.board = null;
ForumStorage.board($scope.id,(function(board){
var callback = (function(p){
return (function(thread){
$scope.board.threads[p] = thread;
$scope.$apply();
});
});
$scope.board = board;
console.log("Using board:",$scope.board);
for(var i=0;i<board.threads.length;i++)
if(typeof(board.threads[i].id)=='undefined')
ForumStorage.thread(board.threads[i],callback(i));
$scope.$apply();
}));
}
function ForumController($scope,ForumStorage){
$scope.name = localStorage.forumName||"Forum";
$scope.boards = [];
ForumStorage.forum("forum",(function(forum){
document.title = $scope.name = localStorage.forumName = forum.name;
$scope.boards = forum.boards;
var callback=(function(p){
return (function(o){
$scope.boards[p] = o;
$scope.$apply();
});
});
for(var i=0;i<$scope.boards.length;i++){
if(typeof($scope.boards[i].id) == 'undefined')
ForumStorage.board(forum.boards[i],callback(i));
}
$scope.$apply();
}));
}
If your backend is google cloud storage, you can use my open source database library http://dev.yathit.com/api-reference/ydn-db/storage.html It cached in IndexedDB and persist to blob store. forum post URI path is taken as primary key of the record. LastModified header value is persisted into IndexedDB and used for conditional HTTP request. since blob store can only be queried by ascending order of key (URI path), forum post URI path are generated so that the last post is the smallest. In this way, we can query new posts by giving smallest known key as marker.
An example can be found in https://bitbucket.org/ytkyaw/ydn-auth/src/master/examples/note-app/note-app.js (not forum, but a simple note app). you need a backend server that generate signed url for posting new record.
I'm trying to build a small class-like container that will make it a little cleaner to load and store data from the HTML5 IndexedDB. To be honest this is the first time I've ever played with this feature, so my issue could be trivial.
I'm basing my code off of this tutorial:
http://www.html5rocks.com/en/tutorials/indexeddb/todo/
function DBDictionary()
{
this.Holder = {};
this.Entries = new Array();
this.Opened = false;
this.v = "1.0";
this.Holder.indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB;
if ('webkitIndexedDB' in window)
{
window.IDBTransaction = window.webkitIDBTransaction;
window.IDBKeyRange = window.webkitIDBKeyRange;
}
this.Holder.indexedDB = {};
this.Holder.indexedDB.db = null;
this.Holder.indexedDB.onerror = function(e)
{
console.log(e);
};
this.DownloadDB = function()
{
if(this.Opened) return;
var request = this.Holder.indexedDB.open("Storage");
request.onsuccess = function(e)
{
this.Holder.indexedDB.db = e.target.result;
var db = this.Holder.indexedDB.db;
// We can only create Object stores in a setVersion transaction;
if (v!= db.version)
{
var setVrequest = db.setVersion(v);
// onsuccess is the only place we can create Object Stores
setVrequest.onerror = this.Holder.indexedDB.onerror;
setVrequest.onsuccess = function(e)
{
if(db.objectStoreNames.contains("Storage")) db.deleteObjectStore("Storage");
var store = db.createObjectStore("Storage", {keyPath: "Key"});
this.PopulateAll();
};
}
else
{
this.PopulateAll();
}
};
request.onerror = this.Holder.indexedDB.onerror;
};
this.UploadDB = function()
{
this.DeleteAll();
this.SaveAll();
};
this.DeleteAll = function()
{
var db = this.Holder.indexedDB.db;
var trans = db.transaction(["Storage"], IDBTransaction.READ_WRITE);
var store = trans.objectStore("Storage");
Entries.forEach(function(element, index, array)
{
var request = store.delete(index);
request.onerror = function(e)
{
console.log("Error Deleting: ", e);
};
});
};
this.PopulateAll = function()
{
var db = this.Holder.indexedDB.db;
var trans = db.transaction(["Storage"], IDBTransaction.READ_WRITE);
var store = trans.objectStore("Storage");
// Get everything in the store;
var keyRange = IDBKeyRange.lowerBound(0);
var cursorRequest = store.openCursor(keyRange);
cursorRequest.onsuccess = function(e)
{
var result = e.target.result;
//No more results to load
if(!!result == false)
{
if(!this.Opened) this.Opened = true;
return;
}
this.Entries[result.Key] = result.Value;
result.continue();
};
cursorRequest.onerror = this.Holder.indexedDB.onerror;
};
this.SaveAll = function()
{
var db = this.Holder.indexedDB.db;
var trans = db.transaction(["Storage"], IDBTransaction.READ_WRITE);
var store = trans.objectStore("Storage");
Entries.forEach(function(element, index, array)
{
var data = {
"Key": index,
"Value": element,
"timeStamp": new Date().getTime()
};
var request = store.put(data);
request.onerror = function(e) {
console.log("Error Adding: ", e);
};
});
};
}
function main()
{
var dictionary = new DBDictionary();
dictionary.DownloadDB();
dictionary.Entries["hello"] = "world";
alert(dictionary.Entries["hello"]);
}
$(document).ready(main);
My desired implemented state should look something like this:
function main()
{
var dictionary = new DBDictionary();
dictionary.DownloadDB();
dictionary.Entries["hello"] = "world";
alert(dictionary.Entries["hello"]);
}
$(document).ready(main);
What this should do is download the data from the browser's IndexedDB object and store them into the object-housed array Entries. When I want to store the value of Entires back into the DB, I would call dictionary.UploadDB();
However, I'm getting the single javascript error: Uncaught TypeError: Object # has no method 'open'. I'm pretty much at a loss as to what I'm doing wrong. Can anyone offer me some tips?
Do a typeof check and console.log the this.Holder.indexedDB object to inspect the prototype. Does it inherit the IDBDatabase prototype? If it does, the open method would be available to you.
If your window.indexedDB did fire the on success callback, e.target.result would be the correct way to access the newly opened database via the event object. But the fact that you're not getting that far suggests that your this.Holder.indexedDB object is not actually an instance of an IDBDatabase.
EDIT: Yes, this is exactly your issue. If you console.log the this.holder.indexedDB object you get an object that looks like {"db":null}.
Swap this.Holder.indexedDB for window.webkitIndexedDB at your open invocation and you'll see that 'world' alert pops. JSFiddle here.