Skip to content
jbrisbin edited this page Jan 14, 2012 · 2 revisions

The webhooks plugin is very configurable. Everything is done from the system rabbit.config file. It probably doesn't exist unless you've created one already. Check the directory "/etc/rabbitmq". If there's no config file in there, create one called "rabbitmq.config".

As of v0.14, there is a Ruby script you can use to transalte a YAML config file into the more complex and finicky Erlang config file. It will generate the correct atoms for you to include in your system rabbitmq.config file.

An example YAML file will look like this (with the bare minimum left uncommented, everything commented out is optional and the values shown are the defaults):

--- # Test YAML file for driving config file generation.

# Broker configuration
username          : guest
virtual_host      : /

# Use a YAML alias to reference this one exchange for all configs.
exchange: &webhook_exchange
  name            : webhooks
  # type            : topic
  # auto_delete     : true
  # durable         : false

# Webhooks configurations
webhooks:
  - 
    name            : webhook1 # Name should be unique within the config file
    url             : http://localhost:8000/rest
    # method          : post # get | post | put | delete
    exchange        : *webhook_exchange
    queue:
      name          : webhook1 # Best to have the queue name match the config name
    #   auto_delete   : true
    # routing_key     : "#"
    # max_send:
    #   frequency     : 5
    #   per           : second # second | minute | hour | day | week
    # send_if:
    #   between: 
    #     start_hour  : 8 # 24-hour time
    #     start_min   : 0
    #     end_hour    : 17  # 24-hour time
    #     end_min     : 0

If you want to configure it manually, an example Erlang config file is included in priv/: Here's a sample configuration file to get you started:

[
  {rabbit_webhooks, [
    {username, <<"guest">>},
    {virtual_host, <<"/">>},
    {webhooks, [
      {test_one, [
        {url, "http://localhost:8000/rest"},
        {method, post},
        {exchange, [
          {exchange, <<"webhooks.test">>},
          {type, <<"topic">>},
          {auto_delete, true},
          {durable, false}
        ]},
        {queue, [
          {queue, <<"webhooks.test.q">>},
          {auto_delete, true}
        ]},
        {routing_key, <<"#">>},
        {max_send, {5, second}},
        {send_if, [{between, {13, 24}, {13, 25}}]}
      ]}
    ]}
  ]}
].

Parameter Substitution

One of the cool things the webhooks plugin can do for you is parameter substitution on your URLs.

Given a URL configured like:

http://localhost:8000/rest/{oid}

The message you want forwarded to this URL, then, should contain a message header with the name "oid". The plugin will do parameter substitution before it calls the URL and will turn the above into something like this (given a header value of "12345jhkasd847"):

http://localhost:8000/rest/12345jhkasd847

Per-message Overrides

Each message can override the default URL and HTTP method for a given webhook.

By way of example, assume you're using webhooks to update an object asynchronously using a REST API. If you wanted to create a new object, you'd set the "oid" value we mentioned above to "" (the empty string). This would result in an HTTP POST to the url: http://localhost:8000/rest/, which would create a new object. If you wanted to update an object using a webhook, however, you'd override the method to PUT by adding a message header named "method" with the value "put" and specifying an "oid". In REST parlance, a POST creates a new object and a PUT updates an existing object.

Full REST Support

Since the URL is a pattern and the HTTP method is configurable on a per-message basis. Using webhooks gives your RabbitMQ AMQP broker full REST support. You can DELETE objects, POST new ones, PUT existing ones, etc... as the result of sending messages to an AMQP exchange.

Outgoing Message Throttling

The webhooks plugin uses the internal RabbitMQ worker_pool to send outgoing HTTP messages. This means your HTTP requests will be made as fast as possible, depending on the number of processors in your machine. It will intelligentlly spawn enough processes to keep up with the requests you're sending it without swamping your system.

But it may not always be desirable to queue 10,000 HTTP requests as fast as possible. Your application server might not be able to handle that much load!

To limit the number of outgoing requests, you can set a 'max_send' configuration parameter on your webhook that will limit the number of outgoing HTTP requests per second, minute, hour, day, and week. It's a tuple of the number of messages and an atom of the unit of time. If you want to limit outgoing requests to 5 requests per second, you'd configure {max_send, {5, second}}. Or 1,000 per minute would be {max_send, {1000, minute}}. You get the idea.

The delay algorithm isn't as smart as I'd like it to be. There's certainly room for improvement there, but I was looking for something that worked as closely to what I wanted without having to spend a lot of time writing code for minimal gain. The webhooks plugin will queue requests as fast as it can up to the maximum number of messages you have set in the first part of the tuple. When this maximum is reached, the consumer will sleep for however long you've configured (second, minute, hour, etc...). This is obviously not ideal, as the better solution is to take into account how far into that second or minute or hour you already are when the maximum is reached. In the interest of expediency, though, I elected to put off spending time on that improvement until other, higher-priority items are taken care of.

Send Window

Not only can you restrict the number of messages per second/minute/etc... that the webhook plugin processes, you can restrict outgoing HTTP traffic to only certain times of day. If you have almost no traffic on your site from 1:00-3:00 a.m., for example, you could configure your webhook to only send outgoing HTTP requests during that window. Messages sent to your queue at other times during the day will sit in the queue and wait to be processed until the send window opens.

To configure a send window, add a send_if configuration element to your webhook and give it a list of tuples that describe the method by which the window is calculated (right now only the atom between is supported), and a couple of two-tuples that define the starting hour and minute and the ending hour and minute:

{send_if, [{between, {13, 24}, {13, 25}}]}

The time is in "military" or 24-hour time. 3:00 p.m. is {15, 00}, etc... It is also local to the broker. There is no time zone support yet so you'll have to define your windows in terms of the broker's local time.

Clone this wiki locally