One of the challenges we found in real world projects is the routing of messages. It was very easy for the subscription rules in the Azure Service Bus to get complex.

We have introduced a feature which will allow you to set some basic configuration in your config file which will help you to simplify a routing pattern. There are two ways this can be used.

Config Driven Routing Key Property

In this usage the aim is to set a property on the message called RoutingKey using only the features of the framework and configuration. The first thing to do is to add a lookupMessageTypeRoutingKey property set to true on your message client configuration. Shown below:


    <add name="OneWay-MessageTypeRoutingKey-Topic" 
             connectionString="ServiceBusConnection" 
             sendToMessagingEntity="test-messagetype-to-routingkey" 
             serializationFormat="Json" 
             lookupMessageTypeRoutingKey="true" />


If the routing config section is also added to the client side config file then the framework will look up in this configuration to see if it can identify the value to use as a routing key based on the message type.

If a routing key can not be identified then the default routing key will be added to the message.

The below example shows this configuration.


  <appfx.servicebus.client.routing.messagetype
         defaultRoutingKey="NotUK">
         <messageTypeRouting>
              <add             
                   messageType="urn://mynamespace#Message2" 
                   routingKey="UK"/>      
         </messageTypeRouting>
  </appfx.servicebus.client.routing.messagetype>

Messaging Client Routing

The same configuration shown below but modified to only show the client routing, it can also be used to help look up the name of the Messaging Client in the config file that we should use. Normally it would be something like:


  <appfx.servicebus.client.routing.messagetype
         defaultMessageClientName="OneWay-MessageTypeRoutingClient-Default">
         <messageTypeRouting>
              <add             
                   messageType="urn://mynamespace#Message2" 
                   messageClientName="OneWay-MessageTypeRoutingClient-Custom" />      
         </messageTypeRouting>
  </appfx.servicebus.client.routing.messagetype>



    var client = new SimpleServiceBusClient("OneWay-MessageTypeRoutingKey-Topic");
    client.Send<Message2>(message);


This would determine that the message should be send using a specific set of client config from the config file. The code could be modified to choose based on the routing config section which messaging client to use from the config file. This code would look something like the below


    var messageType = message.GetMessageType();
    var router = new MessageTypeRouter();
    var messageClientRef = router.GetMessageClientName(messageType);
    var client = new SimpleServiceBusClient(messageClientRef);
    client.Send<Message2>(message);


Using Side By Side

The two approaches described above can be used side by side simply by adding both the routing key and mesage client attributes to the routing rules. An example is shown below:

  <appfx.servicebus.client.routing.messagetype
         defaultRoutingKey="NotUK"
         defaultMessageClientName="OneWay-MessageTypeRoutingClient-Default">
         <messageTypeRouting>
              <add             
                   messageType="urn://mynamespace#Message2" 
                   messageClientName="OneWay-MessageTypeRoutingClient-Custom" 
                   routingKey="UK"/>      
         </messageTypeRouting>
  </appfx.servicebus.client.routing.messagetype>


Any other options

In the first option listed above it talks about how to use a purely config driven approach which is fine in some circumstances but there are also other options. You would use these with a little more code a bit like in the message client routing option but you can use a regular expression based on the message type which would let you look up a routing key or message client and you would then set these as required. A couple of examples are below:

Lookup Message Client Based on RegEx

The config would look like:

  <appfx.servicebus.client.routing.messagetype
         defaultMessageClientName="OneWay-MessageTypeRoutingClient-Default">
         <messageTypeRouting>
              <add             
                   messageType="urn://mynamespace#*" 
                   messageClientName="OneWay-MessageTypeRoutingClient-Custom" />      
         </messageTypeRouting>
  </appfx.servicebus.client.routing.messagetype>


The code would look like:


    var messageType = message.GetMessageType();
    var router = new MessageTypeRouter();
    var messageClientRef = router.GetMessageClientNameUsingRegEx(messageType);
    var client = new SimpleServiceBusClient(messageClientRef);
    client.Send<Message2>(message);


Lookup Message Routing Key Based on RegEx

The config would look like:

  <appfx.servicebus.client.routing.messagetype
         defaultRoutingKey="NotUK">
         <messageTypeRouting>
              <add             
                   messageType="urn://mynamespace#*" 
                   routingKey="UK"/>      
         </messageTypeRouting>
  </appfx.servicebus.client.routing.messagetype>


The code would look like:


    var messageType = message.GetMessageType();
    var router = new MessageTypeRouter();
    var routingKey = router.GetRoutingKeyUsingRegEx(messageType);
    var client = new SimpleServiceBusClient(messageClientRef);
    client.Properties.Add("RoutingKey", routingKey);
    client.Send<Message2>(message);



Again you can also use these options side by side or you can choose to implement something completely different and just set the values as required.


Last edited Feb 14, 2014 at 10:42 PM by michaelstephenson, version 1

Comments

No comments yet.