Update: There is now a refreshed version of this blog post available using the Message Hub Service for Bluemix.

The MQ Light for Bluemix service is deprecated from 9 August 2017. See the MQ Light retirement schedule blog for more information. As an alternative, you can use the MQ Light API in Message Hub.

This post covers developing and deploying Node.js apps using the MQ Light Service for Bluemix and its’ MQ Light API. By going through this post, you will be able to get a sample up and running, and see worker offload in action, understand how it works, and get started with developing your own Node.js apps using the MQ Light Service for Bluemix.

If you have already gone through the Getting started with Liberty for Java apps using the MQ Light Service for Bluemix, then quite a few parts of this post are going to be familiar to you, such as what the sample is meant to do or the Bluemix-related content, so you can skip those bits and focus on the Node.js details. Also make sure that you check out the last section of this post (getting the Liberty for Java and Node.js apps to talk with each other!).

Tip: For more information about MQ Light in Bluemix, see Getting started with IBM MQ Light for Bluemix.

1. Where can I get the sample?

This sample is available here. After clicking on this, you can do one of two things:

  • Click on MQLight_Worker_Offload_Node_Sample.zip – this will allow you to download a ZIP file containing pre-built versions of the samples. If you just want to try out the sample and have a quick look at the source code, this is the best option.
  • Use Git to clone our Jazzhub repository – if you prefer using Git
git clone https://hub.jazz.net/git/ibmmq/mqlight-worker-offload-sample-node

2. What is this sample about?

The sample app is actually composed of two simple apps: a web front-end that sends messages to a back-end where they are processed – capitalizing the words – and then returned to the front-end.

sample_screenshot

This sample basically shows:

  • how easy it is to get disjoint apps talking to each other using the MQ Light Service
  • how the MQ Light Service can be used to perform worker offload, which provides benefits such as:
    • the front-end will remain responsive while the back-end is processing your data (here the actual processing is not very intensive as it is just a simple example, but imagine if your application had to process a heavy workload, such as a video!)
    • you can scale the number of instances of the back-end app to have several workers processing the requests sent from the front end and get the work done much more quickly

You can also do more advanced stuff, like having several back-end apps in different languages processing the work load from the front end, but first things first…let’s see the sample in action!

3. How do I get it running on Bluemix?

If this is the first time that you are going to deploy an app to Bluemix, you will need to:

  1. Sign up for Bluemix if you don’t have an account yet
  2. Install and setup the Cloud Foundry command line interface by following these instructions, which will allow you to manage your Bluemix applications from your machine (don’t forget to cf login)

Once you have done that, you will have to create an MQ Light Service instance that your apps can use when they are deployed to Bluemix:

cf cs MQLight standard MQLight-sampleservice

That’ll create you an MQLight service instance named MQLight-sampleservice using the standard plan.

Now that you’ve created the service, you’re ready to push the apps themselves, so navigate to the root directory where you downloaded the apps, and run:

cf push

First, this uploads the app files themselves, then sorts out all of the setup for you, taking information from the package.json to download the Node dependencies. This command also binds the service you created to both the apps which were pushed, and starts them up.

Tip: To do all this, this command uses the manifest.yml that is in the root directory to facilitate the deployment. This file is optional, but avoids having to specify all of the arguments each time you run the command (another tip: have a look at cf push -h if you want to specify these manually):

  • name is the name of your application in Bluemix.
  • disk is how much disk space your application have.
  • command is the command that is run to start your app once it is setup in Bluemix. In this case, it is the same command you used to start them locally.
  • path is the path to the app on your local machine.
  • memory is how much RAM you assign the app.
  • instances indicates how many instances of the app Bluemix creates – this is only relevant to the back end worker.
  • no-route indicates that the back end does not need a route (URL) created for it.
  • host indicates the route (URL) to create for the front end (i.e. where the web app is available). Note that ${random-word} generates a random word that should lower the chances of trying the create an already taken route.
  • services lists the services that you want to bind the app to upon creation. In this case it is the MQ Light service you created in the previous step.

When it’s done, you can run the cf apps command or check your Bluemix dashboard to see the apps running.

cf apps output

Head to the URL listed along with the front end in the¬†cf apps command or in your Bluemix dashboard and if everything went well, you will see the front-end, as presented in the screen shot in the Sample app section. When you click the ‘Submit work’ button, the app publishes messages to the mqlight/sample/words topic, which are received and processed by the back end workers (we deployed two of them when we used cf push), and returned capitalized.

messages-recieved

Now that the app has been successfully deployed to Bluemix…how does it actually work? Have a look at the following section if you are interested.

4. What’s under the covers?

Looking at mqlight_sample_frontend_node/app.js, you can get an idea of what is going on. Early on, you check to see whether you’re running in Bluemix by checking for the presence of process.env.VCAP_SERVICES. If you find it, you can grab the necessary details from Bluemix, otherwise you can run it locally and use the default local settings.

if (process.env.VCAP_SERVICES) {
  var services = JSON.parse(process.env.VCAP_SERVICES);
  console.log( 'Running BlueMix');
  if (services[ 'mqlight' ] == null) {
    throw 'Error - Check that app is bound to service';
  }
  mqlightService = services['mqlight'][0];
  opts.service = mqlightService.credentials.connectionLookupURI;
  opts.user = mqlightService.credentials.username;
  opts.password = mqlightService.credentials.password;
} else {
  opts.service = 'amqp://localhost:5672';
}

You can then start the MQ Light client using these options:

var mqlightClient = mqlight.createClient(opts, function(err) {
  ...

Here you can see the app subscribing and specifying the processMessage as the callback that is called when a message arrives:

  mqlightClient.on('message', processMessage);
  mqlightClient.subscribe(SUBSCRIBE_TOPIC, SHARE_ID, 
    {credit : 1,
      autoConfirm : false,
      qos : 1}, function(err) {
        if (err) console.err("Failed to subscribe: " + err); 
        else {
          console.log("Subscribed");
          mqlightSubInitialised = true;
        }
      });

You are subscribing with a credit of 1 and autoConfirm set to false meaning that you deal with one message at a time until you confirm that you have dealt with it. The rest of the code is fairly self explanatory.

Now that you understand how this sample works, are you ready to develop your own Node.js apps? The next section gives a few tips about how to do that.

5. Developing your own Node.js apps for Bluemix

When writing your own app (which can be based on this sample if it helps!), you can either modify the source code and push your apps to Bluemix to test them…or you can install MQ Light onto your own machine and test it locally! This way, you can test out your apps more efficiently, and once you feel that your app is ready, get it deployed onto Bluemix. Here is a quick guide explaining how you can get the sample running on your own machine. You should be able to follow very similar steps for your own apps.

First, follow the MQ Light Getting started guide and ensure that you have MQ Light and Node.js set up on your machine as described. When you have completed this process, you should have a web browser open and pointing at the MQ Light Web UI as this opens automatically when starting MQ Light.

From each of the directories (mqlight_sample_frontend_node and mqlight_sample_backend_node), install the Node module dependencies, as specified in package.json:

npm install

Tip: This installs of the dependencies in a node_modules directory. When you push your app to Bluemix however, this directory does not need to be pushed as Bluemix will get the dependencies for you. To avoid pushing this directory, the .cfignore file contains a reference it!

When everything has finished installing, use the following to start each app:

node app.js

Point your browser to localhost:3000 to get to the front end deployed on your local machine.

6. Troubleshooting your own Node.js apps for Bluemix

To troubleshoot your Node.js apps using the MQ Light Service for Bluemix, there are two useful sources of information: the MQ Light UI, available both on your local MQ Light installation and for the MQ Light Service for Bluemix, and the logs from your Bluemix apps.

The MQ Light UI

To get to the MQ Light UI:

  1. For your app running locally: it should have been fired up when you started MQ Light, but if you closed it, point your browser to localhost:9180
  2. For your app running on Bluemix: login to the Bluemix Web UI, and, from the Dashboard, click on your instance of the MQ Light Service.

In both cases, you will be able to see senders appearing on the left-hand side, and receivers on the right-hand side, with any messages flowing in the middle.

For example, going back to the sample, after clicking on the ‘Submit work’ button, you should see something similar to the screenshot below. You can click on ‘Topic List’ for senders and on ‘Details’ for receivers to get more information about the connected applications. Click on ‘Details’ in any of the messages to get some more information on it, such as the payload, who sent it, to where, and whether or not anyone is waiting for it. This is perfect for troubleshooting messaging applications as you can see what your messages are actually doing.

Looking at Bluemix logs

To see the logs generated by your app on Bluemix, you can use the cf logs command:

  • To tail your logs as they are being generated (from a separate command prompt while pushing for example)
  • To see your app’s most recent logs using the --recent option

Tip: Only the logs following the latest app startup will be shown.

Tip: If you have several instances of an app running, use the drop down box next to ‘Instances’ (under ‘Files and logs’) to see the logs from each of them

 

7. Working with the Liberty for Java sample

If you have already gone through the Getting started with Liberty for Java apps using the MQ Light Service for Bluemix, then you will have a Node.js back-end app hooked into the same instance of the MQ Light service. If those are stopped, and you have only your Liberty for Java apps started (ie. your Node.js apps are stopped), you should see the following when you click the button:

all-liberty-full

As you can see, it is only the Node.js back-end that is doing the work. If you start the Liberty for Java back end you created in the other post and click the button, you should then see something like:

interop-full

This time, each message sent by the Node.js front end is processed by both the Liberty for Java and the Node back ends. Head over to your Liberty for Java front end and you should see the same thing. And just like that, you’ve got¬†Liberty for Java and Node.js apps talking to each other. Nice.

The way this works is:

  • JMS publish/subscribe inter-works between JMS and Node.js.
  • JMS topic names are the same as Node.js topic names.

    In Node.js, the topics are simply defined in the app.js files, for example, in the front-end app:

    var PUBLISH_TOPIC = "mqlight/sample/words";
    var SUBSCRIBE_TOPIC = "mqlight/sample/wordsuppercase";
  • In Liberty for Java, topics are specified in the server.xml file:

    <jmsTopic id="jms/BackEndWorkerListenTopic" jndiName="jms/BackEndWorkerListenTopic">
       <properties.wmqJms baseTopicName="mqlight/sample/words"/>
    </jmsTopic>
    
    <jmsTopic id="jms/BackEndWorkerNotificationTopic" jndiName="jms/BackEndWorkerNotificationTopic>"
       <properties.wmqJms baseTopicName="mqlight/sample/wordsuppercase"/>
    </jmsTopic>
    

    In BackEndMDB.java:

    @MessageDriven(
            activationConfig = { @ActivationConfigProperty(
                    propertyName = "destinationType", propertyValue = "javax.jms.Topic"), @ActivationConfigProperty(
                    propertyName = "destination", propertyValue = "jms/BackEndWorkerListenTopic")
            }, 
            mappedName = "jms/as_MQLight-sampleservice")
    
  • The JMS equivalent of a shared destination, is enabled in JMS 1.1 by setting the cloneSupport option on the destination.

In this example, you can simply have every message being ‘processed’ twice (once by each back end), but in reality you’ve got lots of options with this pattern. Perhaps a Node app could take messages and display them in a responsive web app, while a Liberty for Java app stores the same messages in a database or does analytics without affecting the responsiveness of your front end at all. But what if you only want each message to be processed once? The MQ Light API supports the concept of ‘shares’ where multiple clients can be subscribed to the same destination, but each message is only received by a single client – this is perfect for scaling up to deal with heavy load and there are other workshops that deal with that particular scenario.

Join The Discussion

Your email address will not be published.