Building Our Own ESB: Part 5
The dust is settling now after a crazy month, so here we go with Part 5 of the ESB series. There is a lot of excitement building around this project. Keep in mind that the repository on GitHub will always contain the latest code if you want to keep up to date with the latest progress:
http://www.github.com/jezell/iserviceoriented.
Our class diagram continues fill out. Here's where we stand today:
Again, a few notes before we start:
As the number of classes increases, we need to move some of the support classes into their own namespaces. We don't want to end up with one giant namespace.
I've added support for IoC (inversion of control) containers, thanks to the recent release of the "common service locator" interface. We will provide a simple service locator so a full-fledged IoC container is entirely optional.
Message delivery has been removed from the service bus core. Previously, we made sure to allow custom message queues, now we will take things one step further, allowing consumers to chose one of our strategies or implement their own. DirectDeliveryCore will allow queues to be bypassed entirely, or to be managed by dispatchers (useful if you want to leave queuing entirely up to NetMsmqBinding on both ends or don't care about queuing at all). QueuedDeliveryCore contains the implementation of previous delivery strategy.
DLR hosting and support is started in the IServiceOriented.ServiceBus.Scripting project. This will allow the use of scripts for filters and message transformations.
Unit tests have been moved to NUnit from MSTest.
Due to the interest in the project, I have attached an official license in the repository. The code is available under the MIT license, which means you are free to use it however you please.
The custom formatter for our message queue now supports both MessageContracts and DataContracts.
Our original plan called for RuntimeServices to be able to customize the behavior of our bus. Today, let's look at how we can use RuntimeServices to add functionality to the bus.
Subscription Persistence
Being able to persist subscriptions is extremely important. If our bus needs to be restarted, consumers should not have to re-register to receive notifications. The actual persistence logic is defined by the ISubscriptionDb interface:
SqlSubscriptionDb implements this interface for SQL Server using stored procedures and SqlCommand objects, but using the interface allows consumers to implement the same functionality on top of MySql, Oracle, or an ORM like NHibernate if they prefer. With our data layer interface in place, adding subscription persistence to our bus is a snap:
Performance Monitoring
When our ESB starts to see some action, performance monitoring will also be a must. By hooking into the MessageDelivered and MessageDeliveryFailed events on the ServiceBusRuntime, we can tap into the excellent performance counter support that Windows provides:
Management
Until now, all subscriptions and listeners needed to be programmatically added to the bus. While this works for simple cases, we need to be able to connect to our bus remotely and be able to add or remove subscriptions and change the configuration of our bus. WcfManagementService will host a WCF service that exposes this functionality to consumers. Note that we haven't explicitly written any security checks into the service. This is intentional. We will come back to security soon, but it's worth noting at this that WCF allows role based, claim based, and custom security policies to be injected into services without modifying the core code of our management service. Enough talk, here's the code for our initial management service:
Auto registration
Now that we have the ability to remotely register subscriptions with our service bus, wouldn't it be great if consumers could automatically register themselves with our bus the first time they start up, instead of requiring someone to manually add them? By hooking into WCF with custom behaviors, we can provide an attribute that, when added to a service definition, automatically registers services with our bus:
To have any WCF service automatically register itself with our bus, all we have to do is add an [AutoSubscribe] attribute to the class definition.