Rock N’ Roll with Bluemix, Cloudant & NodeExpress


In this post I create a  cloud application that is based on Bluemix, Cloudant DB and NodeExpress.  NodeExpress is used to perform DB operations on  CloudantDB

The code can be forked from Devops from bluemix-cloudant-exp. You can also clone the code from Github from bluemix-cloudant-exp

The following NodeExpress routes are created for performing the basic database operations

  1. a) Displaying the list of books
  2. b) Adding a book
  3. c) Updating a book and
  4. d) Deleting a book

1

 

Push the app to Bluemix

a) Push the app to Bluemix using
cf push bluemix-cloudant -p . -m 512M

b) In the Bluemix dashboard add the Cloudant service.

c) Double click the CloudantNoSQLDB

9

and then click the ‘Launch’ button. This will bring the WebSQL based version of Cloudant DB

10

c) Next click the link bluemix-cloudant.mybluemix.net

11

This will start the Webserver and also populate the database.

e) This can be seen in the Cloudant Dashboard for the ‘test’ database which has 3 records shown below
12
The setup for these routes in the NodeExpress are as follows

app.get('/', routes.index);
app.get('/booklist', booklist.list);
app.get('/newbook', newbook.list);
app.post('/addbook',addbook.list);
app.get('/changebook', changebook.list);
app.post('/updatebook', updatebook.list);
app.get('/rembook', rembook.list);
app.post('/deletebook',deletebook.list);

Setting up the environment for Cloudant’s PouchDB

The first thing is to setup the environment for Cloudant’s Pouch DB by parsing the process.env environment variables as shown below

//Parse the process.env for the port and host that we've been assigned
if (process.env.VCAP_SERVICES) {
// Running on Bluemix. Parse the port and host that we've been assigned.
var env = JSON.parse(process.env.VCAP_SERVICES);
var host = process.env.VCAP_APP_HOST;
var port = process.env.VCAP_APP_PORT;
console.log('VCAP_SERVICES: %s', process.env.VCAP_SERVICES);
// Also parse Cloudant settings.
var cloudant = env['cloudantNoSQLDB'][0]['credentials'];
}
var db = new pouchdb('books'),
remote =cloudant.url + '/books';
opts = {
continuous: true
};
// Replicate the DB to remote
console.log(remote);
db.replicate.to(remote, opts);
db.replicate.from(remote, opts);

Displaying the list of books

Cloudant responds to DB queries as JSON messages. Hence to display the list of books the fields of each document is stored as an array and then displayed using the Jade table in booklist.jade  This is shown below

  1. a) booklist.js

var docs = db.allDocs(function(err, response) {
val = response.total_rows;
var details = "";
j=0;
var booklist = new Array(val);
for(i=0; i < val; i++) {
db.get(response.rows[i].id, function (err,doc){
j++;
booklist[j] = new Array(3);
booklist[j][0] = doc._id;
booklist[j][1] = doc.Title;
booklist[j][2] = doc.author;
details= details + JSON.stringify(doc.Title) + "  " +  JSON.stringify(doc.author) + "\n";
// Kludge because of Node.js asynchronous handling. To be fixed - T V Ganesh
if(j == val) {
res.render('booklist', {
"booklist" : booklist
});
}
}); // End db.get
} //End for
}); // End db.allDocs

  1. b) booklist.jade

The jade template simply displays the each booklist as a row in a table

block content
h1= "Display the list of books"
p
strong DocId  Title   Author
table
each book, i in booklist
tr
td #{book}
p
p
a(href='/') Home

2

Adding a book
To add a book the book details are obtained using the newbook.jade which display a form
block content
h1= "Add a book"
form#formAddBook(name="addbook",method="post",action="/addbook")
input#inputBookTitle(type="text", placeholder="Title", name="title")
input#inputBookAuthor(type="text", placeholder="Author", name="author")
button#btnSubmit(type="submit") submit
a(href='/') Home

With the values obtained from the form above a document is inserted into the books database as follows

// Get our form values. These rely on the "name" attributes
var Title = req.body.title;
var Author = req.body.author;
db.put({
author: Author,
Title : Title,
}, Title, function (err, response) {
console.log(err || response);
if (err) {
// If it failed, return error
res.send("There was a problem adding the information to the database.");
}
else {
// Redirect to booklist - Display booklist
res.location("booklist");
// And forward to success page
res.redirect("booklist");
}
});

Note: When inserting a document into the books database the docid for the document is set to be the same as the book Title itself

7

4

Updating a book

To update a document we need to input the document id. Also the document to be updated should use the “_rev” field which is obtained when we get the document. The values to be input are taken with the changeuser form

block content

h1= "Update a book"
form#formUpdateBook(name="addbook",method="post",action="/updatebook")
input#inputDocId(type="text", placeholder="DocId", name="docid")
input#inputBookTitle(type="text", placeholder="Title", name="title")
input#inputBookAuthor(type="text", placeholder="Author", name="author")
button#btnSubmit(type="submit") submit
a(href='/') Home

The values obtained are used to populate the document as follows

db.get(DocId, function(err, response) {
db.put({
_id: DocId,
_rev: response._rev,
author: Author,
Title : Title,
}, function(err, response) {
if (err) {
// If it failed, return error
res.send("There was a problem updating the information to the database.");
}
else {
// If it worked, redirect to display books
res.location("booklist");
// And forward to success page
res.redirect("booklist");
}
});
});

6

5

Deleting a document

To delete a document we need the document id which is taken with the rembook.jade form

block content
h1= "Delete a book"
form#formDeleteBook(name="addbook",method="post",action="/deletebook")
input#DocId(type="text", placeholder="DocId", name="docid")
button#btnSubmit(type="submit") submit
a(href='/') Home

//Deleting document book1
db.get(DocId, function(err, doc) {
db.remove(doc, function(err, response) {
if (err) {
// If it failed, return error
res.send("There was a problem removing the information to the database.");
}
else {
// Redirect to booklist
res.location("booklist");
// And forward to success page
res.redirect("booklist");
}
console.log(err || response);
});
});

In the diagram below docid ‘book3′ is deleted

13

8

Important tips

  1. If you run into issues while create a Jade template then do the following

npm install jade --g

You can check your jade template for correctness using

jade <name of jade template>

If the response is ‘rendered <name of jade template>.html’ then the template is fine.

  1. If there are problems with deploying the application or if the application crashes you check the cf logs as follows for the issue

cf logs <name of application> --recent

As mentioned the  code can be forked from Devops from bluemix-cloudant-exp. You can also clone the code from Github from bluemix-cloudant-exp

Disclaimer: This article represents the author’s viewpoint only and doesn’t necessarily represent IBM’s positions, strategies or opinions


Find me on Google+

A Cloud medley with IBM Bluemix, Cloudant DB and Node.js


Here is an interesting Cloud medley based on IBM’s Bluemix PaaS platform, Cloudant DB and Node.js. This application  creates a Webserver using Node.js and uses REST APIs to perform CRUD operations on a Cloudant DB. Cloudant DB is a NoSQL Database as a service (DBaaS) that can handle a wide variety of data types like JSON, full text and geo-spatial data. The documents  are stored, indexed and distributed across a elastic datastore spanning racks, datacenters and perform replication of data across datacenters.Cloudant  allows one to work with self-describing JSON documents through  RESTful APIs making every document in the Cloudant database accessible as JSON via a URL.

This application on Bluemix uses REST APIs to perform the operations of inserting, updating, deleting and listing documents on the Cloudant DB.  The code can be forked from Devops at bluemix-cloudant. The code can also be clone from GitHub at bluemix-cloudant.

1) Once the code is forked the application can be deployed on to Bluemix using

cf login -a https://api.ng.bluemix.net
cf push bm-cloudant -p . -m 512M

2) After this is successful go to the Bluemix dashboard and add the Cloudant DB service.  The CRUD operations can be performed by invoking REST API calls using an appropriate REST client like SureUtils ot Postman in the browser of your choice.

Here are the details of the Bluemix-Cloudant application

3) Once the Cloudant DB service has been added to the Web started Node.js application we need to parse the process.env variable to obtain the URL of the Cloudant DB and the port and host to be used for the Web server.

The Node.js Webserver is started based on the port and host values obtained from process.env

require('http').createServer(function(req, res) {
//Set up the DB connection
if (process.env.VCAP_SERVICES) {
// Running on Bluemix. Parse for  the port and host that we've been assigned.
var env = JSON.parse(process.env.VCAP_SERVICES);
var host = process.env.VCAP_APP_HOST;
var port = process.env.VCAP_APP_PORT;
....
}
....
// Perform CRUD operations through REST APIs
// Insert document
if(req.method == 'POST') {
insert_records(req,res);
}
// List documents
else if(req.method == 'GET') {
list_records(req,res);
}
// Update a document
else if(req.method == 'PUT') {
update_records(req,res);
}
// Delete a document
else if(req.method == 'DELETE') {
delete_record(req,res);
}
}).listen(port, host);

2) Access to the Cloudant DB Access to Cloudant DB is obtained as follows

if (process.env.VCAP_SERVICES) {
// Running on Bluemix. Parse the port and host that we've been assigned.
var env = JSON.parse(process.env.VCAP_SERVICES);
var host = process.env.VCAP_APP_HOST;
var port = process.env.VCAP_APP_PORT;
console.log('VCAP_SERVICES: %s', process.env.VCAP_SERVICES);
// Also parse Cloudant settings.
var cloudant = env['cloudantNoSQLDB'][0]['credentials'];
}
var db = new pouchdb('books'),
remote =cloudant.url + '/books';
opts = {
continuous: true
};
// Replicate the DB to remote
console.log(remote);
db.replicate.to(remote, opts);
db.replicate.from(remote, opts);

Access to the Cloudant DB is through the cloudant.url shown above

3)  Once the access to the DB is setup we can perform CRUD operations. There are many options for the backend DB. In this application I have PouchDB.

4) Inserting a document: To insert documents into the Cloudant DB based on Pouch DB we need to do the following

var insert_records = function(req, res) {
//Parse the process.env for the port and host that we've been assigned
if (process.env.VCAP_SERVICES) {
// Running on Bluemix. Parse the port and host that we've been assigned.
var env = JSON.parse(process.env.VCAP_SERVICES);
var host = process.env.VCAP_APP_HOST;
var port = process.env.VCAP_APP_PORT;
console.log('VCAP_SERVICES: %s', process.env.VCAP_SERVICES);
// Also parse Cloudant settings.
var cloudant = env['cloudantNoSQLDB'][0]['credentials'];
}
var db = new pouchdb('books'),
remote =cloudant.url + '/books';
opts = {
continuous: true
};
// Replicate the DB to remote
console.log(remote);
db.replicate.to(remote, opts);
db.replicate.from(remote, opts);
// Put 3 documents into the DB
db.put({
author: 'John Grisham',
Title : 'The Firm'
}, 'book1', function (err, response) {
console.log(err || response);
});
...
...
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write("3 documents is inserted");
res.end();
}; // End insert_records

The nice part about Cloudant DB is that you can access your database through the URL. The steps are shown below. Once your application is running. Click on your application. You should see the screen as below.

1

Click on Cloudant as shown by the arrow.

Next click on the “Launch’ icon

2

This should bring up the Cloudant dashboard. The database will be empty.

3

If you use a REST API Client to send a POST API call then the Application will insert 3 documents.

4

The documents inserted can be seen by sending the GET REST API call.

5

The nice part of Cloudant DB is that you can use the URL to see your database. If you refresh your screen you should see the “books” database added. Clicking this database you should see the 3 documents that have been added

6

If you click “Edit doc” you should see the details of the document

7

5) Updating a document

The process to update a document in the database is shown below

// Update book3
db.get('book3', function(err, response) {
console.log(response);
return db.put({
_id: 'book3',
_rev: response._rev,
author: response.author,
Title : 'The da Vinci Code',
});
}, function(err, response) {
if (err) {
console.log("error " + err);
} else {
console.log("Success " + response);
}
});

This is performed with a PUT REST API call

8

The updated list is shown below

9

This can be further verified in the Cloudant DB dashboard for book3.

10

6) Deleting a document

The code to delete a document in PouchDB is shown below

//Deleting document book1
db.get('book1', function(err, doc) {
db.remove(doc, function(err, response) {
console.log(err || response);
});
});

The REST calls to delete a document and the result  are shown below

11

12

Checking the Cloudant dashboard we see that only book2 & book3 are present and book1 has been deleted

13

7) Displaying documents in the database

The code for displaying the list of documents is shown below

var docs = db.allDocs(function(err, response) {
val = response.total_rows;
var details = "";
j=0;
for(i=0; i < val; i++) {
db.get(response.rows[i].id, function (err,doc){
j++;
details= details + JSON.stringify(doc.Title) + " by  " +  JSON.stringify(doc.author) + "\n";
// Kludge because of Node.js asynchronous handling. To be fixed - T V Ganesh
if(j == val) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write(details);
res.end();
console.log(details);
}
}); // End db.get
} //End for
}); // End db.allDocs

If you happened to notice, I had to use a kludge to work around Node.js’ idiosyncracy of handling asynchronous calls. I was fooled by the remarkable similarity of Node.js & hence  javascript to C language that I thought functions within functions would work sequentially. However I had undergo much grief  trying to get Node.js to work sequentially. I wanted to avoid the ‘async’ module but was unsuccessful with trying to code callbacks. So the kludge! I will work this out eventually but this workaround will have to do for now!

As always you can use the “Files and Logs” in the Bluemix dashboard to get any output that are written to stdout.

Note: As always I can’t tell how useful the command
'cf  logs <application name> -- recent is for debugging.

Hope you enjoyed this Cloud Medley of Bluemix, Cloudant and Node.js!

Disclaimer: This article represents the author’s viewpoint only and doesn’t necessarily represent IBM’s positions, strategies or opinions


Find me on Google+

Spicing up a IBM Bluemix cloud app with MongoDB and NodeExpress


In this post I highlight the rudiments for a creating a cloud application on IBM’s PaaS offering Bluemix, using MongoDB and NodeExpress.   Clearly Bluemix allows one to fire up a cloud application with a NoSQL database in a matter of  a few hours which makes it really attractive. The NodeExpress  application was initially created using Enide Studio for Node.js  with a local Mongodb server running on my desktop. (Please see my post Elements of CRUD with Node Express and MongoDB) Once you have ironed out the issues in this local application you are ready to deploy on IBM Bluemix.

The code for this Bluemix application can be forked from bluemix-mongo from IBM Devops.

You can also clone the code from GitHub at bluemix-mongo

Here are the key changes that need to be made for running the NodeExpress Webserver with MongoDB as the backend DB

1) Webserver : Setup the port and host for the Webserver.

  1. app.js

