CQRS with event sourcing using NServiceBus, Event Store, Elastic Search, AngularJS and ASP.NET MVC

CQRS+event sourcing posts

Introduction

Command + event sourcing

Read model: Elastic Search and event store projections

UI

 

 

Introduction

Hi,

In the next post series I will show a CQRS architecture. A CQRS architecture is an architecture that splits the system in two parts: the one for managing commands and another one that is a read model (Query). How the data is stored and how to synchronize the command and read model can vary veeeeery much between different architectures, from Relational DDBBs to NOSQLs. Here I will cover a radical one, using event sourcing and a special database for it. If you use this you just store business events, what has happened, and you have to create the read model from it.

 

CQRS

 

When to use it? For me I would only use it if:

  • Scalability is a must, tons of business events a day.
  • You don’t need real time UI but you have to show complex information.
  • Your business entities are very isolated: metering, bank accounts. You just work with one or two entities in each business step. It is difficult to create queries that searchs over the entities in the command model, and the query model could be not in synch.

It is a complex architecture for very complex systems, not the default way to go.

 

In this example I will use the following mix of technologies:

NServiceBus: a messaging bus for implementing the “command” part of the CQRS system. It processes commands from the UI or other systems and emits events if necessary.
Event Store: Greg Young’s database for the event sourcing. This is a blowminder database. In short it stores JSON events in sequences. For instance:

In the sequence Bank-Client-22 the following events are stored: ClientCreated, MoneyDeposited (+50), MoneyWithdrawn (-30).

It also has something for the query part of the system: the projections. These are “temporal queries” that runs over the events “queue”. At the end they take event by event and apply logic, they can also create more streams or events. It is very powerful and can easily (or better than SQL) answer questions like: “detect the clients where their cards have been used in an ATM several times in X minutes”, or it can just add or substract all the movements and keep a variable with the total money in the bank.

ElasticSearch: this is a search and analytics engine. The core of the read model.

– AngularJS: The UI is a SPA in an asynch fashion. It can receive events from the bus.

 

Here is the code:

https://github.com/pablocastilla/CQRS-NServiceBus-EventStore-ElasticSearch

 

To run it you need to:

– Download event store and run it. For example: “.\EventStore.ClusterNode.exe -db .\ESData --run-projections=ALL

– Load the projections in the .NET solution (EventStore/Projections) on event store. Create them as continuous. Make sure that every projection in the system is running.

– Download ElasticSearch

– Run the services, UI and the synchronicers.

 

Next post… The C

Advertisements

12 comments

  1. Riccardone · · Reply

    Hi,

    I’m looking at your code. It’s interesting so thank you for sharing it.

    I have a question.
    In the CreateClientHandler you create an instance of a client using the following line
    var client = Client.CreateClient(message.ClientID, message.Name);

    as you know this raise an event ClientCreated

    in the same CreateClientHandler then you make a deposit and then you save the client. I wonder what could happen if your domainRepository.Save(client, true); fail for some reasons.
    The ClientCreated event is already raised…

    Thanks

    1. Hi Riccardone!

      Thanks for looking into it, now I know that at least one person did it :).

      If you see the raised event is processed in memory and goes to uncommitted events list. In the save the uncommited event list is stored in the event store as a whole.

      So… is something goes wrong an exception is raised, the message goes back again to the queue for retrying and every is undone at memory level. That event just dissapear.

      Hope this helps

      1. Hi Pablo,

        yes this help, thanks. I can’t see the value to encapsulate inside an abstract Aggregate class the logic to manage events. Is it “legal” 🙂
        For example, is it not more logical see the event raised and published from the handler after some action happened?

        If something go wrong, you don’t raise that event. If you need a sort of unit of work, you have to do these tasks as a unit inside an handler. Isn’t it?

        Thanks

        (I did not read yet DDD books so apologize if what I’m saying doesn’t make sense)

      2. Never mind… I’ve just went through other CQRS DDD example and I can see that are all using the same approach with the events.

    2. I recommend you to read CQRS documents written by Greg Young. You will understand better what I am doing. Those events are not messages, they are “inmutable actions” happened to the object.

      https://cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf

  2. […] ago I read a very interesting blog post by Pablo Castilla https://pablocastilla.wordpress.com/2014/09/22/cqrs-with-event-sourcing-using-nservicebus-event-stor… I started studying it and I found it simple and complex enough to be taken as base template for my […]

  3. Hi Pablo,
    I’m trying to confirm some basic rules in order to better define aggregates for behaviours and event sourcing. For what I understood, a command handler (behaviour exposed from an aggregate) can validate and apply logic and then raise an event. An event handler (apply @event) can mutate the state of the aggregate but not apply any logic.
    In your Client aggregate, there is a little logic in Apply events methods and I wonder if it could be better move this logic into the command and raise the event with the result of this logic in it.

    For example this (suggested solution):

    public void Deposit(double quantity, DateTime timeStamp, Guid transactionId, bool fromATM = false)
    {
    var newBalance = balance + quantity;
    RaiseEvent(new MoneyDeposited(newBalance, timeStamp, ID, transactionId, fromATM));
    }

    private void Apply(MoneyDeposited obj)
    {
    balance = obj.Balance;

    }

    instead of this (current):

    public void Deposit(double quantity, DateTime timeStamp, Guid transactionId, bool fromATM = false)
    {
    RaiseEvent(new MoneyDeposited(quantity, timeStamp, ID, transactionId, fromATM));
    }

    private void Apply(MoneyDeposited obj)
    {
    balance += obj.Quantity;

    }

    Does this make sense?

    1. Hi Riccardo!

      Well, that could work, but I would prefer the other way because you keep more info. I see event sourcing as storing events with as much info as possible and later extract it to read models and to recreate the aggregates.

      For example in this case if you are updating the balance you miss the quantity moved in each operation. Imagine you have to create a read model with all the bank operations of the user, you would have lost that information if you do it that way.

      In event sourcing there is another technique called snapshot (I think it is not supported by EventStore) that is to “serialize” the whole aggregate into an event. That is used for deleting old events and not start recreating the entity from scratch. I see what you are doing as an snapshot but not the normal event sourcing way.

      Hope this helps 🙂

      1. I see your point.
        In that case, you can just pass the quantity as parameter if you need to store it for later use.

        The fact here is that any calculation have to be done in the command, not in the event handler. In the event handler you are allowed only to mutate the state (balance = newBalance) registering the state transition of the aggregate without any logic or calculation in it.
        No logic, no validation, no exceptions.
        Why? Imagine that in a real case you need a more complex procedure and/or call a service to get a piece of data or to charge a card. If you do that in the event handler, you end up replaying the same logic every time you replay events.

        I know that this code is extremely simple but when I started looking around it I was confused about where the logic have to stay.

        Anyway… hope that this can be considered as a point of interest 🙂

      2. A reference:
        “… Commands have an intent of asking the system to
        perform an operation where as events are a recording of the action that occurred …”
        Greg Young CQRS Documents Pag. 26

      3. I consider this conversation very interesting and now I agree with you.

        If I would have to connect to another service with CQRS+ES I would store the result in the event to be recreated and to have the information that was returned the day it was called. The balance of an account is an special easy case of logic, I think most cases you will assign without making calculations as you did. So if you store both the balance and the operation quantity is perfect, you have the information and it is easy to recreate 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: