Benjamin W. Smith

Benjamin W. Smith

Benjamin W. Smith  //  Sysadmin by trade, Pythonista by passion. Dad to two boys and a girl. Guitarist. I like my coffee black, just like my metal.

Jan 18 / 6:56pm

stomp-js - STOMP in node.js

Intro

OK, so I suck at this.  I set out to write at least two, maybe three blog posts last night.  One of the other two is going to require much more thought and editing, the third is about vaporware (I literally have one test done) and this one, well, this one is the easiest because most of the work is already done ;).

So here we go with a quick run-through of stomp-js, an implementation of the STOMP 1.0 protocol in node.js.

I initially started out doing this as a simple exercise to learn node.js.  After toying with the code for some time, I realized I had something decent going on.  So I decided to clean it up, refactor some and release it.

Here we are now, with 0.0.2 of stomp-js.

Installation

Installation is pretty straight forward, assuming you already have node.js and npm installed.

npm install stomp

Not using npm?  Clone the github repo!

git clone https://benjaminws@github.com/benjaminws/stomp-js.git

Usage

First and foremost, we should setup a consumer to listen to the queue we will be hammering with messages later.

These examples assume you have a broker (ActiveMQ or RabbitMQ with the STOMP plugin) running on localhost, listening on port 61613.  To adjust the connection settings, change stomp_args, which looks something like this:

Taken almost directly from the project repo:

Pretty simple what's going on here, but lets step through it anyway.

  • Setup arguments to pass to the constructor
  • Create the object
  • Setup some options for subscribing to the destination
  • Connect to the broker
  • Subscribe to events
    • When 'connected' is fired, subscribe to the desired destination
    • When 'message' is fired, ack the message (you could do fancy things with the message here)
    • When 'error' is fired, inform of the error and disconnect
    • When 'SIGINT' is caught by the process, report a tally of work done and disconnect

 

This will listen for messages until we kill it, or if an error is encountered.  It's single purpose is to consume all the messages and acknowledge them with the broker.

Now we can't just let that consumer sit there being all lazy, lets send it some messages.

A stomp-js producer:

 

Stepping through this briefly.

  • Get number of messages to produce from the arguments
  • Decided if we want to get a receipt for messages produced
  • Setup arguments for the constructor
  • Create the object
  • Set the destination for messages
  • Connect to the broker
  • Subscribe to events
    • When 'connected' is fired, loop 'n' times, sending a message to the broker on each iteration.  Disconnect when complete.
    • When 'receipt' is fired, report the receipt ID
    • When 'error' is fired, inform of the error and disconnect
    • When 'SIGINT' is caught by the process, report a tally of work done and disconnect

 

Pretty simple stuff!

I'd like to point out that stomp-js does implement the basic transaction support defined by STOMP 1.0.  Below is some example code showing how to implement this.

Basically you call client.begin(), which returns a transaction id.  Then add a 'transaction' header to the message you're sending with the transaction id as the value.  Once the send is done, call client.commit(transaction_id).

Here is the full example:

Fin

That's basically it!

Want to help make stomp-js better?  Have an issue with it?  Want to keep up with progress?  Follow/Fork/Report on the github page! https://github.com/benjaminws/stomp-js

Filed under  //  gist   git   github   javascript   messaging   node   node.js   npm   stomp  
Dec 28 / 8:31am

New Year's Python Meme

From Tarek via pyDanny

1. What’s the coolest Python application, framework or library you have discovered in 2009?

I did a lot of playing with asyncore and am currently having bit of fun with ply. As far as the coolest goes, I’d have to give a nod to Dingus from Gary Bernhardt. I really like the record-then-assert model for mocking, and the name just takes the cake.

2. What new programming technique did you learn in 2009?

Well, this year I completely changed my development methods. More accurately I actually started practicing some sort of development method where I previously had none. Prior to this year, I just kinda vomited code and didn’t pay much mind to quality. Though I always tried to make my code presentable and maintainable, that was typically an afterthought.

This year I started writing unit tests, then I started writing them first. Before I knew it I had read Clean Code and developed a mental work flow that really helped me focus.

The result (I think) has been higher quality code, and a better understanding of what I’m doing! Also, I’m pretty sure I cranked out more code this year than I ever had before even with less time to do so! Naysayers of TDD/BDD be damned, I am proof dammit! To be fair, this might not work for everyone :).

3. What’s the name of the open source project you contributed the most in 2009? What did you do?

Likely my own projects, specifically stompy and NginxMgr. I wrote them both from the ground up..

4. What was the Python blog or website you read the most in 2009?

Pythonistas on Twitter and Planet Python

5. What are the top three things you want to learn in 2010?

  1. Python Concurrency (and multiprocessing)
  2. More meta programming tricks
  3. A functional programming language (erlang or MAYBE Haskell, though it scared me a tad the last time I tried)