var port = (process.env.VCAP_APP_PORT || 1337);
var host = (process.env.VCAP_APP_HOST || '0.0.0.0');
var app = express();
app.configure(function(){
app.set('port', port);

As seen above the host & port for the Webserver are obtained from the process.env variable.
2) Routes and Middleware
Setup the routes and invoke them appropriately in app.js
var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, userlist = require('./routes/userlist')
, newuser = require('./routes/newuser')
, adduser = require('./routes/adduser')
, changeuser = require('./routes/changeuser')
, updateuser = require('./routes/updateuser')
, remuser = require('./routes/remuser')
, deleteuser = require('./routes/deleteuser')

app.get('/users', user.list);
app.get('/helloworld', routes.index);
app.get('/userlist', userlist.list);
app.get('/newuser', newuser.list);
app.post('/adduser',adduser.list);
app.get('/changeuser', changeuser.list);
app.post('/updateuser', updateuser.list);
app.get('/remuser', remuser.list);
app.post('/deleteuser',deleteuser.list);

3) Initialize MongoDB database: Create a set of 3 records when the Webserver starts as follows

if (process.env.VCAP_SERVICES) {
var env = JSON.parse(process.env.VCAP_SERVICES);
if (env['mongodb-2.2']) {
var mongo = env['mongodb-2.2'][0]['credentials'];
}
} else {
var mongo = {
"username" : "user1",
"password" : "secret",
"url" : "mongodb://user1:secret@localhost:27017/test"
}
}
var MongoClient = mongodb.MongoClient;
var db= MongoClient.connect(mongo.url, function(err, db) {
if(err) {
log("failed to connect to the database");
} else {
log("connected to database");
}
var collection = db.collection('phonebook');
//Clear DB and insert 3 records
remove(mycallback);
var user1 = { "FirstName" : "Tinniam", "LastName" : "Ganesh","Mobile": "916732177728" };
var user2 = { "FirstName" : "Darth", "LastName" : "Vader","Mobile": "6666699999" };
var user3 = { "FirstName" : "Bill", "LastName" : "Shakespeare","Mobile": "8342189991" };

  1. insert(user1,function(err,result){});
  2. insert(user2,function(err,result){});
  3. insert(user3,function(err,result){});
  4. find().toArray(function(err, items) {

});
});

3) Home Page: Setup up a Home page with the CRUD operations when the Bluemix cloud application’s route  for e.g. http://bluemix-mongo.mybluemix.net is clicked. This is shown below.

1

 

2

4) Display Users: To display the list of users the route /userlist is invoked. This function gets all the records from the collection and stores them into a toArray element, which is then used for rendering the list of uses with a ‘userlist.jade’ template

userlist.js
var MongoClient = mongodb.MongoClient;
var db= MongoClient.connect(mongo.url, function(err, db) {
if(err) {

  1. log(“Failed to connect to the database”);

} else {

  1. log(“Connected to database”);

}
var collection = db.collection(‘phonebook’);
//Get all records and display them

  1. find().toArray(function(err, items) {
  2.    log(items);
  3. render(‘userlist’, {

“userlist” : items
});
});
});

  1. jade

This template displays the list of users as a table. The code is shown below

extends layout
block content
h1= "Display the list of Users"
p
strong Firstname Lastname   Mobile
table
each user, i in userlist
tr
td #{user.FirstName}
td #{user.LastName}
td #{user.Mobile}
p
p
a(href='/') Home

Note: A link back to the Home page is included in here at the bottom.

7

 

5) Adding a User
There are 2 parts to this
a) Invoking the /newuser route to display the input form through the newuser.jade
b) Invoking the /adduser route to insert the values entered in the form. The changes are shown below
a) app.js
..
newuser = require('./routes/newuser')
adduser = require('./routes/adduser')
..
app.get('/newuser', newuser.list);
app.post('/adduser',adduser.list);

b) newuser.js
exports.list = function(req, res){

  1. render(‘newuser’, { title: ‘Add User’});

};

The newuser jade displays the input form
c) newuser.jade
extends layout
block content
h1= "Add a User"
form#formAddUser(name="adduser",method="post",action="/adduser")
input#inputUserFirstName(type="text", placeholder="firstname", name="firstname")
input#inputUserLastName(type="text", placeholder="lastname", name="lastname")
input#inputUserLastName(type="text", placeholder="mobile", name="mobile")
button#btnSubmit(type="submit") submit
p
p
a(href='/') Home

3

d) adduser.js

The adduser.js gets the mongo url from the process.env.VCAP_SERVICES and  setups up the connection to the DB and inserts the values received in the ‘newuser.jade’ form into the database

exports.list = function(req, res) {
if (process.env.VCAP_SERVICES) {
var env = JSON.parse(process.env.VCAP_SERVICES);
if (env['mongodb-2.2']) {
var mongo = env['mongodb-2.2'][0]['credentials'];
}
} else {
var mongo = {
"username" : "user1",
"password" : "secret",
"url" : "mongodb://user1:secret@localhost:27017/test"
}
}
// Set up the DB connection
var MongoClient = mongodb.MongoClient;
var db= MongoClient.connect(mongo.url, function(err, db) {
if(err) {

  1. log(“Failed to connect to the database”);

} else {

  1. log(“Connected to database”);

}
// Get our form values. These rely on the “name” attributes
var FirstName = req.body.firstname;
var LastName = req.body.lastname;
var Mobile = req.body.mobile;
// Set our collection
var collection = db.collection(‘phonebook’);
// Insert the record into the DB

  1. insert({

“FirstName” : FirstName,
“LastName” : LastName,
“Mobile” : Mobile
}, function (err, doc) {
if (err) {
// If it failed, return error

  1. send(“There was a problem adding the information to the database.”);

}
else {
// Redirect to userlist – Display users

  1. location(“userlist”);

// And forward to success page

  1. redirect(“userlist”);

}
});
});

If the insert is successful the userlist page is displayed with the new user

4

6) Updating a User & Deleting a User: Updating and Deleting users follow the same format as Adding a user.

7) index.jade The Home page is built using index.jade with a hyperlink invoking the route for each database operation
extends layout
block content
h1= title
p Welcome to #{title}
ul
li
a(href='/userlist') Display list of users
li
a(href='/newuser') Add a user
li
a(href='/changeuser') Update a user
li
a(href='/remuser') Delete a user

Tip: “Return of the Jadei : Getting the jade template right is truly an art as Jade is extremely finicky about spaces, tabs, indents and outdents(???). Creating the Jade template had me run into circles. I found out that you can debug the jade template individually by executing

C:> npm install jade -g"
and then  running
C:> jade <template name>

from the command prompt. If the result of the command is “rendered <template name>.html” then you are in luck and you can incorporate this jade template into your views folder for e.g.

C: >jade index.jade
rendered index.html

8) Push changes to Bluemix: Once the changes have been made push the changes on to Bluemix with ‘cf’ as follows

cf login -a https://api.ng.bluemix.net
cf push bluemix-mongo -p . -m 512M
cf create-service mongodb 100 mongodb01
cf bind-service bluemix-mongo mongodb01

 

The last 2 commands can also be performed through the Bluemix dashboard in which you add the mongodb service to your Node.js app/

8) Files and Logs: In the Bluemix dashboard you can check your logs in the Files and Logs

5

 

6

Important tip: Finally if the application fails to start when you  push the application with ‘cf’ for e.g.

cf push <app name> -p . -m 512M
....
.....
----> Writing a custom .npmrc to circumvent npm bugs
----> Installing dependencies
----> Caching node_modules directory for future builds
----> Cleaning up node-gyp and npm artifacts
----> No Procfile found; Adding npm start to new Procfile
----> Building runtime environment
----> Checking and configuring service extensions
----> Uploading droplet (7.6M)
of 1 instances running, 1 down
of 1 instances running, 1 down
of 1 instances running, 1 down
of 1 instances running, 1 down

or if  it crashes when you click a link then your debugging friend is

