Friday, October 30, 2009

Book Review: Enterprise Service Bus

ESB About a year ago, I was lucky enough to attend the Kaizenconf in Austin. When I joined the discussions on ESB Patterns, Dru Sellers and Chris Patterson (also known as the MassTransit guys) were talking about this book called Enterprise Service Bus from David Chappell. I finally took the time to read it and for the most part it was a real eye opener. As you might have guessed, the book provides an architectural overview of the ESB concept. Although it does provide some amount of detail, there are no in depth discussions on any particular technologies. But after reading the book it is quite clear that the author comes more from a Java background. However this is not that important for a book like this as these concepts are technology agnostic anyway.

I must admit that getting through the first chapter, which tries to introduce the ESB, was not that easy. Too abstract and high level for my taste.

The second chapter is about the State of Integration and discusses how both business and technical drivers contributed to the ESB approach as opposed to Enterprise Application Integration (EAI). One of the best parts in the book is the discussion about "Accidental Architecture" which is an accurate and far too familiar description of the current architecture in most companies. Although the book is approximately 5 years old, it is still very relevant as the adoption rate of ESB's is still not that common. But then again, I could be wrong about this :-).   

The third chapter examines the key concepts of an ESB were the author tries to prove that these are born out of necessity, based on real requirements and problems that couldn't be solved with typical EAI broker architectures (like Biztalk for example).

Chapter 4 states that XML is the exchange format of choice for passing data structures between applications and services. Nothing new here.

Chapter 5 till 8 provide in dept information about each of the key concepts described in chapter 4, like Message Oriented Middleware (MOM), Service Containers and Endpoints, Routing, Transformation, Messaging, etc. ...

Chapter 9 goes back to the real world by exploring the most common form of integration that is practiced today: bulk data transfer using ETL and an endless amount of small batch applications. Sounds familiar? This chapter also provides the necessary steps in order to migrate away from latency and reliability issues towards a real-time integration and how this affects your business.

Chapter 10 is a bit more technology focused as it talks about Java Components in an ESB. However, this could equally be .NET or any other platform.

For me, chapter 11 is a real masterpiece especially the part on Portal Server Integration patterns like Forward Cache and Federated Query. Highly recommended reading.

The final chapter discusses the WS-DeathStar (WS-*) specifications and what they could mean for an ESB.

In the end, I have a lot to think about after reading this book. It challenged a lot of my earlier assumptions on distributed computing and it certainly helped me understand a couple of things while I was exploring NServiceBus.

Till next time

Thursday, October 29, 2009

Next European VAN on 18 November 2009

Mark Nijhof is going to enlighten us all with his DDD/CQRS sample application. You can read all about it at the E-VAN blog.

Friday, October 16, 2009

Mapping From IDataReader/IDataRecord with AutoMapper

A while ago, I submitted a patch to AutoMapper that added basic support for mapping data from an IDataReader/IDataRecord to an object. For those of us who don't have the luxury to use NHibernate in their projects, this feature can save you from writing lots of repetitive and tedious code.

Its usage is pretty much the same as with regular object-to-object mapping using AutoMapper. Lets show a very simple example.

Suppose we have a view object like the one shown below:

public class SomeView
{
    public Int32 SomeNumber { get; private set; }
    public Guid AnId { get; private set; }
    public Double OrNothing { get; private set; }
}

Now when we can execute a query like this,

SELECT ColumnA AS SomeNumber,
       ColumnB AS AnId,
       ColumnC AS OrNothing
FROM SomeTable
WHERE ...

and read the results using a data reader. Now we can use AutoMapper to map the results to instances of our view class:

var dataReader = ... // Execute a data reader
var views = Mapper.Map<IDataReader, IEnumerable<SomeView>>(_dataReader);

This results in a collection of one of or more view objects. When our query is guaranteed to always return one record, we can use the following syntax:

var dataRecord = ... // Execute data reader and read first record
var = Mapper.Map<IDataRecord, SomeView>(_dataRecord);

This approach expects that a convention is followed whereby the name of a field returned by the query matches the name of a property on the target class. Its also possible to use projection as already provided for regular object-to-object mapping.

Suppose we add a new property to our view,

public class SomeView
{
    ...
    public DateTime SomeDate { get; private set; }
}

and we modify the query so that we retrieve the corresponding date value from the database:

SELECT ...
       ColumnD AS BirthDay
FROM SomeTable

Notice that we've broken the convention here and we need to use projection to ensure that the retrieved date value is mapped to the correct property.

Mapper.CreateMap<IDataRecord, SomeView>()
    .ForMember(dest => dest.SomeDateAndTime, 
               options => options.MapFrom(
               src => src.GetDateTime(src.GetOrdinal("BirthDay"))));

var dataRecord = ...    // Execute data reader and read first record
var = Mapper.Map<IDataRecord, SomeView>(_dataRecord);

