Archive

Archive for the ‘EDA’ Category

Getting a better view from the roof of the Bus

November 3rd, 2009 stiiifff No comments

Last time, I had a first spike with NServiceBus in combination with Castle Windsor, NHibernate & FluentNHibernate, and highlighted the fact that it was quite easy to get those guys up and running together in a clean way, and from there, to process your first messages.

This time, I would like to take a step back, off the Bus, to lay down the foundations of a more concrete & complete example. To do so, I will use the well-known used & abused database sample from Microsoft : Northwind !

I can already hear you all “Northwind, WTF ?!” … except that this time, it’s gonna be different, trust me !

Let’s start by having a look at our veteran database diagram …

NorthwindDiagram

As we can see, Northwind is a traditional sales company, with an online business, which is:

  • Receiving Orders from Customers, classified in different Demographic segments, and shipping those orders via third-party Shippers.
  • Provisioning adequate Stock quantities of Products, arranged in Categories, by buying from several Suppliers, to deliver ordered quantities.
  • Managing Salesmen organized in Territories & Regions.

(yeah, I can get all that from a simple database diagram … impressive imagination huh ? ;-) )

In an SOA world, we wil tend to breakdown the different facets of the company into several independent but cooperating Services.

A naive but all too common way to split our problem domain would probably be as follows:

  • Employee service: manage employees, territories & regions.
  • Customer service: manage customer & demographic segments.
  • Order service: manages customer orders & shippers.
  • Supplier service: manages suppliers & stock.
  • Product service: manages products & categories.

Unfortunately, this simplistic way of defining service boundaries around groups of related concepts most often leads to services that are not autonomous (e.g. call each others, use same database), which violates one of the 4 tenets of SOA (“Services are autonomous“). Plus the fact that it just smells too much like a CRUD API.

A better starting point for modeling services is to analyze the Business Capabilities of the company, that is to say, the distinctive aspects of the company that are contributing to achieve its main goals. Another possibility can also be to model your Services around Bounded Contexts that you would have previously identified, if you are a DDD practitioner. I’m still not yet entirely sure which solution you should prefer and in which conditions … good topic for another discussion.

But in any case, your Services will be better aligned with the Business rather than just being technical CRUD-services.

Here is an attempt at defining the Business Capabilities (BC) and their respective goals in our beloved fictive Northwind company:

  • Marketing BC: maintains a catalog of products, define pricing & promotional operations to maximize sales.
  • Sales BC: accepts customer orders and improves customer relationship.
  • Inventory BC: optimizes the provisioning of product stocks via suppliers to support sales.
  • Shipping BC: optimizes delivery times & costs through shippers.
  • HR BC: manages salesmen to cover sales territories & markets.

They might change as the company’s goals evolve, some being dropped, new ones being added but let’s focus on these ones for now. One service will be defined for each business capability.

Each of those services will eventually use it’s own independent datastore to persist information and will expose its features by accepting incoming Messages and triggering outgoing Events on the Messaging infrastructure.

Those services will be composed to form one or more application(s) that will deliver great value to the company and increase its sales by multiple orders of magnitude !!!

To break with the past, I’ve decided to name this sample Southwind! It sounds warmer and way cooler than Northwind, doesn’t it? :-)  Indeed, it will feature a first personal attempt at building a sample bringing together an Event-Driven Architecture with domain models built following the Domain-Driven Design approach, on top of NServiceBus. Might be a bit ambitious, but it’s so interesting right ?

That’s it for now, till next time where I will focus on the messages & events being exchanged by the different services.

Meanwhile, go read this great article about Event Driven SOA with NServiceBus.

As always, remarks, comments, suggestions are welcome. And if you wanna help building this great sample, you’re more than welcome! ;-)

Business Capabilities

October 23rd, 2009 stiiifff No comments
Categories: Architecture, EDA, SOA Tags:

Stepping onto the Bus

October 12th, 2009 stiiifff No comments

I recently had the chance to follow the Advanced Distributed Systems Design with SOA course with Udi Dahan in Brussels, a rejuvenating experience for various reasons : I had no real-world SOA or Messaging Bus experience, it helped me clear out some misunderstandings I had about DDD and also, although painful at first, Udi finger pointed all the bad habits & misconceptions I had accumulated over the years (I can still hear him squeaking “Northwind ! Northwind !“).

So here I am, entering the realm of SOA, EDA & DDD that might well be heaven on earth for both business people & software-makers, the place we all heard of but never saw. But let’s start slowly, and discover my first endeavor with NServiceBus, shall we? :)

For a good introduction on NServiceBus, I suggest you to read the post from Jan who has been doing research on the same aforementioned topics as well.

This post will focus on how well NServiceBus, NHibernate, FluentNHibernate & Castle Framework play together and how to make them fly in a DDD context. Ok, ok, enough talking, show me the code man !!! :D

To manage my NHibernate sessions (ISession), I like to use the Castle’s NHibernate Integration facility, as it gives me a nice abstraction in the form of the ISessionManager component:

ISessionManager

Next to that, a little more than a month ago, the 1.0 version of FluentNHibernate was released, and it’s really neat for both NHibernate configuration & mappings. So, I like to use it as well:

