12 June 2014
PDF (527 KB)
 
Franck Barillaud

Franck Barillaud

Power Development Cloud Architect

@fbarilla on Twitter

John A. Jacobson

John A. Jacobson

IBM Cloud Technical Specialist

@jjacobso on Twitter
Follow me on G+

IBM Bluemix services enable you to provision resources, called service instances, on demand — for example, databases on a multitenant server or accounts on a SaaS application. You can provision services as either managed services (available through the Bluemix catalog) or user-provided (external) services. When you use a user-provided service instance, you can:

  • Avoid hard-coding credentials for a service instance into your application.
  • Treat the user-provided service instance exactly like a managed service instance.

Bluemix does not currently support managed services created by end users. Bluemix provides an onboarding process for enabling third-party managed services.

This article shows you how to build and deploy a web-based application on Bluemix and bind it to both a managed Bluemix database service and an external POWER8™-based database service. You'll start with a sample Node.js application (the polling application from Joe Lennon's article "Build a real-time polls application with Node.js, Express, AngularJS, and MongoDB") and — working in Eclipse — customize it to use an external POWER 8-based service. Although the external asset in this example is a MongoDB database, it could be any external asset that you want to provide as a service.

READ:Cloud Foundry Developer Guide: Using Services

When you use a user-provided service instance, you can avoid hard-coding credentials for a service instance into your application.

What you'll need for your application

 
  • A x86 PC running Ubuntu 12.04
  • Familiarity with basic Eclipse functionality
  • An IBM DevOps Services account
  • A Bluemix account
  • An understanding of how to create a Power Development Platform (PDP) reservation
  • Familiarity with Site Ox