cf logs <app name > — recent
This will dump the error that was encountered either while the application was being started of why the application crashed.

You can fork this Bluemix application from bluemix-mongo at  IBM Devops or from GitHub at bluemix-mongo

Disclaimer: This article represents the author’s viewpoint only and doesn’t necessarily represent IBM’s positions, strategies or opinions


Find me on Google+

Elements of CRUD with NodeExpress and MongoDB using Enide Studio


In this post I perform basic CRUD operations using NodeExpress and MongoDB with Enide Studio. There is not a whole lot of information in the Web on using Node Express with Enide Studio so the task was kind of difficult. Anyway I managed to get basic CRUD operations to work. The complete code can be cloned from nodeexpress-mongo.

Here it is.

1) To get started create a new Node Express project with Enide Studio File->New->NodeExpress Project.

2) This should create the necessary files, routes and views.

3) Start the MongoDB as follows

mongod –dbpath <folder of project>

4) Start the mongo console. To get started I created 3 records as follows

mongo>
db.phonebook.insert({ "FirstName" : "Tinniam", "LastName" : "Ganesh","Mobile": "916732177728" })
db.phonebook.insert({ "FirstName" : "Darth", "Lastname" : "Vader","Mobile": "6666699999" })
db.phonebook.insert({ "FirstName" : "Bill", "Lastname" : "Shakespeare","Mobile": "8342189991" })

5) You can display the added records with

> db.phonebook.find().pretty()
{
"_id" : ObjectId("53de3f8e0e7f8abf82c0c850"),
"FirstName" : "Tinniam",
"LastName" : "Ganesh",
"Mobile" : "916732177728"
}
{
"_id" : ObjectId("53de3fed0e7f8abf82c0c851"),
"FirstName" : "Darth",
"Lastname" : "Vader",
"Mobile" : "6666699999"
}
{
"_id" : ObjectId("53de40200e7f8abf82c0c852"),
"FirstName" : "Bill",
"Lastname" : "Shakespeare",
"Mobile" : "8342189991"

6) For each of the CRUD operations there are 4 components

- Set the route
– Invoke app.get/app.post as approriate
– Call the necessary route Javascript file
– Use the appropriate Jade constructs for rendering the output

7) Here are the changes for the Display of the users

A) Displaying the User
a) app.js
..
userlist = require('./routes/userlist')
..
app.get('/userlist', userlist.list);
..

var mongodb = require(‘mongodb’);

b) userlist.js

/* GET Phone users page. */
exports.list =  function(req, res) {
// var db = req.db;
var MongoClient = mongodb.MongoClient;
var db= MongoClient.connect("mongodb://localhost:27017/test", function(err, db) {
if(err) {

  1. log(“Failed to connect to the database”);

} else {

  1. log(“Connected to database”);

}
var collection = db.collection(‘phonebook’);

  1. find().toArray(function(err, items) {
  2.    log(items);
  3. render(‘userlist’, {

“userlist” : items
});
});
});
};

c) userlist.jade
extends layout
block content
h1= "Display the list of Users"
p
strong Firstname Lastname   Mobile
table
each user, i in userlist
tr
td #{user.FirstName}
td #{user.LastName}
td #{user.Mobile}
p
p
a(href='http://localhost:3000') Home

This is shown below

2

 

B) Adding a User

There are 2 parts to this

a) Invoking the /newuser route to display the input form
b) Invoking the /adduser route to insert the values entered in the form. The changes are shown below

a) app.js
..
newuser = require('./routes/newuser')
adduser = require('./routes/adduser')
..
app.get('/newuser', newuser.list);
app.post('/adduser',adduser.list);

These require the following

b) newuser.js

exports.list = function(req, res){

  1. render(‘newuser’, { title: ‘Add User’});

};

The newuser jade displays the input form

c) newuser.jade

block content
h1= "Add a User"
form#formAddUser(name="adduser",method="post",action="/adduser")
input#inputUserFirstName(type="text", placeholder="firstname", name="firstname")
input#inputUserLastName(type="text", placeholder="lastname", name="lastname")
input#inputUserLastName(type="text", placeholder="mobile", name="mobile")
button#btnSubmit(type="submit") submit
p
p
a(href='http://localhost:3000') Home

3

The /adduser route inserts the record into the phonebook collection as shown

d) adduser.js

var FirstName = req.body.firstname;
var LastName = req.body.lastname;
var Mobile = req.body.mobile;
// Set our collection
var collection = db.collection('phonebook');
// Insert the record into the DB

  1. insert({

“FirstName” : FirstName,
“LastName” : LastName,
“Mobile” : Mobile
}, function (err, doc) {
if (err) {
// If it failed, return error

  1. send(“There was a problem adding the information to the database.”);

}
else {
// If it worked, redirect to userlist – Display users

  1. location(“userlist”);

// And forward to success page

  1. redirect(“userlist”);

}
});

This takes us  back to Display users if it successfully added the user

4

C) Updating a User and Deleting a User are similar to Adding a User

D) Index page

All the actions are included in the index.jade as shown below with hyperlinks

p Welcome to #{title}
ul
li
a(href='http://localhost:3000/userlist') Display list of users
li
a(href='http://localhost:3000/newuser') Add a user
li
a(href='http://localhost:3000/changeuser') Update a user
li
a(href='http://localhost:3000/remuser') Delete a user

5

Important tip:
Here is an important note. I found that getting the jade template right extremely frustrating. It is really unforgiving and is very picky up indents, outdents(whatever that is!), tabs and spaces. A quick way to check whether your jade template is fine or not is to install jade in your project directory.

npm install jade –global
You can debug your jade with
If there an error you will get