Using projection we're able to manually map from a data reader or data record. In some sense,  we're back to square one if we have to do this for all fields. Trying to follow the convention is of course the most useful. 

I know it's not much, but I think it can be helpful for those cases where you actually need to map from a data reader or a data record to an object.

Saturday, October 10, 2009

Exploring NServiceBus

I've been learning a bit more about Service-Oriented Architecture (SOA) and Event-Drive Architecture (EDA) over the last couple of months. Something that kept coming back in the articles and books I've read so far is the concept of an Enterprise Service Bus (ESB). I've heard numerous times about NServiceBus, Mass Transit and Rhino Service Bus in the past, but I've never fully realized what types of problems these technologies try to solve. Besides trying to learn about the scenarios and business needs that drive these technologies, I also decided to take a closer look at NServiceBus by creating the simplest example I could think of: Starbucks!

You've probably found out by now that yours truly isn't capable of making up innovative sample applications, but since we actually have two (!) Starbucks shops already here in Belgium, I couldn't let this go unnoticed either.

The scenario is actually quite simple:

  1. The customer places his order at the cashier.
  2. The cashier passes the order to a barista who starts preparing the drinks.
  3. The cashier asks the customer to pay for his order.
  4. When the customer paid for his order at the cashier, the barista is informed that the payment has been completed.
  5. When the barista finishes its order, he checks whether payment has been completed and delivers the order to the customer.

I've used NSB 2.0 for this exercise, which is the trunk version at the moment. The thing that amazed me the most was how easy it is to get started. I pretty much expected to be muddling around for a week before I could actually send my first message, but this was certainly not the case. Let me show a couple of basic code snippets that illustrate how NSB is used.

Here's an example of the fluent API for bootstrapping NSB:

Configure.With()
    .StructureMapBuilder(ObjectFactory.Container)
    .MsmqSubscriptionStorage()
    .XmlSerializer()
    .Sagas()
    .NHibernateSagaPersisterWithSQLiteAndAutomaticSchemaGeneration()
    .MsmqTransport()
        .IsTransactional(true)
        .PurgeOnStartup(false)
    .UnicastBus()
        .ImpersonateSender(false)
        .LoadMessageHandlers()
    .CreateBus()
    .Start();

Notice that I'm able to reuse my IoC container of choice that is also used elsewhere in the application. After bootstrapping NSB, the IoC container contains an instance of IBus which we can use to send and publish messages, etc. ...

A message that can be sent with NSB must implement the IMessage interface.

[Serializable]
public class NewOrderMessage : IMessage
{
    ...
}

Notice that NSB doesn't require a message to be a class. You can just as well use an interface:

public interface INewOrderMessage : IMessage
{
    ...
}

A message can be send using an instance of the bus:

_bus.Send(new NewOrderMessage(...));

Handling a message is accomplished using a message handler that implements the IHandleMessages interface:

public class CashierMessageHandler 
    : IHandleMessages<NewOrderMessage>
{
    public void Handle(NewOrderMessage message)
    {
        ...
    }    
}

The destination of a message must be configured in the configuration file of the sending application.

<UnicastBusConfig>
    <MessageEndpointMappings>
        <add Messages="CashierContracts" Endpoint="cashier"/>
    </MessageEndpointMappings>
</UnicastBusConfig>

When publishing a particular message, this kind of configuration goes in the configuration file of the subscribing application instead of the publisher.

Bus.Publish(new PaymentCompleteMessage(...));
<UnicastBusConfig>
    <MessageEndpointMappings>
        <add Messages="CashierContracts.PaymentCompleteMessage, 
                       CashierContracts" 
             Endpoint="cashier"/>
    </MessageEndpointMappings>
</UnicastBusConfig>

NSB also supports sagas. Here's an example of how to create a saga.

public class CashierMessageHandler 
    : Saga<CashierSagaData>,
      IAmStartedByMessages<NewOrderMessage>,
      IHandleMessages<PaymentMessage>
{
    public void Handle(NewOrderMessage message)
    {
        ...
    }
    
    public void Handle(PaymentMessage message)
    {
        ...
    }
}

public class CashierSagaData : IContainSagaData
{
    public virtual Guid Id { get; set; }
    public virtual String Originator { get; set; }
    public virtual String OriginalMessageId { get; set; }

    ...
}

The saga data class contains data that should be persisted during the lifetime of a saga so that it can be used when different messages arrive. So make sure that the public members of saga data classes are virtual!

You can find the code of this sample application using NServiceBus at the Elegant Code repository (turns out we actually have one of those at Google Code). I've probably did a whole bunch of things wrong with it, but I definitely learned a thing or two in the process :-).

There's a lot more that I want to learn about NSB like testing sagas, the generic host, etc. ...

Let me round of this post by providing a couple of resources that were very helpful:

I just want to say thanks to Andreas for answering my stupid questions on the NServiceBus user group.

Till next time,