Filed under  //  bdd   holidays   meme   python   stomp   tdd  
Sep 19 / 8:29pm

Python STOMP Updates

Due to a flurry of activity(like, you know, a couple people) on bitbucket and twitter, it became apparent to me that people were actually using the library I created for working with message brokers that utilize the STOMP protocol. This is exciting news for me! ;-)

In response I decided it would be a good idea to, you know, maintain the software and polish it up a bit. There were three forks of the python-stomp repository on
bitbucket, so I waded through diffs to see what ideas/suggestions/improvements others had. Everything I saw looked great, so I pulled in and merged all the changes in to the main repository. Thankfully this was a trivial task because mercurial is FREAKING AWESOME. The next step was to polish it all up. So, I went to PEP8ifying where needed(thankfully others had done a great deal of that work for me), and unit testing new functionality introduced by the other developers.

There are many improvements/changes in the latest iteration of this library, so I’d like to outline some of them here.

  • Renamed to stompy
  • Fully documented with Sphinx
  • Simplified client interface with automatic transaction support (abstracted stompy.stomp as stompy.simple)
  • Intermediate message queue layer
  • Simplified authentication
  • More resilient and informative error handling
  • Polling/Non-blocking support
  • Now able to subscribe to multiple destinations at a time
  • Tested and known to work well with ActiveMQ and RabbitMQ
  • Now available on pypi!

This is just a high level overview of the major changes to stompy. For more detailed information, have a look at the source and documentation.

I’d like to thank a few people that have submitted patches and new functionality.

In closing, I’d like to point out that this “project” was an exercise in TDD(Test Driven Development) for me. I wrote the tests first, then the actual code to make the tests pass. This was also the first time I had used the mocking library Dingus. This has been a pleasurable and enlightening development experience for me!

Thanks for reading!

Filed under  //  activemq   bitbucket   etc   hg   mercurial   python   rabbitmq   stomp  
Apr 3 / 5:42am

Python STOMP Implementation

Everyone else is doing it!

Quite seriously though… In my dealings with JMS Message Queuing, specifically with ActiveMQ, I felt the lack of a simple, straight-forward and easy to use Python implementation of the protocol that was also well documented and hackable.

More often than not, I found myself using Perl’s Net::Stomp module because it was so much quicker to get going. Gasp you say, a Perl module that is easier to use than a Python module?! BLASPHEMY! I implore you to believe me!

I don’t think I’ve reinvented the wheel, merely rounded it to my specifications. So, if you choose, check out my implementation of STOMP in Python over at Bitbucket: python-stomp.

It is feature-complete according to the STOMP Protocol, 100% Unit test covered, documented, comes with example usage and is simple to use.

Feedback is appreciated in the form of issues on the Bitbucket issue tracker or this blog if you want to say something nice, or mean about it!

Documentation:

Code:

Filed under  //  activemq   etc   python   stomp  
Sep 3 / 1:07am

ActiveMQ stomp end to end test for nagios

I recently found myself needing to test producing and consuming messages from activemq via stomp. It’s a pretty trivial task thanks to Perl and nagios! Here is a quick script to test the production and consumption of messages and the command you’ll need to put into core.cfg (nagios v2). It’s slim on libs to cut down on excess fat. Enjoy!

Prerequisites..

Class::Accessor (Net::Stomp wants it)
Net::Stomp
$USER3$ = custom location of nagios check scripts..
check_mq = the name of the script.
$ARG1$ = host to check
$ARG1$ = number of messages to produce/consume
$ARG2$ = name of queue to test with

The command for core.cfg:

define command{
        command_name    check_mq
        command_line    $USER3$/check_mq $ARG1$ $ARG2$ $ARG3$
        }

The code:

#!/usr/bin/perl -w

use strict;
use Net::Stomp;

my $host = $ARGV[0];
my $nummsgs = $ARGV[1];
my $queue = $ARGV[2];

my $stomp = Net::Stomp->new( { hostname => $host, port => '61613' } );

$stomp->connect();

for (my $i=0; $i <$nummsgs; $i++) {
    $stomp->send({ destination => "/queue/$queue",
                   body => "$queue$i",
                   persistent => 'true'} );
}

$stomp->subscribe({ destination => "/queue/$queue",
                    'ack' => 'client',
                    'activemq.prefetchSize' => 1});

my $count = 0;
for (my $i=0; $i <$nummsgs; $i++) {
    my $frame = $stomp->receive_frame;
    my $body = $frame->body;
    if ($body eq "$queue$i") {
        $count++;
    }
    $stomp->ack( { frame => $frame } );
}

$stomp->disconnect();

print "Produced: $nummsgs Consumed $count\n";

if ($count == $nummsgs) {
    exit(0);
}
elsif (($count != $nummsgs) && ($count != 0)) {
    exit(1);
}
elsif ($count == 0) {
    exit(2);
}

Oh so simple..

Filed under  //  activemq   nagios   perl   stomp