c:> jade userlist.jade
throw e
^
TypeError: userlist.jade:6
4|   h1= title
5|   ul
> 6|      each user, i in userlist
7|         li
8|           #{user.FirstName}
Cannot read property 'length' of undefined
at eval (eval at <anonymous>

If there are no errors you should see that the html is rendered as below

C: >jade index.jade
rendered index.html

You can clone the complete code from GitHub at nodeexpress-mongo


Find me on Google+

A Bluemix recipe with MongoDB and Node.js


Here is a tasty IBM Bluemix recipe with a dash of MongoDB and a pinch of Node.js. This posts shows the steps needed to perform basic CRUD (Create, Remove, Update & Delete) operations on the MongoDB database using REST APIs of PUT,GET, UPDATE & DELETE.

You can fork the code for the below app from Devops at mymongodb

The code can also be cloned from GitHub at mymongodb

For this,  the first  thing we need to do is to create a Webserver using Node.js as shown below

Webserver

require('http').createServer(function(req, res) {
if ( typeof mongodb !== 'undefined' && mongodb ) {
// Perform CRUD operations through REST APIs
if(req.method == 'POST') {
insert_records(req,res);
}
else if(req.method == 'GET') {
list_records(req,res);
}
else if(req.method == 'PUT') {
update_records(req,res);
}
else if(req.method == 'DELETE') {
delete_record(req,res);
}
} else {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write("No MongoDB service instance is bound.\n");
res.end();
}
}).listen(port, host);

The Webserver users the port and host values obtained as shown above to wait for  HTTP requests.

The REST API calls are handled by individual  Node.js functions to perform the operations of insert, update, delete and select.

Insertions

The code for insertions is shown below. For this a set of 5 documents are created and then inserted using Node.js

var insert_records = function(req, res) {
var MongoClient = require('mongodb').MongoClient;
// Connect to the db
MongoClient.connect (mongo.url, function(err, db) {
//Create a collection test
var collection = db.collection('books', function(err, collection) {
//Create a set of documents to insert
var book1 = { book: "The Firm", author: "John Grisham", qty: 3 };
var book2 = { book: "Foundation", author: "Isaac Asimov", qty: 5 };
collection.remove(mycallback);
//Insert the books
console.log("Insert the books");
collection.insert(book1,function(err,result){});
collection.insert(book2, {w:1}, function(err, result) {
});
collection.insert(book5, {w:1}, function(err, result) {});
console.log('Inserted 5 books');
}); //var collection
}); // End MongoClient.connect
}; // End insert_records

Updating documents in Mongodb

For update 2 documents are changed as shown below

var update_records = function(req, res) {
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect (mongo.url, function(err, db) {
// Update
var collection = db.collection('books', function(err, collection) {
collection.update({book:"Fountainhead"},{$set:{qty:2}}, {w:1},function(err,result) {});
collection.update({book:"Animal Farm"},{$set:{author:"George Orwell"}}, {w:1},function(err,result) {});
console.log("Updated 2 books");

}); // var collection
}); //End MongoClient.connect

}; //End update-records

Deletions

The delete functions requires a callback method which is included

var delete_record = function(req, res) {
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect (mongo.url, function(err, db) {

//Deleting documents
var collection = db.collection(‘books’, function(err, collection) {

collection.remove({book:”Foundation”},mycallback);
collection.remove({book:”The Da Vinci Code”},{w:1},mycallback);
console.log(‘Deleted 2 books’);

});
}); //End MongoClient.connect
}; //End delete-records

Retrieving documents

To retrieve documents the collection.find.stream() method is used as below

var list_records = function(req, res) {
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect (mongo.url, function(err, db) {
//Retrieve documents
var collection = db.collection('books', function(err, collection) {
var stream = collection.find().stream();
console.log("Printing values...");
res.writeHead(200, {'Content-Type': 'text/plain'});
stream.on('error', function (err) {
console.error(err.stack)
});

stream.on(“data”, function(item) {
console.log(item);
res.write(JSON.stringify(item) + “\n”);
});

stream.on(“end”, function() {
console.log(“End”);
res.end();
});
}); //var collection
}); //End MongoClient.connect

The connection between the Node.js & Webserver and the MongoDB is setup using the VCAP_SERVICES as follows

if (process.env.VCAP_SERVICES) {
var env = JSON.parse(process.env.VCAP_SERVICES);
if (env['mongodb-2.2']) {
var mongo = env['mongodb-2.2'][0]['credentials'];
}
} else {
var mongo = {
"username" : "user1",
"password" : "secret",
"url" : "mongodb://user1:secret@localhost:27017/test"
}
}

To get started you can fork the code for the above Bluemix- MongoDB app from Devops from mymongodb

The code can also be cloned from GitHub at mymongodb

After you have forked the code you can clone the code into a local directory on your machine.

Now use the ‘cf’ command to push the code onto IBM Bluemix as shown. In my case I named the app as mymongodb01

cf login -a https://api.ng.bluemix.net
cf push mymongodb01 -p . -m 512M
cf create-service mongodb 100 mongodb
cf bind-service mymongodb01 mongodb

Instead of the last 2 steps you can also use the Add-service in Bluemix dashboard to add the MongoDB service. (Note: You will have to check Experimental at the top and you will see the service under Data Management.) After the MongoDB service is added check if your app is running in the Bluemix dashboard

If the app is running you can check the CRUD operations on MongoDB using the SureUtils-REST API client extension to Chrome.

The CRUD operations performed are shown below

1.POST + GET

Here 5 documents are inserted in the MongoDB and then displayed subsequently

1

2

2.UPDATE + GET

Here 2 records are updated – The quantity of the book ‘Fountainhead’ is set to 2 and the author of ‘Animal Farm’ is set to George Orwell

3

4

3.DELETE + GET

In this set 2 book are deleted and the result is displayed

5

6

If all things went well you should be able to see the app running.

7

You can also get the output o the console.login Files and Logs in the Bluemix dashboard.

8

Important tip:  While executing the Buemix app if you run into problems and you app crashes with the “Health decreased” for your app and its colour turning red you can use the recent history of ‘cf” command to debug your problem

PS C:\Users\IBM_ADMIN\git\mymongodb> cf logs mymongodb01 –recent

Connected, dumping recent logs for app mymongodb01 in org tvganesh.85@gmail.com / space dev as tvganesh.85@gmail.com…

…….

…….

2014-07-27T11:34:26.45+0530 [App/0]   OUT We are connected to DB
2014-07-27T11:34:26.46+0530 [App/0]   OUT Updated 2 books
2014-07-27T11:34:31.17+0530 [App/0]   OUT We are connected to DB
2014-07-27T11:34:31.17+0530 [App/0]   OUT Updated 2 books
2014-07-27T11:34:31.18+0530 [RTR]     OUT mymongodb01.mybluemix.net - [27/07/2014:06:04:31 +0000] "PUT / HTTP/1.1" 200 1
7 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36" 75
.126.70.43:19986 vcap_request_id:4fa831610b6e79455d0257581a51014e response_time:0.009122768 app_id:ed49744f-1a29-4e3f-9e
1c-8b45e85c3310
2014-07-27T11:35:02.75+0530 [App/0]   ERR
2014-07-27T11:35:02.75+0530 [App/0]   ERR /home/vcap/app/app.js:95
2014-07-27T11:35:02.75+0530 [App/0]   ERR       MongoClient.connect (mongo.url, function(err, db)   {
2014-07-27T11:35:02.75+0530 [App/0]   ERR       ^
2014-07-27T11:35:02.75+0530 [App/0]   ERR ReferenceError: MongoClient is not defined
2014-07-27T11:35:02.75+0530 [App/0]   ERR     at delete_record (/home/vcap/app/app.js:95:2)
2014-07-27T11:35:02.75+0530 [App/0]   ERR     at Server.<anonymous> (/home/vcap/app/app.js:165:12)
2014-07-27T11:35:02.75+0530 [App/0]   ERR     at Server.emit (events.js:98:17)
2014-07-27T11:35:02.75+0530 [App/0]   ERR     at HTTPParser.parser.onIncoming (http.js:2108:12)
2014-07-27T11:35:02.75+0530 [App/0]   ERR     at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:121:
23)
2014-07-27T11:35:02.75+0530 [App/0]   ERR     at Socket.socket.ondata (http.js:1966:22)
2014-07-27T11:35:02.75+0530 [App/0]   ERR     at TCP.onread (net.js:527:27)
2014-07-27T11:35:02.80+0530 [RTR]     OUT mymongodb01.mybluemix.net - [27/07/2014:06:05:02 +0000] "DELETE / HTTP/1.1" Mi
ssingResponseStatusCode 0 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.19

 

Happy cooking with Bluemix, MongoDB & Node.js!

Disclaimer: This article represents the author’s viewpoint only and doesn’t necessarily represent IBM’s positions, strategies or opinions


Find me on Google+

Brewing a potion with Bluemix, PostgreSQL, Node.js in the cloud


Here is a heady potion made with the key ingredients of IBM’s Bluemix, PostgreSQL & Node.js. In this post I instantiate an app ‘mypgdb01′ on IBM’s Bluemix which uses the services of PostgreSQL in the cloud. This is shown in the picture below.

8

The mypgdb01 is a Webserver running on Node.js in Bluemix and uses the services of PostgreSQL DB. The app mypgdb01 performs basic CRUD (Create, Remove, Update & Delete) on the PostgreSQL.

The code for this can be forked from Devops  from my link mypgdb

The code can also be cloned from GitHub at mypgdb

1) This app uses the Node.js Webstarter kit and the PostgreSQL service.  The Node.js Webserver is created by parsing the VCAP services variable as usual

if (process.env.VCAP_SERVICES) {
var env = JSON.parse(process.env.VCAP_SERVICES);
var credentials = env['postgresql-9.1'][0]['credentials'];
} else {
var credentials = {"uri":"postgre://user:secret1@localhost:5433/db"}
}
var port = (process.env.VCAP_APP_PORT || 1337);
var host = (process.env.VCAP_APP_HOST || '0.0.0.0');
http.createServer(function(req, res) {
console.log("Inside Webserver");
....
....
}).listen(port, host);

The details of VCAP_SERVICES can be see by clicking Runtime for you application and is shown below

9

Note: From above it can be seen that the PostgreSQL DB’s host & port is

"host": "192.155.243.14",
"hostname": "192.155.243.14",
"port": 5433

This different from the host & port of the Node.js Webserver which  can be see in Logs & Files tab (included below) and is

Webserver: host: 0.0.0.0
port:62733

2) Once the Webserver is started the server waits for REST calls of GET,PUT, UPDATE & DELETE as shown below.

// Perform CRUD operations through REST APIs
if(req.method == 'POST') {
insert_records(req,res);
}
else if(req.method == 'GET') {
list_records(req,res);
}
else if(req.method == 'PUT') {
update_record(req,res);
}
else if(req.method == 'DELETE') {
delete_record(req,res);
}

3)  The REST API call  are implements as follows

