Thursday, June 14, 2012

Programmatically create RabbitMQ Exchange and Queue with Burrow.NET

- As mentioned in previous posts, IRouteFinder is an interface defined in Burrow.NET to help publishing the message to correct target. If you have many message types, potentially you will need many exchanges and queues. And if it's true, setup everything for different environments or different machines is not an interesting task. So with Burrow.NET we can programmatically create these exchanges, queues and bind them very easy.

- What you need is an implementation of IRouteFinder which should define your exchange names, queues name based on message type.

class TestRouteFinder : IRouteFinder
    public string FindExchangeName<T>()
        return "Burrow.Exchange";

    public string FindRoutingKey<T>()
        return typeof(T).Name;

    public string FindQueueName<T>(string subscriptionName)
        return string.IsNullOrEmpty(subscriptionName)
            ? string.Format("Burrow.Queue.{0}", typeof(T).Name)
            : string.Format("Burrow.Queue.{0}.{1}", subscriptionName, typeof(T).Name);

- Once having the route finder implemented, write a few lines of code like below:
var exchangeSetupData = new ExchangeSetupData{ExchangeType = "direct"};   
var queueSetupData = new QueueSetupData {SubscriptionName = "BurrowTestApp", MessageTimeToLive = 100000};

Func<string, string, IRouteFinder> factory = (environment, exchangeType) => new TestRouteFinder();
var setup = new RabbitSetup(factory, Global.DefaultWatcher, ConfigurationManager.ConnectionStrings["RabbitMQ"].ToString(), "TEST");

setup.SetupExchangeAndQueueFor<YourMessageA>(exchangeSetupData, queueSetupData);
setup.SetupExchangeAndQueueFor<YourMessageB>(exchangeSetupData, queueSetupData);
setup.SetupExchangeAndQueueFor<YourMessageC>(exchangeSetupData, queueSetupData);

- Ofcourse, if you have a predefined exchange and queue names but want to have the same settings for different box you can use built-in ConstantRouteFinder:
Func<string, string, IRouteFinder> factory = (environment, exchangeType) => new ConstantRouteFinder("exchangeName", "queueName", "routingKey");

- These code can be run multi times even though the exchanges and queues have've been created before. In practice, I use a application config key/value to determine to run these setup or not. If there have been existing exchanges, queues with the same names but the setting details like ExchangeType, MessageTimeToLive, Durable are different, running the code against the same server will print out the warning messages that would tell you the settings are different. Please note that different exchange type will lead to unexpected results.

- For someone who like to write integration tests which need to create the exchanges, queues before a test and destroy everything after the test, you can use the Destroy method:
Func<string, string, IRouteFinder> factory = (x, y) => new TestRouteFinder();
var setup = new RabbitSetup(factory, Global.DefaultWatcher, ConfigurationManager.ConnectionStrings["RabbitMQ"].ToString(), "TEST");

setup.Destroy<YourMessageA>(exchangeSetupData, queueSetupData);
setup.Destroy<YourMessageB>(exchangeSetupData, queueSetupData);
setup.Destroy<YourMessageC>(exchangeSetupData, queueSetupData);

- This sample code is also available in Githup project



Post a Comment