Sunday, May 18, 2014

RabbitMQ deployment on BlueMix

RabbitMQ is open source message broker software (sometimes called message-oriented middleware) that implements the Advanced Message Queuing Protocol (AMQP). The RabbitMQ server is written in the Erlang programming language and is built on the Open Telecom Platform framework for clustering and failover. Client libraries to interface with the broker are available for all major programming languages.RabbitMQ can run all major operation systems (for example, Windows, Linux, MacOS) and supports a huge number of developer platforms (for example, Java, Ruby, Python, .NET, Node.JS, and etc).

Today I will talk about how to use node.js or jave to send message using RabbitMQ on the BlueMix.Let's get started.

1.Node.js

a)Firstly, you need to create a new RabbitMQ service instance with the cf create-service command. Type the following command at terminal:

cf login -a https://api.ng.bluemix.net
cf create-service rabbitmq 100 rabbitmq-test

b)Create a manifest.yml,it will describe the deployment strcture on BlueMix.The service name should be "rabbitmq-test" you created before.
applications:
- services:
  - rabbitmq-test
  host: RabbitMQ
  disk: 1024M
  name: RabbitMQ
  command: node app.js
  path: .
  domain: ng.bluemix.net
  instances: 1
  memory: 128M


Notes: Pls make sure the host name is not taken by others,otherwise the deployment will report error.You have to change other name to instead of it.
c) Since our command point the start node from app.js,so we need to create app.js file.You can copy below content into your files.

var http = require('http');
var amqp = require('amqp');

if (process.env.VCAP_SERVICES) {
  var env = JSON.parse(process.env.VCAP_SERVICES);
  var credentials = env['rabbitmq-2.8'][0]['credentials'];
} else {
  var credentials = {"url": "amqp://user1:secret@localhost:5672/vhost"}
}

var port = (process.env.VCAP_APP_PORT || 1337);
var host = (process.env.VCAP_APP_HOST || '0.0.0.0');

http.createServer(function(req, res) {
 
  res.writeHead(200, {'Content-Type': 'text/plain'});

  var conn = amqp.createConnection({url: credentials.url});

  conn.on('ready', function() {
    var exchange = conn.exchange('test-event', {type: 'fanout'});
    conn.queue('test-event-queue', function(q) {
      q.bind(exchange, '');
      q.subscribe(function(json) {
        res.end("Fetched message: " + json.body);
        conn.end();
      });
   
      exchange.publish('test-event-queue', {'body': 'Hello, world!'} );
    });
  }); 

}).listen(port, host);

d) Create a package.json.
This text file contains all the information about the project, like project path, dependencies, author name, tags, bug tracking info etc.. To create a package.json run npm init command from the root folder. It will ask series of questions and finally it will create package.json file.

Our package.json file will look like this.

{
  "version":"1.0.0",
  "scripts":{"start":"node app.js"},
  "dependencies":{"amqp":"*"},
  "name":"hellorabbitmq",
  "description":"This is a Bluemix demo"
}
Notes:
You need to add dependencies amqp,it will automatic download the node module when you deploy to the BlueMix.

e) use cf push command to deploy Node application to the BlueMix.You can see below sucessfule info.

1 of 1 instances running

App started

Showing health and status for app RabbitMQ in org gyyuan@cn.ibm.com / space dev
as XXX@XXX...
OK

requested state: started
instances: 1/1
usage: 128M x 1 instances
urls: RabbitMQ..ng.bluemix.net

     state     since                    cpu    memory          disk
#0   running   2014-05-18 11:26:27 PM   0.0%   30.6M of 128M   21.8M of 1G
f) Open the browser and luanch the url http://rabbitmq.ng.bluemix.net ,you can see the below screenshot.It means your deployment sucessfule.


2. Java 

In ordet to quick to demostrate the java ability,  I decied to use servlet to show the sending message to RabbitMQ result .Also I will use java liberty as my runtime enviorment.If you have no experience for that you should read my previous post "How to use eclipse to develop liberty java application to BlueMix"

a.Create a dynamic web project named RabbitMQTest. Download below  two libs and copy to WEB_inf lib folder.
rabbitmq-client.jar  
cloudfoundry-runtime-0.7.1.jar
get it from http://www.java2s.com/Code/Jar/c/Downloadcloudfoundryruntime071jar.htm


b) Create a java package named com.ibm.bluemix,and create a servlet class named RabbitMq.The detail code you can see below

package com.ibm.bluemix;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.cloudfoundry.runtime.env.CloudEnvironment;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

/**
 * Servlet implementation class RabbitMq
 */
@WebServlet("/RabbitMq")
public class RabbitMq extends HttpServlet {
    private static final long serialVersionUID = 1L;
   
    private final static String QUEUE_NAME = "hello";
      
    /**
     * @see HttpServlet#HttpServlet()
     */
    public RabbitMq() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         PrintWriter out = response.getWriter();
            try{
              String connURL = getServiceInfo();
              ConnectionFactory factory = new ConnectionFactory();
              factory.setUri(connURL);
              Connection connection = factory.newConnection();
              Channel channel = connection.createChannel();

              channel.queueDeclare(QUEUE_NAME, false, false, false, null);
              String message = "Hello World!";
              channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
              out.println(" [x] Sent '" + message + "'");

              channel.close();
              connection.close();

              out.println( "Successful" );
            }catch(Exception e){
              out.println( "Error running query: " + e.getMessage() );
              e.printStackTrace();
            }
    }
   
    public String getServiceInfo() throws Exception {
        CloudEnvironment environment = new CloudEnvironment();
        List<Map<String, Object>> services= environment.getServices();
        List<Map<String, Object>> matchedServices = new ArrayList();
        List<String> listlabels=new ArrayList();
        listlabels.add("rabbitmq-2.8");
        for (Map service : services) {
          if ( listlabels.contains(service.get("label"))) {
              System.out.println("we get match service");
            matchedServices.add(service);
          }else{
              System.out.println("service name"+service.get("label"));
          }
        }
        if (  matchedServices.size() == 0 ) {
            throw new Exception( "No RabbitMQ service is bund to this app!!" );
        }

        Map credential = (Map)( matchedServices.get(0)).get( "credentials" );
   
        return (String)credential.get( "url" );
      }

}

Notes:
Here getServiceInfo() method will include all the service deployed on the BlueMix,so we need to filter the service which only used the rabbitmq-2.8.You can use this way to filter other service. The service detail parameter you can check your application run time enviroment variable.


c)Create an IBM BlueMix server like below screenshot.
d) Fill the credential info and use validate account to connect remote BlueMix env,
e)When your BlueMix server is started,you can add the RabbitMQTest project to the server,in the launch deployment wizard,you need to enter the deploy host name and application name etc info.



f) Choose the rabbitMQ service "rabbitmq-test"we created before .
g)You should see the console some logs.If you see below logs,it means your deployment is successful.

Checking application - RabbitMQTest
Generating application archive
Creating application in Cloud Foundry server
Pushing application to Cloud Foundry server
Application successfully pushed to Cloud Foundry server

h) Login into the BlueMix website and click the Dashboard tab and you can see your application is not started.Click the start button to start the application.

i) After started and launch the browser and open the url  rabbitmqtest.ng.bluemix.net/RabbitMq, you should see the below screenshot.
Notes: /RabbitMq part url  is defined in the RabbitMq servlet annations.
@WebServlet("/RabbitMq")

Now all are done.Enjoy the node.js and java integration with RabbitMQ.

1 comment:

  1. The RabbitMQ server is written in the Erlang programming language and is built on the Open Telecom Platform framework for clustering and failover. continuous deployment tool

    ReplyDelete