a) POST:

var insert_records = function(req, res) {
// Connect to DB
var client = new pg.Client(credentials.uri);
client.connect(function(err) {
if (err) {
res.end("Could not connect to postgre: " + err);
}

//Drop table if it exists
client.query("DROP TABLE IF EXISTS emps");
// Creat table and insert 2 records into it
client.query("CREATE TABLE IF NOT EXISTS emps(firstname varchar(64), lastname varchar(64))");
client.query("INSERT INTO emps(firstname, lastname) values($1, $2)", ['Tinniam', 'Ganesh']);
client.query("INSERT INTO emps(firstname, lastname) values($1, $2)", ['Anand', 'Karthik']);

b) GET:

// Select all rows in the table<
var query = client.query("SELECT firstname, lastname FROM emps ORDER BY lastname, firstname");
query.on("row", function (row, result) {
result.addRow(row);
});
query.on("end", function (result) {
// On end JSONify and write the results to console and to HTML output
console.log(JSON.stringify(result.rows, null, "    "));
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write(JSON.stringify(result.rows) + "\n");
res.end();
});

c) UPDATE:

query = client.query("UPDATE emps set firstname = 'Kumar' WHERE firstname='Anand' AND lastname='Karthik'");
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write("Updated record  - Set record with firstname Anand to Kumar\n");

d)DELETE

// Delete the record where the lastname is Karthik
client.query("DELETE FROM  emps WHERE lastname = 'Karthik'");
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write("Deleted record where lastname was Karthik\n");

4) Once the changes are made you can  push the changes to Bluemix using ‘cf’ commands.

The commands are

cf login -a https://api.ng.bluemix.net
cf push mypgdb01-p . -m 512M
cf create-service postgresql 100 pgdb01
cf bind-service mypgdb01 pgdb01

5) In the Bluemix dashboard the app ‘mypgdb01′ should be up and running.

6) To invoke the different database operations we need to make REST API calls to the app.

7) To make the REST API calls you can install Sure Utils -> REST API Chrome extension.  I installed the SureUtils-.REST API Client. This is a Chrome extension and can be installed from Chrome Web Store (search for REST API client). You could choose any REST API client of your choice for the browser you intend to use (Chrome, Firefox)

8) Now we can test the Nodejs-PostgreSQL app with the Sure Utils – Chrome extension

8) The following REST API calls can be made to test the PostgreSQL operations on the database

POST- insert

1

GET – select

2

UPDATE + GET – update + select

The PUT API updates Anand Karthik to Kumar Karthik. This is shown in the GET API call

3

4

.DELETE + GET – delete  + select

5

6

 

Here the DELETE API call deletes the Kumar Karthik record. The GET API call now displays only 1 record.

The console.log output in Bluemix can be see in Files and logs -> stdout.log as shown below

7

The above post shows some basic operations done on a cloud based application that is composed of a Webserver with a PostgreSQL as a backend. The code can be enhanced by adding  front end using Node express.

As mentioned above the code for this can be forked from Devops at mypgdb. The code can also be cloned from GitHub at mypgdb

Disclaimer: This article represents the author’s viewpoint only and doesn’t necessarily represent IBM’s positions, strategies or opinions


Find me on Google+

Working with Node.js and PostgreSQL


In this post I create a simple Webserver with Node.js which uses PostgreSQL database in the backend. This post shows how to perform simple database operations of insert, select, update and delete using REST APIs (POST, GET, PUT & DELETE).

Assuming that you already have Node.js installed here are the steps to create this CRUD (Create, Remove Update & Delete) Webserver.

  1. Install Node.js if you already haven’t from Nodejs.org
  2. Create a test directory pg for this PostgreSQL based Node.js Webserver
  3. Open a command prompt and run

npm install pg

4.You will also need to install the PostgreSQL Enterprise DB with installer. Choose the appropriate OS and CPU

5.For this example I create a simple Employee Database.

6. In Windows Click Start->All Programs->PostgreSQL 9.3->pgAdmin III

7. Right click Databases-> New Database and Enter employees

1

8. The next step is to create Node.js Webserver and connect to this Database. PostgreSQL accepts DB connections through port 5432.

9.In this post The Webserver accepts connections from port 5433. Here is the shell of the Node.js Webserver

var pg = require("pg")
var http = require("http")
var port = 5433;
var host = '127.0.0.1';

http.createServer(function(req, res) {
if(req.method == 'POST') {
insert_records(req,res);
}
else if(req.method == 'GET') {
list_records(req,res);
}
else if(req.method == 'PUT') {
update_record(req,res);
}
else if(req.method == 'DELETE') {
delete_record(req,res);
}
}).listen(port,host);
console.log("Connected to " + port + "   " + host);

The Webserver accepts the usual 4 REST API calls – POST, GET, UPDATE, and DELETE for which there are 4 separate function calls.  The REST API calls correspond to the database operations insert, select, update and delete respectively.

10. Prior to performing each operation the  a client connects to the database as follows

var conString = "pg://postgres:postgres@localhost:5432/employees";
var client = new pg.Client(conString);
client.connect();

11. The POST operation is performed as follows

