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, first make sure the following requirements are met:

  • Ensure that you have a working installation of Git.
  • Ensure that the dependencies detailed in the Server Build documentation are installed and functional.

Erlang.mk is used to build RabbitMQ and its plugins. The easiest way to start on a new plugin is probably to copy an existing plugin such as rabbitmq-metronome, used as an example below.

Activating Plugins During Development

To test your plugin while you're working on it, you can start a broker with your plugin enabled:

$ make run-broker

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 on GitHub contains a copy of the code for this plugin.

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

Filename Purpose
Makefile This top-level Makefile defines the name of your plugin and its dependencies. The name must match the Erlang application name. Dependencies are declared using erlang.mk's variables. Just after that, the Makefile includes rabbitmq-components.mk and erlang.mk, as well as rabbitmq-plugins.mk using erlang.mk plugins facility. See below for a description of those files.
erlang.mk A local copy of erlang.mk. This is not a vanilla copy because RabbitMQ relies on a few modifications which have not been merged upstream at the time of this writing. That's why ERLANG_MK_REPO and ERLANG_MK_COMMIT are overridden for now.
build.config This file configures which features of erlang.mk should be enabled. In most of RabbitMQ's plugins, EUnit is disabled, because they depend on a running broker. Our erlang.mk extensions take care of starting a node and run the EUnit tests when you type make tests.
rabbitmq-components.mk A local copy of rabbitmq-components.mk. The original file is in rabbitmq-common which your plugin will depend on automatically. It contains other erlang.mk extensions and helpers which must be defined before erlang.mk inclusion. This file must be kept up-to-date w.r.t. rabbitmq-common: when it is out-of-date, you will get the following error:
error: rabbitmq-components.mk must be updated!
In this case, just run the following command to update your copy:
make rabbitmq-components-mk
src/rabbitmq_metronome.app.src This file declares the dependencies required by the plugin (rabbit and amqp_client). These applications will be available and started before starting the plugin. Note that the real .app file is generated from this .app.src; there is no need to fill in the list of modules. You can let the vsn field empty: it will inherit RabbitMQ's version.
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
  • Start up your Rabbit broker:
    $ make run-broker
  • To ensure that your new plugin is up and running, run the following command:
    ./deps/rabbit/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",[]}
  • You can run the automated tests by issuing:
    $ make tests
  • Finally, you can produce a .ez file, suitable for distribution with:
    $ make dist
    The file appears in the plugins subdirectory.