Step 1. Set up the development environment on your PC

 
  1. Install MongoDB:
    sudo apt-get install mongodb-server
  2. Configure MongoDB to listen on remote IP addresses. Edit the /etc/mongodb.conf file and update it to:
    # bind_ip = 127.0.0.1 
    bind_ip = 0.0.0.0 
    port = 27017
  3. Install alien:
    sudo apt-get install alien
  4. Install and test the Cloud Foundry command-line interface (CLI):
    1. cd ~
      mkdir CF
      cd CF
    2. On the Cloud Foundry CLI GitHub repository page, click Debian 64 bit and save the package to the CF directory.
    3. Install:
      sudo alien -i cf-cli_amd64.deb
    4. Test the Bluemix connection:
      cf login -a https://api.ng.bluemix.net
  5. Install Eclipse Kepler on Ubuntu 12.04.3 using the steps outlined on the Eclipse website.
  6. Install the Eclipse Marketplace Client:
    1. In Eclipse, click Help > Install New Software.
    2. In the Work with field, enter the update site http://download.eclipse.org/releases/kepler.
    3. Filter on marketplace and press Enter to load the contents of the update site.
    4. Select the Marketplace Client 1.2.1.v20140219 check box.
    5. Click Next and accept the license terms.
    6. Click Finish to install the plug-in. If you are warned that you're installing software that contains unsigned content, click OK to continue.
    7. Restart Eclipse for the changes to take effect.
  7. Install the Node.js environment:
    1. In Eclipse, click Help > Eclipse Marketplace.
    2. In the Eclipse Marketplace window, in the Find field, enter node.js.
    3. After the results are displayed, in the section for Enide Studio 2014 — Node.js, JavaScript and Java 0.11-preview, click Install.
  8. Install Express. (For an obscure reason, the standard Ubuntu version of npm doesn't work on Ubuntu 12.04.3 64-bit, so you must reinstall it.)
    sudo apt-get purge nodejs npm
    sudo apt-get update
    sudo apt-get install -y python-software-properties python g++ make
    sudo add-apt-repository ppa:chris-lea/node.js
    sudo apt-get update
    sudo apt-get install nodejs

    Check the installed versions of node and npm:
    node -v
        v0.10.28
    npm -v
        1.4.9
    sudo npm install -g express
  9. When the IDE is up and running again, install the Cloud Foundry plug-in:
    1. In Eclipse, click Help > Eclipse Marketplace.
    2. In the Eclipse Marketplace window, in the Find field, enter Cloud Foundry.
    3. After the results are displayed, in the section for Cloud Foundry Integration for Eclipse 1.6.1, click Install.
    4. On the Confirm Selected Features page, click Confirm.
    5. Accept the terms and click Finish.
    6. If you are required to restart Eclipse, click Yes.
  10. Build a basic Express back end:
    1. In the Eclipse IDE, create a new Node Express project from the Node perspective. Keep the Jade check box marked. When the process completes, Eclipse will download the npm required packages and create a simple Express application.
    2. Edit the views/layout.jade file and change doctype 5 to doctype html.
  11. Run the Express app:
    1. In the Eclipse Project Explorer, right-click app.js and from the context menu, choose Run As > Node Application. A web server is started and the application is deployed on it.
    2. Open http://localhost:3000 in your browser to view the Express application.

Your environment setup is complete, and you can start building the polling web application.

Step 2: Import the poll demo code into Eclipse and test it with MongoDB

 

This section describes the testing of the poll demo with MongoDB in a variety of environments: local x86 development environment, POWER8 on Power Development Platform, and POWER on SiteOx.

Download the demo code from Joe Lennon's polls project on DevOps Services:

Load the code into Eclipse. You can do this in various ways (a topic that is out of this article's scope); one way is to Import the code as a file system.

Test the poll demo with MongoDB (x86)

 

This section describes testing the poll demo on your local x86 development environment.

  1. In Project Explorer, right-click package.json and choose Run As > npm install to install the npm modules and any additional dependencies.
  2. When installation is done, find app.js in the root of your project, right-click, and choose Run As -> Node Application. Now a browser opened at http://localhost:3000 displays the polling app: Screen shot of the original poll demo app

Test the poll demo with MongoDB (POWER8 on PDP using VPN)

 

This section describes testing the poll demo with the Node.js application on your local development environment accessing MongoDB on Power in the Power Development Platform (PDP).

For more information on creating a PDP reservation, visit the IBM Power Development Cloud.

  1. Use the Power Development Platform (PDP) to create an Ubuntu 14.04 reservation. Establish the VPN connection to the PDP and connect to the reservation:
  2. Install MongoDB:
    sudo apt-get install mongodb-server
  3. Stop MongoDB:
    sudo /etc/init.d/mongodb stop
  4. Change the IP address binding:
    sudo vi /etc/mongodb.conf
  5. Change the loopback address to the IP address of the system:
    #bind_ip = 127.0.0.1
        bind_ip = 172.29.160.120  (IP address of the PDP Virtual Server)
  6. Open MongoDB Port (27017) on the Iptables firewall:
    sudo iptables -I INPUT -p tcp -m state --state NEW,ESTABLISHED --dport 27017 -j ACCEPT
  7. Start MongoDB:
    sudo /etc/init.d/mongodb start
  8. Check which port MongoDB is listening on:
    sudo lsof -iTCP -sTCP:LISTEN | grep mongo
  9. Edit the routes/index.js file and change the mongoose.createConnection() statement to point to the remote MongoDB instance running on Power (mongodb://172.29.160.120:27017/pollsapp) :
    if (process.env.VCAP_SERVICES) {
       var env = JSON.parse(process.env.VCAP_SERVICES);
       db = mongoose.createConnection(env['mongodb-2.2'][0].credentials.url);
    } else {
       // db = mongoose.createConnection('localhost', 'pollsapp');
       db = mongoose.createConnection('mongodb://172.29.160.120:27017/pollsapp');
    }
  10. Select app.js in the root of your project, right-click, and choose Run As > Node Application. Now a browser opened at http://localhost:3000 displays a fresh instance of the polling app: Screen shot of UI for creating a new poll
  11. Test that the environment is fully working by creating a new poll: Screen shot of creating a new poll
  12. Test the poll and view the results: Screen shot of poll results

Test the poll demo with MongoDB (Power on Site Ox using SSH tunnel)

 

This section describes testing the poll demo with the Node.js application on your local development environment accessing MongoDB on Power in SiteOx.

  1. Request a free Ubuntu on Power trial from Site Ox. When the reservation is up and running, install MongoDB:
    sudo apt-get install mongodb-server
  2. Open an SSH tunnel:
    ssh -L 27017:localhost:27017 -p 20322 rawa@lop.siteox.com
  3. Edit the routes/index.js file and change the mongoose.createConnection() statement back to the original:
    if (process.env.VCAP_SERVICES) {
       var env = JSON.parse(process.env.VCAP_SERVICES);
       db = mongoose.createConnection(env['mongodb-2.2'][0].credentials.url);
    } else {
       db = mongoose.createConnection('localhost', 'pollsapp');
    }
  4. Select app.js in the root of your project, right-click, and choose Run As -> Node Application. Now a browser opened at http://localhost:3000 displays the UI for creating a new poll.
  5. Create a new poll to test that the environment is fully working.

Configure the demo to create a SSH tunnel

While we were able to successfully test the poll demo accessing MongoDB on Ubuntu Power trial from SiteOx, we first had to establish an SSH tunnel which prompted us for a password. To configure this tunnel as part of the application, we need to exchange SSH keys that allow passwordless login between the local x86 development environment and the Ubuntu Power trial on SiteOx.

  1. Install SSH keys between the client and the Site Ox server. On the client:
    ssh-keygen -t rsa
    scp .ssh/id_rsa.pub server
  2. On the user's home directory on the server:
    mkdir .ssh
    chmod 0700 .ssh
    cp id_rsa.pub .ssh/authorized_keys
    chmod 0600 .ssh/authorized_keys
  3. On the client, log in to the server with your password. Then log out and run ssh-add.
  4. Now you can connect to your Site Ox server without entering the login information:
    ssh -X -p 20322 rawa@lop.siteox.com
  5. In the Eclipse Project Explorer, open the views/index.js file. Add the following piece of code at the top of the file to configure the tunnel:
    //create the SSL tunnel
    var exec = require('child_process').exec, child;
    
    child = exec('ssh -L 27017:localhost:27017 -p 20322 rawa@lop.siteox.com',
        function (error, stdout, stderr) {
            console.log('stdout: ' + stdout);
            console.log('stderr: ' + stderr);
            if (error !== null) {
                 console.log('exec error: ' + error);
            }
        });
    
    function sleep(milliseconds) {
      var start = new Date().getTime();
      for (var i = 0; i < 1e7; i++) {
        if ((new Date().getTime() - start) > milliseconds){
          break;
        }
      }
    }
    
    // wait 20 seconds for the tunnel to be created.
    sleep(20000);

Okay, okay, values in this code are hard-coded. Our goal here is not to go into details on how to set up a tunnel programatically but how to get a proof of concept running. A few Node.js packages (ssltunnel, ssh2, node-control) include all the logic for setting up a tunnel and managing SSH connections.

Step 3. Push the application to Bluemix and bind it with the Bluemix MongoDB service

 

While the previous steps discussed the local deployment of the poll demo with various MongoDB connections, this step describes the deployment of the application to BlueMix leveraging the node.js runtime and MongoDB service.

  1. Log in to Bluemix:
    cf login -a https://api.ng.bluemix.net
  2. Create an instance of the MongoDB service:
    cf create-service mongodb 100 pollsapp
  3. From the Eclipse directory, push the app without starting it:
    cd ~/workspace/Bluemix     (where the Eclipse project has been created)
    cf push simple-poll --no-manifest --no-start -c 'node app.js'
  4. Bind the MongoDB service to the new app:
    cf bind-service simple-poll pollsapp
    cf push simple-poll
  5. Start the application:
    cf start simple-poll
  6. Log in to Bluemix. In the dashboard for your app, click the application URL to open the application running on Bluemix.

Step 4. Push the application to Bluemix and bind it with MongoDB on POWER8 as a user-provided service (running outside of Bluemix)

 

Finally, the moment we've been waiting for. This is where we deploy the poll demo leveraging the Node.js runtime in BlueMix, accessing the user-provided MongoDB service on the Ubuntu Linux trial from SiteOx. But first, we need to make some changes to the project.

  1. If the application is still running on Bluemix, go to the Bluemix dashboard and manually remove the application and its associated services.
  2. You can't set up any SSH keys in Bluemix to connect transparently to the remote server, so you must make additional modifications to your application code.
    Run Install pty.js. Then, in Project Explorer, edit package.json and add the pty dependency:
    "dependencies": {
          "express": "3.4.3",
            "socket.io": "~0.9.16",
            "jade": "*",
            "pty": "*",
            "mongoose": ">= 3.8.0"
      }
  3. Right-click package.json in Project Explorer and choose Run As > npm install to install the npm modules and any additional dependencies.
  4. Update the application code to support an SSH connection to the remote POWER8 service:
    1. Create a new ssh folder in Project Explorer. In the ssh directory, create a new conn.js file that will set up an SSH tunnel:

      Click to see code listing

      console.log('Starting SSH connection');
      
      var pty = require("pty");
      var term;
      var password;
      
      if (process.env.VCAP_SERVICES) {
          var env = JSON.parse(process.env.VCAP_SERVICES);
          var user = (env['user-provided'][0].credentials.username);
          password = (env['user-provided'][0].credentials.password);
          var port = (env['user-provided'][0].credentials.port);
          var host = (env['user-provided'][0].credentials.host);
          
          console.log('Connection information: ' + 'user: ' +user+ ' password: 
      '+password+ ' host: '+host+ ' port: '+port );
          
          var fullport = '-p '+port;
          var address = user+'@'+host;
          
          term = pty.spawn("ssh", ['-L', '27017:localhost:27017', fullport,  address]);
          
      }else{
          term = pty.spawn("ssh", ['-L', '27017:localhost:27017', '-p 20322',  'rawa@50.241.203.177']);
      }
      
      var auth = false;
      
      term.on("data", function(data) {
      console.log("Incoming: " + data.toString());
      
      if (data.toString().indexOf("yes") !=-1) {
          term.write("yes\n");
          console.log("Accepting keys");
          }
      
      var passwdStr = password+'\n';
      
      if (data.toString().indexOf("password") !=-1) {
                 term.write(passwdStr);
                 console.log("Password sent");
                 auth=true;
          }
      });
    2. Modify the routes/index.js file for the MongoDB connections:
      // // Connect to MongoDB using Mongoose
      var mongoose = require('mongoose');
      var db = mongoose.createConnection('localhost', 'pollsapp');
    3. Modify the apps.js file to start the SSH tunnel before starting the application:
      /*jshint node:true*/
      
      function sshConn() {
          var conn = require('./ssh/conn.js');
      }
          
      function loadApp() {    
          var express = require('express');
          var routes = require('./routes');
          var http = require('http');
          var path = require('path');
          var app = express();
          var server = http.createServer(app);
          var io = require('socket.io').listen(server);
          
          app.set('port', process.env.VCAP_APP_PORT || 3000);
          app.set('views', path.join(__dirname, 'views'));
          app.set('view engine', 'jade');
          app.use(express.favicon());
          app.use(express.logger('dev'));
          app.use(express.bodyParser());
          app.use(express.methodOverride());
          app.use(app.router);
          app.use(express.static(path.join(__dirname, 'public')));
          
          // Handle Errors gracefully
          app.use(function(err, req, res, next) {
              if(!err) return next();
              console.log(err.stack);
              res.json({error: true});
          });
          
          // Main App Page
          app.get('/', routes.index);
          
          // MongoDB API Routes
          app.get('/polls/polls', routes.list);
          app.get('/polls/:id', routes.poll);
          app.post('/polls', routes.create);
          app.post('/vote', routes.vote);
          
          io.sockets.on('connection', routes.vote);
          
          server.listen(app.get('port'), function(){
            console.log('Express server listening on port ' + app.get('port'));
          });
      }
      
      //Async tasks 
      function async(arg, callback) {
          if(arg == 1){
              console.log('Connect using SSH');
              sshConn();
          }
          if(arg == 2){
              console.log('Load application');
              loadApp();
          }
          // setTimeout(function() { callback(arg * 2); }, 10000);
          setTimeout(function() { callback(arg); }, 10000);
      }
      
      // A simple async series:
      var items = [ 1, 2 ];
      function series(item) {
        if(item) {
          async( item, function(result) {
            return series(items.shift());
          });
        } 
      }
      series(items.shift());
    4. Save all the files.

Now we are ready to push the application to BlueMix.

Push the new code to Bluemix

 
  1. Log in to Bluemix.
  2. From the Eclipse directory, push the app without starting it:
    cd ~/workspace/Bluemix     (where the Eclipse project has been created)
    cf push simple-poll --no-manifest --no-start -c 'node app.js'
  3. Check the logs:
    cf logs simple-poll --recent
  4. Create a user-provided service:
    cf cups MongoDB-Site-OX -p "host, port, username, password" 
    
    host> 50.241.203.177 
    port> 20322 
    username> rawa 
    password> hit1miss 
    Creating user provided service MongoDB-Site-OX in org 
    fbarilla@us.ibm.com / space dev as fbarilla@us.ibm.com... 
    OK
  5. List services:
    cf services 
    
    Getting services in org fbarilla@us.ibm.com / space dev as fbarilla@us.ibm.com... 
    OK 
    
    name              service         plan   bound apps   
    MongoDB-Site-OX   user-provided
  6. Bind the service to the application:
    cf bind-service simple-poll MongoDB-Site-OX 
    Binding service MongoDB-Site-OX to app simple-poll 
    in org fbarilla@us.ibm.com / space dev as fbarilla@us.ibm.com... 
    OK 
    TIP: Use 'cf push' to ensure your env variable changes take effect
  7. Push the app again so that the binding takes effect:
    cf push simple-poll --no-manifest --no-start -c 'node app.js'
  8. To verify that the service instance is now recorded in VCAP_SERVICES, click the simple-poll... link: Screen shot of the original poll demo app
  9. Then click on the Quick Docs link to view the user credentials for the MongoDB service.
  10. Start the simple-poll application from the BluemixGUI and then check the logs:
    cf logs simple-poll recent
    Screen shot of ap startup on Ubuntu
  11. Click the simple-poll.ng.bluemix.net link, which takes you directly to the application.

Done!

Conclusion

 

You've completed the following tasks:

  • Set up the development environment using Eclipse.
  • Test the application with MongoDB running on x86.
  • Test the application with MongoDB running on POWER8 on PDP using VPN.
  • Test the application with MongoDB running on Power on Site Ox using an SSH tunnel.
  • Bind the application to MongoDB running in the Bluemix environment.
  • Bind the application to MongoDB running on POWER8 outside of the Bluemix environment.

You can also create an application from scratch and push it to Bluemix to take advantage of external user-provided services.


RELATED TOPICS:Node.jsEclipsePOWER8

Add a comment

Note: HTML elements are not supported within comments.


1000 characters left

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Cloud computing, Linux
ArticleID=973778
ArticleTitle=Use POWER8 services on IBM Bluemix
publish-date=06122014