Fluently.Configure(config)
  .Database(MsSqlConfiguration.MsSql2008
    .DefaultSchema("dbo")
    .ConnectionString(c => c
      .FromConnectionStringWithKey("Northwind"))
    .QuerySubstitutions("true 1, false 0")
    .DoNot.UseOuterJoin()
    .ShowSql())
  .Mappings(m => m
    .FluentMappings.AddFromAssemblyOf<CatalogMap>()
    .ExportTo(System.Environment.CurrentDirectory))
  .BuildConfiguration();

One very nice thing about NServiceBus (and its Generic Host) is that it acknowledges from the start that our softwares have to operate in different environments and for that, it offers a very clean solution : Profiles.

Wrapping it all up, wouldn’t it be nice if I could use Castle‘s NHibernate Integration facility for useful components like ISessionManager (and others, more on that later), FluentNHibernate for configuration & mappings and take advantage of NServiceBus Profiles ? Hell yeah !!! Well, that’s actually quite easy & clean. :)

First, configure the NH facility in your config file:

<castle>
  <facilities>
    <facility id="nhibernate.facility" type="Castle.Facilities.NHibernateIntegration.NHibernateFacility, Castle.Facilities.NHibernateIntegration">
      <factory id="nhibernate.factory"/>
    </facility>
  </facilities>
</castle>

Notice that the configuration for the factory is empty … indeed, we want to configure it fluently in the code.

Create a Profile Handler class (implements a IHandleProfile role interface) which simply registers an object into the container (NSB is container-agnostic) :

public class IntegrationProfileHandler : IHandleProfile<Integration>
{
  public void ProfileActivated()
  {
    Configure.Instance.Configurer
      .RegisterSingleton<IConfigurationContributor>(
        new IntegrationNHibernateConfig());
  }
}

… and finally, an implementation of the IConfigurationContributor interface … which is part of Castle‘s NHibernate Integration facility, and will be called before NH‘s SessionFactory is built in order to, well, contribute to the configuration. :)

public class IntegrationNHibernateConfig : IConfigurationContributor
{
  public void Process(string name, Configuration config)
  {
    Fluently.Configure(config)
      .Database(MsSqlConfiguration.MsSql2008
        .DefaultSchema("dbo")
        .ConnectionString(c => c
          .FromConnectionStringWithKey("Northwind"))
        .QuerySubstitutions("true 1, false 0")
        .DoNot.UseOuterJoin()
        .ShowSql())
      .Mappings(m => m
        .FluentMappings.AddFromAssemblyOf<CatalogMap>()
        .ExportTo(System.Environment.CurrentDirectory))
      .BuildConfiguration();
  }
}

Ok, very nice … but I’m not done yet.

A nice concept that we want to use when querying in a true DDD fashion is the notion of Fetching Strategy (read more about it here & there). We need Fetching Strategies for a very simple reason:

Make sure that once we call into the Domain Model to perform a certain action, it has everything it needs to do its job, without causing lazy-loading to trigger and possibly N+1 select problems.

For that matter, I define a simple interface IFetchingStrategy (IEntityRole is just a marker interface):

public interface IFetchingStrategy<TEntityRole>
    where TEntityRole : IEntityRole
{
  string[] FetchList { get; }
}

… that I can then implement to define a fetching strategy per entity role:

public interface IRegisterProductInCatalog : IEntityRole
{
  void RegisterProduct(string category,
         string productName, string productDescription);
}

public class RegisterProductInCatalogStrategy : IFetchingStrategy<IRegisterProductInCatalog>
{
  public string[] FetchList
  {
    get { return new[] { "Categories.Products" }; }
  }
}

Now, it would be nice if I could get an easy access to those fetching strategies … well, that’s what you use an IoC container for ;) Here is the configuration of Castle’s Windsor container in NServiceBus endpoint’s configuration class:

public class EndpointConfig : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
{
  public void Init()
  {
    var container = new WindsorContainer(new XmlInterpreter());

    Configure.With()
      .CastleWindsorBuilder(container)
      .XmlSerializer();

    container.Register(
      AllTypes
        .Of(typeof(IFetchingStrategy<>))
        .Pick(Configure.TypesToScan)
        .WithService.FirstInterface()
    );
  }
}

Fluent configuration for the Bus & the Container ! Woohoo, my head is turning ! :D

Now, for the final part, the MessageHandler that makes use of all those cuties & with the help some little extension methods:

public class ProductManager : IHandleMessages<RegisterProductInCatalogRequest>
{
  public virtual IBus Bus { get; set; }
  public virtual ISessionManager SessionManager { get; set; }
  public virtual IFetchingStrategy<IRegisterProductInCatalog> Strategy { get; set; }

  public virtual void Handle(RegisterProductInCatalogRequest message)
  {
    using (var session = SessionManager.OpenSession())
    {
      var catalog =
            session.For<Catalog>(message.CatalogId)
                   .Apply(Strategy)
                   .UniqueResult<IRegisterProductInCatalog>();

      catalog.RegisterProduct(message.CategoryName,
                              message.ProductName,
                              message.ProductDescription);
    }
  }
}

I don’t know you, but that’s the kind of code that makes me happy (like a hippo). :)

Comments, feedback, suggestions are all welcome ! ;)