# RabbitMQ adapter for Yggdrasil

[![Build Status](]( [![Hex pm](]( [![ downloads](](

This project is a RabbitMQ adapter for `Yggdrasil` publisher/subscriber.

## Small example

The following example uses RabbitMQ adapter to distribute messages:

iex(1)> channel = %Yggdrasil.Channel{
iex(1)>   name: {"amq.topic", "some_channel"},
iex(1)>   adapter: :rabbitmq
iex(1)> }
iex(2)> Yggdrasil.subscribe(channel)
iex(3)> flush()
{:Y_CONNECTED, %Yggdrasil.Channel{(...)}}

and to publish a message for the subscribers:

iex(4)> Yggdrasil.publish(channel, "message")
iex(5)> flush()
{:Y_EVENT, %Yggdrasil.Channel{(...)}, "message"}

When the subscriber wants to stop receiving messages, then it can unsubscribe
from the channel:

iex(6)> Yggdrasil.unsubscribe(channel)
iex(7)> flush()
{:Y_DISCONNECTED, %Yggdrasil.Channel{(...)}}

## RabbitMQ adapter

The RabbitMQ adapter has the following rules:
  * The `adapter` name is identified by the atom `:rabbitmq`.
  * The channel `name` must be a tuple with the exchange and the routing key.
  * The `transformer` must encode to a string. From the `transformer`s provided
  it defaults to `:default`, but `:json` can also be used.
  * Any `backend` can be used (by default is `:default`).

The following is an example of a valid channel for both publishers and

  name: {"amq.topic", "postgres_channel_name"},
  adapter: :rabbitmq,
  transformer: :json

It will expect valid JSONs from RabbitMQ and it will write valid JSONs in

## RabbitMQ configuration

Uses the list of options for `AMQP`, but the more relevant optuons are
shown below:
  * `hostname` - RabbitMQ hostname (defaults to `"localhost"`).
  * `port` - RabbitMQ port (defaults to `5672`).
  * `username` - RabbitMQ username (defaults to `"guest"`).
  * `password` - RabbitMQ password (defaults to `"guest"`).
  * `virtual_host` - Virtual host (defaults to `"/"`).
  * `heartbeat` - Heartbeat of the connections (defaults to `10` seconds).
  * `subscriber_options` - Controls the amount of connections established with
  RabbitMQ. These are `poolboy` options for RabbitMQ subscriber (defaults to
  `[size: 5, max_overflow: 10]`).

The following shows a configuration with and without namespace:

# Without namespace
config :yggdrasil,
  rabbitmq: [hostname: ""]

# With namespace
config :yggdrasil, RabbitMQOne,
  postgres: [
    hostname: "",
    port: 1234

Also the options can be provided as OS environment variables. The available
variables are:

where `<NAMESPACE>` is the snakecase of the namespace chosen e.g. for the
namespace `RabbitmqTwo`, you would use `RABBITMQ_TWO` as namespace in the OS
environment variable.

## Installation

Using this RabbitMQ adapter with `Yggdrasil` is a matter of adding the
available hex package to your `mix.exs` file e.g:

def deps do
  [{:yggdrasil_rabbitmq, "~> 4.1"}]

## Running the tests

A `docker-compose.yml` file is provided with the project. If  you don't have a
RabbitMQ database, but you do have Docker installed, then just do:

$ docker-compose up --build

And in another shell run:

$ mix deps.get
$ mix test

## Relevant projects used

  * [`AMQP`]( AMQP application.
  * [`Connection`]( wrapper over
  `GenServer` to handle connections.

## Author

Alexander de Sousa.

## License

`Yggdrasil` is released under the MIT License. See the LICENSE file for further