var insert_records = function(req, res) {


//Drop table if it exists
client.query("DROP TABLE IF EXISTS emps");
// Creat table and insert 2 records into it
client.query("CREATE TABLE IF NOT EXISTS emps(firstname varchar(64), lastname varchar(64))");
client.query("INSERT INTO emps(firstname, lastname) values($1, $2)", ['Tinniam', 'Ganesh']);
client.query("INSERT INTO emps(firstname, lastname) values($1, $2)", ['Anand', 'Karthik']);

12. To display the contents of the database the list_records function is used as follows

var list_records = function(req, res) {
console.log("In listing records");
// Select all rows in the table
var query = client.query("SELECT firstname, lastname FROM emps ORDER BY lastname, firstname");
query.on("row", function (row, result) {
result.addRow(row);
});
query.on("end", function (result) {

13. The REST API Update is performed as below

var update_record = function(req, res) {
// Update the record where the firstname is Anand
query = client.query("UPDATE emps set firstname = 'Kumar' WHERE firstname='Anand' AND lastname='Karthik'");

14.Finally a delete is performed using a delete_record method

var delete_record = function(req, res) {
// Delete the record where the lastname is Karthik
client.query("DELETE FROM  emps WHERE lastname = 'Karthik'");

15.The output of each operation is sent back as HTML  as

query.on("row", function (row, result) {
result.addRow(row);
});
query.on("end", function (result) {
// On end JSONify and write the results to console and to HTML output
console.log(JSON.stringify(result.rows, null, "    "));
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write(JSON.stringify(result.rows) + "\n");
res.end();
});

16.To test the Webserver you need to install a REST API client for the browser you use. I installed the SureUtils-.REST API Client. his is a Chrome extension nand can be installed from Chrome Web Store (search for REST API client). You could choose any REST API client of your choice for the browser you intend to use (Chrome, Firefox)

17.Here are the tests I performed

18.The POST API call

2

19. The GET API call

3

20.The PUT  call followed by GET call

4

5

The PUT API updates Anand Karthik to Kumar Karthik. This is shown in the GET API call.

21. The DELETE call followed by the GET call

Here the DELETE API call deletes the Kumar Karthik record. The GET API call now displays only 1 record.

6

7

22. The console.log output for the operations above  is shown below

8

The code for the Node.js- PostgreSQL can be cloned from GitHub at node-pg


Find me on Google+

Getting started with Node.js and Mongodb


Here is a post in which I try to get my arms around Node.js & MongoDB. This is first encounter with Web programming. There is a veritable universe of frameworks, languages, libraries and modules out there.

There are a gazillion blogs already on this topic so here is one more. When I came across Node.js recently,  I have been  impressed mightily with its ability to quickly cook up Webservers, TCP based server side programming and the like with really brief code. Another alluring fact was that it is based on Javascript which itself smacks of plain C, added to its charm. The experience with Node.js is difficult for a beginner. Also I must add that the Node.js’es callback functions takes a bit of getting used and I have had my share of pain with it.

MongoDB is an open-source document database, and one of the  leading NoSQL databases out there.

First things first – Install Node.js from Nodejs.org. Next install MongoDB for your OS and machine type. You will also need to install the mongodb module for use with Node.js. You can this by opening a command prompt and typing

npm install mongodb -g

This will allow you to access the mongodb module for use within your program. Now you should be good to go and create some basic code to manipulate MongoDB through Node.js.  This code is based on the commands from the following MongoDB wiki

Here are the steps for a basic CRUD (Create,Remove,Update & Delete) operations on MongoDB with Node.js

1. Create a folder c:\node\mongotest

2. Go to the directory where you have extracted the mongodb files and type in

mongod –dbpath c:\node\mongotest

This  will  start the database.

3. Here are the main functions of the code.

Connect to the mongodb database

var MongoClient = require('mongodb').MongoClient;
// Connect to the db
MongoClient.connect(“mongodb://localhost:27017/exampleDb”, function(err, db) {
if(!err) {
console.log(“We are connected”);
}

4. Create a collection of documents

//Create a collection test
console.log(“Creating a collection test”);
var collection = db.collection(‘test’);

5. Insert documents into the collection

//Create documents to insert
var doc1 = {‘hello':’doc1′};
var doc2 = {‘hello':’doc2′};
var lotsOfDocs = [{'hello':'doc3'}, {'hello':'doc4'}];
//Insert the docs
console.log(“Inserting the docs”);
collection.insert(doc1,function(err,result){});
collection.insert(doc2, {w:1}, function(err, result) {});

6. Update the inserted documents as follows

//Updating
var doc3 = {key:1,value:1};
collection.insert(doc3,{w:1},function(err,result) {
if(err) {
console.log(‘Could not insert’);
}
collection.update({key:1},{$set:{value:2}},{w:1},function(err,result) {});
});

7. Delete specific  documents from the database. Note: The remove() command requires a callback which I have included separately instead of the standard anonymous callback style

var mycallback = function(err,results) {
console.log(“mycallback”);
if(err) throw err;
}
//Deleting documents
console.log(“The delete operation”);
var doc4=[{key1:1},{key2:2},{key3:3}];
//Insert the document and then remove
collection.insert(doc4,{w:1},function(err,result) {
collection.remove({key1:1},mycallback);
collection.remove({key4:4},{w:1},mycallback);
});

8. Finally retrieve the inserted/updated records from the database

var stream = collection.find({mykey:{$ne:2}}).stream();
console.log(“Printing values…”);
stream.on(“data”, function(item) {
console.log(item);
});
stream.on(“end”, function() {});

The stream.on(“data”,) retrieves all the data till it encounters a stream.on(“end”).

So if I execute the above code I get the following output

C:\test \mongotest>node app3.js
We are connected
Creating a collection test
Inserting the docs
The delete operation
Printing values…
{ _id: 53c27ecbd5f4c59c1a2a5d39, hello: ‘doc1′ }
{ _id: 53c27ecbd5f4c59c1a2a5d3a, hello: ‘doc2′ }
{ _id: 53c27ecbd5f4c59c1a2a5d3b, key: 1, value: 1 }
{ _id: 53c27ecbd5f4c59c1a2a5d3c, key1: 1 }
{ _id: 53c27ecbd5f4c59c1a2a5d3d, key2: 2 }
{ _id: 53c27ecbd5f4c59c1a2a5d3e, key3: 3 }
mycallback
mycallback

The code can be cloned from Github at node-mongo


Find me on Google+

Mixing Twilio with IBM Bluemix


This post walks you through the steps to get started with Twilio on IBM’s Bluemix. Twilio comes as a service that you can add  to your Mobile Cloud or Node.js app. Here’s a quick look at Twilio. Twilio, is a cloud communications IaaS organization which  allows you use standard web languages to build voice, SMS and VOIP applications via a Web API.

Twilio provides the  ability to build VOIP applications using APIs. Twilio itself resides in the cloud and is always available. It also provides SIP integration which means that it can be integrated with Soft switches. Twilio looks really  interesting with its ability to combine the  cloud, Web and VOIP, SMS  and  the like.

This post barely scratches the surface of Twilio & Blue mix. This article provides aa hands-on experience for integration of Twilio with Bluemix and is based on this Twilio blog post. It enables you to send a SMS to your mobile phone by typing in a URL.

As in my earlier post the steps are

1) Fire-up a Node.js  Webstarter application from the  Bluemix dashboard.  In my case I have named the application websms. Once this is up and running

2) Click Add a Service and under ‘Web and Application’ choose Twilio.

3) Enter a  name for the Twilio service. You will also need the Account SID and Authorization token

4) For this go to http://www.twilio.com and sign up2

5) Once you have registered, go to your Dashboard for the Account SID and Auth Token. If the Auth token is encrypted, you can click the ‘lock’ symbol to display the Auth token in plain text.

6) Enter the Accout SID and Auth Token in the Twilio service in Bluemix

7)  To get started you can simply  fork my Twilio  websms code from devops.

8) Now clone the code into a folder you create as follows

git clone https://hub.jazz.net/git/tvganesh/websms

9) You will need to modify the following files

package.json

manifest.yml

app.js

 

10) You can create package.json by running
npm init. Make sure you enter the name of the application you created in Bluemix. In my case it is “websms’ For the rest of the options you can choose the default. Here is the package.json file
"name": "websms",
"version": "0.0.0",
"description": "This README.md file is displayed on your project page. You should edit this \r file to describe your project, including instructions for building and \r running the project, pointers to the license under which you are making the \r project available, and anything else you think would be useful for others to\r know.",
"main": "app.js",
"dependencies": {
"gopher": "^0.0.7",
"express": "^3.12.0",
"twilio": "^1.6.0",
"ejs": "^1.0.0"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "https://hub.jazz.net/git/tvganesh/websms"
},
"author": "",
"license": "ISC"
}

