Plugin Development Guide

This is the RabbitMQ Server Plugin Development Guide. It is expected that before reading this guide, the reader has a basic understanding of the RabbitMQ plugin mechanism. Readers are also expected to have a basic understanding of Erlang OTP system and design principles.

Why Write A Plugin?

Writing a RabbitMQ plugin provides a number of appealing possibilities:

  • Enable your application to access internal RabbitMQ functionality that is not exposed via the AMQP interface.
  • Running in the same Erlang VM as the broker may increase performance for certain applications.
  • Plugins provide an easy deployment model, since they allow for a single "RabbitMQ Appliance" to be built that acts in a self-contained manner. This can be useful both for easing production deployments, and for producing all-in-one infrastructure for use during development.

Why To Not Write A Plugin

As with any plugin mechanism, consideration should be given when developing functionality as to whether embedding it as a plugin is the most appropriate path to take. Some reasons that you might not want to develop your functionality as a plugin:

  • Depending on undocumented internal Rabbit APIs can result in your application requiring changes when RabbitMQ is updated. If you can do what you need to do without using RabbitMQ internals, then your application will be far more compatible in the future.
  • As mentioned in the Admin Guide, a poorly written plugin can result in the entire broker crashing!

Getting Started

To develop a RabbitMQ plugin, a working RabbitMQ development environment first needs to be configured. An "umbrella" project is now provided to assist in assembling all the necessary repositories. The following steps will walk through the process of checking out and using a copy of the umbrella project in your local environment.

  • Ensure that you have a working installation of Mercurial.
  • Ensure that the dependencies detailed in the Server Build documentation are installed and functional.
  • Clone the RabbitMQ public umbrella:
    $ hg clone http://hg.rabbitmq.com/rabbitmq-public-umbrella
  • Checkout the sub-projects into the Umbrella:
    $ cd rabbitmq-public-umbrella
    $ make co
  • Optionally, switch to a different branch, e.g. if you want to build plugins for a particular version of RabbitMQ:
    $ make BRANCH=<tag> up_c
  • Ensure that the umbrella environment is functional by building one of the supplied sub-projects, for example rabbitmq-stomp:
    $ cd rabbitmq-stomp
    $ make
    This should build the dependencies of STOMP (in this case, this includes the rabbitmq-server sub-project) and then the STOMP adapter. You could also run the STOMP tests (issue make test in the sub-project directory), which should all PASS.

Activating Plugins During Development

Instead of requiring that developers rebuild plugin archives and re-install them each time a change is made, plugins can be operated in a development-style mode to make it possible to develop plugins in place.

To enable and activate a plugin in a development environment, create a symlink to the build output location of the plugin directory from the rabbitmq-server/plugins directory (which you will have to create if it does not exist already). For example, to enable a development build of the rabbitmq-shovel plugin and its dependencies:

$ mkdir -p rabbitmq-server/plugins
$ cd rabbitmq-server/plugins
$ ln -s ../../rabbitmq-erlang-client
$ ln -s ../../rabbitmq-shovel
$ ../scripts/rabbitmq-plugins enable rabbitmq_shovel
The plugin will be activated when the server is restarted.

Conversely, to deactivate a plugin, simply remove the symlink, run rabbitmq-plugins disable plugin-name, and restart the broker instance.

Plugin Quality Tips

As highlighted in the Administration Guide, badly-written plugins can pose a risk to the stability of the broker. The following tips aim to provide a series of best-practices for ensuring that your plugin can safely co-exist with Rabbit.

  • Always install a Supervisor above your application. You should never start your application directly, instead opting to create a (possibly quite trivial) supervisor that will prevent the Erlang VM from shutting down due to a crashed top-level application.

Example Plugin: Metronome

Seeing as no development guide would be complete without a Hello World example, the following tries to provide the basics of how your would build your very own RabbitMQ plugin. The following example details how you might build a simple plugin that acts like a metronome. Every second, it fires a message that has a routing key in the form yyyy.MM.dd.dow.hh.mm.ss to a topic exchange called "metronome". Applications can attach queues to this exchange with various routing keys in order to be invoked at regular intervals. For example, to receive a message every second, a binding of "*.*.*.*.*.*.*" could be applied. To recieve a message every minute, a binding of "*.*.*.*.*.*.00" could be applied instead.

The rabbitmq-metronome repository in Mercurial contains a copy of the code for this plugin. This will be checked out for you in the make co step above, or you can check it out separately.

The following table should explain the purpose of the various files in the repository.

Filename Purpose
Makefile The top-level umbrella.mk file aims to make your application's Makefile as declarative as possible. Your plugin's Makefile is still a real Makefile however, so you can still do any kind of normal Make tasks.
package.mk Contains various settings used by the umbrella Makefile.
src/rabbitmq_metronome.app.src This file declares the dependencies required by the plugin (rabbit and amqp_client). These will be available and started before starting the plugin. Note that the real app file is generated from this; there is no need to fill in the list of modules.
src/rabbit_metronome.erl Implementation of the Erlang "application" behaviour. Provides a means for the Erlang VM to start and stop the plugin.
src/rabbit_metronome_sup.erl Implementation of the Erlang "supervisor" behaviour. Monitors the worker process and restarts it if it crashes.
src/rabbit_metronome_worker.erl The core of the plugin. The worker will connect internally to the broker, then create a task that will be triggered every second.
test/rabbit_metronome_tests.erl Automated tests for the plugin.
  • Run make to build your application:
    $ make
    Note that the umbrella build system will build the server and the Erlang client first if necessary.
  • Next, associate your plugin (and its dependencies) with the server:
    $ mkdir -p rabbitmq-server/plugins
    $ cd ../rabbitmq-server/plugins
    $ ln -s ../../rabbitmq-erlang-client
    $ ln -s ../../rabbitmq-metronome
    $ ../scripts/rabbitmq-plugins enable rabbitmq_metronome
    $ cd ..
  • Start up your Rabbit broker:
    $ make run
  • To ensure that your new plugin is up and running, run the following command:
    ./scripts/rabbitmqctl status
    If your plugin has loaded successfully, you should see an entry in the returned list that looks like:
    {rabbitmq_metronome,"Embedded Rabbit Metronome","0.01"}
  • You can run the automated tests by issuing:
    $ make test
  • Finally, you can produce a .ez file, suitable for distribution with:
    $ make dist