11) In the manifest.yml make sure you enter the name of your application and the host

applications:
- host: websms
disk: 1024M
name: websms
command: node app.js
path: .
domain: <your domain>
mem: 128M
instances: 1

12) Lastly make changes to your app.js.

// dependencies
var app = require('gopher'),
twilio = require('twilio');
var config = JSON.parse(process.env.VCAP_SERVICES);
var twilioSid, twilioToken;
config['user-provided'].forEach(function(service) {
if (service.name == 'Twilio') {
twilioSid = service.credentials.accountSID;
twilioToken = service.credentials.authToken;
}
});
// URL test
app.get('/', function(request, response) {
var client = new twilio.RestClient(twilioSid, twilioToken);
client.sendMessage({
to:'<Your mobile number>',
from:'<Number from Twilio dashboard',
body:'Twilio notification through Bluemix!'
}, function(err, message) {
response.send('Message sent! ID: '+message.sid);
});
});

13) After you have made the changes you will need to push the changes to Bluemix using the command line based ‘cf’ tool
14) Login into cf with
cf login – a http://api.ng.bluemix.net

15) Push the websms onto bluemix

16) In the folder where you websms files reside entr the following command
cf push websms -p . -m 512M

17) This should push the code to Bluemix.
Note: If you happen to get a
Server error, status code: 400, error code: 170001, message: Staging error: cannot get instances since staging failed
then you need to make sure to check the changes made to  files app.js, package.,json or the manigfest,yml.

18)  If all things went smoothly, go to your Bluemix dashboard and click the link adjacent to the Routes. You should see that an SMS has been sent as shown

3

19) Your mobile should now display the message that was sent as shown below
Screenshot_2014-06-22-13-41-44

20) Check the  analytics in your Twilio dashboard
1

Disclaimer: This article represents the author’s viewpoint only and doesn’t necessarily represent IBM’s positions, strategies or opinions

Find me on Google+

Test driving Push notification in Bluemix


This post is a continuation of my earlier post ‘Getting started with mobile cloud in Bluemix‘. Here I take a test drive of the push service that Bluemix offers based on the article “Extend an Android app using the Push cloud service” from developerWorks.

This post assumes that you have already completed the changes from my earlier post for the mobile cloud. If you haven’t,  you could clone the code from “mobile data” which is the official IBM version of this app and includes all the changes needed for persisting data in the cloud through their Android.

The Mobile Cloud App I created on Bluemix is “mobtvg“. The main steps to have Push notification service using Bluemix are

  1. GCM services : Get Google API Project number  & GCM API Key
  2. Include the Google Play services library project
  3. Add the jar files to enable Push service
  4. Modify the server side Node.js file to send push notifications to all registered devices
  5. Make necessary code changes
  6. Run the application and test for notification

Here are more details on the above steps

a) GCM services : Google Cloud Messaging for Android (GCM) is a service that allows you to send data from your server to your users’ Android-powered device, and also to receive messages from devices on the same connection. The 1st thing to do is get the Google API Project number & GCM API key.

- Click on Google Developer Console

- Click Create Project. Enter Project name & click Create.

- Note the Project Number on top of the page.

- Click API & Auth on left panel. Click API.

- Scroll down and turn-on Google Messaging for Android

-  Click credentials and click “Create new key”. Click server key. Click create

-Copy API key in the Public API access

Now go the Bluemix dashboard and click your application. Click the Push module. In the Configuration tab, scroll down to Google Cloud Messaging and  click ‘Edit’

Enter the Google API Project Number & GCM API key for both the Sandbox & Production configuration and click Save.

4
b) In Eclipse click Windows->Android SDK manager. Scroll down to the bottom and under Extras select Google Play services. Click install. Once the installation is successful import the project as follows File-Import->Android->Existing Android  code into Workspace. Click Next. In the next screen Browse to the path where your ADT bundle is installed and choose the folder

<ADT-Bundle>\ sdk\extras\google\google_play_services

and Click Ok. Also  check ‘Copy project into workspace’. This will copy.

3

Now build the Google Play Services Project. To do this the project. Click Project->Properties->Android and make sure that you select ‘Is library project’ and then click build.

5

Add a reference to the Google Play services in the Androidmanifest.xml

<meta-data

android:name=”com.google.android.gms.version”

android:value=”@integer/google_play_services_version” />

c) Make all the code changes given in Step 4 of “Extend an Android app using the Push cloud service.

d) In MainActivity.java make sure you change the app_name to the name of your app for e.g

public static final String CLASS_NAME = “MainActivity”;

public static final String APP_NAME = “mobtvg“;

Also ensure that under assets folder you have populated the Application ID in the bluemix.properties file

applicationID=<Application ID from Bluemix>

d) Add ibmcloudcode.jar, ibmpush.jar, android-support-v4.jar (from <Android_SDK_Location>/extras/android/support/v4)

e) Now the Mobile Push project need to include this library project. To do this select your Mobile App project. Click Project->Properties->Android. Click Add and select google-play-services-lib. Note: Make sure “Is library project” is unchecked otherwise you are in for a lot of grief.

8

f) Now you need to make changes to the Node.js application to push any changes from the server to all registered devices.  The code for this is in bluelist-push-node. Note; Making changes through the GUI results in an error that “manifest.yml is not in root node”. So I suggest that you take the ‘cf’ route as follows.

- Clone the code using Git

git clone https://hub.jazz.net/git/mobilecloud/bluelist-push

Go to bluelist-push-node folder

i) Open the app.js with your favorite editor and enter the Application ID of your Bluemix application

//Data Values

var values = {

version:”0.3.1″,

//change this to the actual application id of your mobile backend starter

appID : “<APPLICATION ID>”,

host : “https://mobile.ng.bluemix.net&#8221;

}

ii) Open manifest.yml and change host name & name to the name of your application for e.g.

host: mobtvg

disk: 1024M

name: mobtvg

command: node app.js

path: .

domain: ng.bluemix.net

mem: 128M

instances: 1

iii) Once the changes are complete, open a command propmpt and  login into Bluemix using ‘cf’ as follows

- cd to the directory in which Node.js & manifest.yml exist, Do

cf login – a http://api.ng.bluemix.net

cf push mobtvg -p . -m 512M

(Note the changes are pushed to the mobile cloud app on Bluemix)

This will run through and finally give the status that the app is running successfully.

f) Now that all changes are complete the Mobile Cloud with Push can be tested..

g) Click Window->Android Virtual Device Manager. Click the Device definitions. You choose Google Nexus, Nexus 7. Click Create AVD.

Note: Make sure you choose Google API Level Y and not Android x.x.x API Y.

6

Let the AVD come up and display the current items in the grocery list.

h) Login to Bluemix. Click Push and select the Notifications tab and enter a test message for e.g. “This is a notification from Bluemix” and click send.

7

This will result in a Push Notification to be sent to the AVD. You should see this popup on you AVD as shown below

1

i) Add another AVD through Windows-Android Virtual Device manager. While one AVD is running go to Run->Run Configurations->Target Device and choose the newly created AVD.

j) This will start a second AVD which will refresh with the contents of the grocery list. Now adda new item in one of AVD devices. This will result in a Push notification to the other device that the Bluelist has been updated.

2

There you have it.

1) A mobile cloud applications in which changes persist in the cloud and are refreshed each time the Android device is restarted.

2) A Push notification that is sent to all registered devices whenever there is a change to the list.

Disclaimer: This article represents the author’s viewpoint only and doesn’t necessarily represent IBM’s positions, strategies or opinions

Find me on Google+