Showing posts with label Axon. Show all posts
Showing posts with label Axon. Show all posts

25 November 2013

Axon framework - behavior driven testing

Rich domain model that emerges from application of DDD techniques has many advantages over anemic model but is hard (or even impossible) to deliver when modeled entities need to be stored in relational database. The reason lays deeply in the mismatch between goals of DDD and ORM models. Without going into details, the main difference is that the goal of ORM models is to enable "easy" persistence/storage and retrieval (including ad-hoc queries) of modeled objects leveraging SQL/RDBMS technology while the goal of DDD models is to decompose complex business domain into manageable pieces taking into account scalability and consistency requirements. Therefore applying both DDD and ORM modeling techniques simultaneously seems to be at least risky endeavor. But with help of Axon framework doing DDD on top of ORM is possible and may lead to better overall design.

In my previous article in this series Axon framework - DDD and EDA meet together (which I recommend to read before proceeding) I have introduced Axon framework and described how it enables application of DDD, CQRS, SAGA design techniques. I have also described key building blocks of DDD (Aggregates and Events) and mentioned event sourcing as "optional building block".
In this article I will show how to upgrade JPA managed entities (shortly persistent entities) that play role of Aggregate Roots (AR) to event sourced Aggregate Roots, so that they can be loaded from an event stream. The goal is not to replace relational database with event store (we are not ready yet to be eventual consistent ;-), but to improve quality of unit tests of ARs (remember, ARs are not simple data container, they contain business logic and thus deserve careful testing). As we will see, having possibility to construct ARs from events will let us write self-documenting unit tests expressed purely in terms of events and commands.
The main problem that needs to be addressed when modeling Aggregate Roots that are both persistent and event sourced entities is lack of consistency boundary concept in ORM model. Persistent entity can hold direct reference to any other persistent entity, while Aggregate Root can't hold direct reference to other Aggregate Root. Let's take a closer look at this problem and try to enumerate possible solutions.

Direct dependencies between Aggregate Roots


We can easily load persistent entity that contains graph of other persistent entities because EntityManager can execute any series of SQL select statements (using joins if possible) while fetching the entity. There is nothing that prevents EntityManager from assembling single graph containing several different persistent entities even if we modeled those entities as different Aggregate Roots. When dealing with event sourced ARs, its not the case. Event sourced repository only knows how to load single AR. Thus, to be able to load AR from event stream we need to ensure that it has no direct dependencies to other ARs. 
Note that it is perfectly valid for AR to keep direct references to owned entities. When loading from event store, AR is responsible for recreating all owned entities.
Of course, by definition AR should not have reference to other AR, but because our ARs are persistent entities direct references in some cases might occur because they are for some reasons convenient or even necessary. Lets think of those reasons.

Entities need to be queried


Sometimes we model dependencies between persistent entities just to be able to perform effective queries using JPQL. The solution in this case is easy: referencing by id.
It turns out we can easily replace object reference to related entity with its identifier (aka primary key) by providing targetEntity parameter in mapping annotation (probably not very commonly used JPA feature):

And that's it. Problem solved.

Entities should not contain duplicated data


There is another reason for corrupting boundaries between ARs when modeling on top of relational database: avoiding data duplication (aka normalization). The normalization leads to complexity that can be easily noticed by looking at any "robust enough" ERD diagram (ex.: online shop data model).
Complexity shows up in the code of business logic. It quickly turns out that logic of any business operation (except some simple CRUD operations) requires access to data from multiply entities.
In example below Payment Plan (AR) (part of operational domain/context) implements register payment operation that performs check if received payment is complete (the received payment amount is equal to amount defined in Payment Plan (AR) (part of planning domain/context)) and thus accesses paymentAmount property of PaymentPlanAR:

We can get rid of direct relationship to payment plan AR by simply duplicating paymentAmount in Payment Plan and Payment Period (we would copy the value from PaymentPlanAR during creation of PaymentPeriodAR). That way we keep both ARs (contexts) separated.
So solution in that case is simple: data duplication.

(There is also a third possibility: model the activity as business process (SAGA) that can interact with many ARs, but we will not consider this option here).

OK, but lets assume we can't do it (duplicate data). The reason we can't could be that we want payment amount to be editable and we don't want to care about synchronization of changes between payment plan and payment period, assuming such synchronization would be necessary...

Shortly, lets assume we need to keep direct references between some ARs...

Now, we still want to be able to construct ARs from events for testing purposes.
Fortunately, Axon framework allows registering AggregateFactory that can assist AR construction and initialization from event stream.

Aggregate Factory


Lets introduce Subscription Plan (AR) that holds reference to Subscription Pool (AR):

When loading the subscription plan from jpa repository (production environment), the pool will be automatically initialized by underlying JPA provider. When loading from event sourced repository (test environment) Axon framework will check if AggregateFactory is registered for SupscriptionPlanAR type and call AggregateFactory#doCreateAggregate method providing aggregate identifier and first event from the event stream to create empty AR instance (AggregateFactory does not fill business properties of AR, they will be initialized when applying events from event stream).

Thus, we need to implement SubscriptionPlanFactory capable of instantiating SubscriptionPlanAR with SubscriptionPoolAR injected:

Logic inside SubscriptionPlanFactory#instantiate is also used by command handler when processing SubscriptionPlanCreateCommand so good idea is to promote SubscriptionPlanFactory to standard factory for SubscriptionPlanAR that is not only able to instantiate empty aggregate root but also create new valid aggregate root as dictated by business requirements. To do so we will add public create method to the factory:


Please note that event sourced ARs can't rely on auto-generated identifiers (identifiers generated after AR is saved to database), that's why our factory generates identifier before creating AR (previously it was responsibility of command handler).

Please also note that main construction logic (application and handling of SubscriptionPlanCreatedEvent) is still placed inside AR itself, but now it is contained in create method instead of constructor:

Worth noting is separation between event publishing (create method) and event application (handle method). Previously (without support for event sourcing) both operations could be implemented in one method (or constructor) (see: Account.java), now they need to be split so that loading aggregate root from event stream is possible.

Now, implementation of command handler is straightforward:

Test fixture


We are now ready to configure Axon's given-when-then test fixture that can be used for testing different types of Aggregate Roots:


Concrete implementation of test class will need to define aggregate type, aggregate factory (Axon provides GenericAggregateFactory that can be used if no custom initialization of AR is required) and command handler. Both aggregate factory and command handler are then passed to specialized registration methods of Axon's FixtureConfiguration. At the end, command handler is passed reference to repository that was created by GivenWhenThenFixture (in production scenario command handler works with JPA-based implementation of Repository interface, in test scenario the repository (of class EventSourcingRepository) and event store are constructed by Axon's test framework).

Finally we can implement unit tests by simply declaring commands and events using given-when-then style as following:

 - Given: a set of historic events
 - When: I send a command
 - Then: expect certain events

Sometimes it is shorter to declare commands instead of events in given section as one command can result in multiply events. Axon supports that too. It is also possible to assert return value or exception returned/thrown by command handler. It should be noted that all events or commands should refer only to single AR. If you want to test Saga classes (interactions between different ARs) you need to use AnnotatedSagaTestFixture.

Let's see couple of example tests:



What happens in the background when test is executed can be described in a few steps:
 - given section
    - given events (or events published as the result of given commands execution) are saved to in-memory event store
 - when section
    - command handler is invoked
    - command handler asks repository to load aggregate root by id
    - repository loads AR from event store (aggregate factory creates empty AR and then events are applied to that AR)
    - command handler invokes appropriate business method on AR

Looking at test class you can see that there is no code related to infrastructure (no dependency to jpa, sql import statements, etc.), we don't care about persistence layer at all. We test external interface represented by command (input) and events (output) decoupling tests from actual AR being tested. Tests are self-explanatory out of the box. Creating a test in this way could be easily supported by some gui tool that would allow building the test by dragging widgets representing events, commands, entities and exceptions into a form (containing given, when, then section) and filling their properties :)

1 August 2011

Axon Framework - DDD and EDA meet together

CQRS (Command Query Responsibility Segregation) is a new approach towards building scalable and distributed systems that is based on simple pattern know as Command Query Separation (CQS). In short, you should design your system in a way that it either processes a command or serves response to a query. CQRS in its core is quite simple. Just split your service interface into two parts: Query Service and Command Service and you are done. But what is important is that by making this simple separation, you make your system open to many opportunities for architecture that may otherwise not exist. In this article I will not show you what is possible when fully applying CQRS (check this CQRS Starting Page for details). Instead I will present you how some design patterns can effectively be applied to standard ORM-based application when you decide to split your interface into Commands and Queries and use Axon - CQRS framework for Java. But first we must talk about DDD as it plays crucial role in building scalable and maintainable systems and fits very well to CQRS-based architecture.

DDD shortly

Generally DDD is about domain model that, when expressed in Ubiquitous Language, can be shared by developers and domain experts allowing them to communicate effectively. From technical point of view DDD is about modeling your core domain using aggregate roots (AR), entities, value objects and some other artifacts like domain services and repositories. What is important, when applying DDD to medium or large domains (generally complex domains are good candidates for DDD), you should not be expecting one model to arise representing all areas covered by the system. Each area will likely be modeled separately (inside its own Bounded Context). This aspect is very important, especially if your application starts to grow covering more and more business activities. If you stick with one model aka EDM (Enterprise Domain Model) (that typically reassembles model of relations inside your sql database), you will end up with monolithic system not capable of adjusting to business requirements.
Therefore building application DDD-way should be seen as completely different approach comparing to standard approach (one model to rule them all approach). You will need additional means to express communication between your different models (Bounded Contexts).
Thats where EDA - event based communication comes in.

Let's see how to apply DDD and EDA to standard ORM-based application with use of Axon.

Axon introduction

Axon framework provides building blocks for CQRS applications. Some blocks, i.e. (event sourcing, asynchronous processing of commands (no response from Command Handler)) are optional and can be omitted. If you are not ready for (or just don't need) full CQRS, you can still benefit from other goodies such as synchronous command handling, events, sagas and others. Additionally Axon integrates deeply with Spring making configuration a trivial task (just use built in namespaces (xml part) and annotations). Unique feature of Axon is that it allows to integrate existing JPA-based application. To make your entities become Aggregate Roots extend AbstractAggregateRoot class, to load your ARs from database use GenericJpaRepository (or even better HybridJpaRepository if you want to use EventStore). For detailed instructions see User's Guide. Lets start working with code.


Get rid of Transaction Script

When applying DDD, we tend to build rich entities that encapsulate behavior.
In contrast to standard approach with anemic domain model and procedural code inside Application Services (see: Transaction Script), most of business logic should be handled inside Aggregate Roots. When a command comes in, it is dispatched to Command Handler whose only job should be to get AR from Repository and invoke single method on it.

Lets imagine a system that manages user accounts (Account AR). One of Account's properties is state. To activate an account, AccountActivateCommand must be sent by the client. In order to handle this command, we must register and implement specialized Command Handler:


That's it. Nothing special. Clean code so far.

Implementing business logic - uniformed approach

First, we need to extend our model in order to make it more interesting :) Our system must support handling user's payments related to Payment Period. The following requirements are added:
1) when Account is activated, Payment Period must be created that will be used to keep track of payments related to the Account
2) after Payment Period expires, subsequent Payment Period must be created, but expired Payment Period should still be accessible

We could model our Account like this:


In this model, Account is responsible for managing Payment Periods. It sounds good, we can implement account activation inside Account class:


Please notice three blocks of code in this method and theirs order. This separation is dictated by CQRS-based design. You should have all these blocks in every method that is invoked by Command Handler. The blocks are:

1) validation - checking if operation is allowed and will not break consistency of the Aggregate
2) raising event - creating a Domain Event containing information about Aggregate's change
3) handling event - updating state of the Aggregate (no exceptions, no logic here!)

Every change of Aggregate's state must be signaled with an Event (Domain Event). All Domain Events will be stored in Event Store (if configured) (just serialized as Blobs or Clobs to single table).

If our Aggregate Root is event-sourced (is reconstructed from Event Store instead or being created by EntityManager), we should move event handling code to separate method:


We will not discuss Event Sourcing in this article, as we don't want to get rid of our powerful ORM, or do we? (actually in CQRS world ORM is
persona non grata - you were warned ;)

Keep your ARs lously coupled

Going back to our model, after thinking a little bit longer, we realize that it doesn't fit well our needs... One of the requirements is to process commands related directly to Payment Periods. These commands should be dispatched directly to Payment Period entity rather than go through Account AR. Payment Period should be an AR on its own. When we think more about this (and talk with our Domain Expert (if we have one;)), the separation of Account and Payment Period will become even more obvious. We could easily imagine two services Account Service (responsible for accounts management) and Payment Service (responsible for payment registration) working independently.

So we can simplify Account AR and upgrade Payment Period to AR:


Now account activation is implemented partially (Payment Period is not being created). We could implement Application Service that would first call Account#activate and than create new Payment Period, but implementing business logic within Application Service layer leads to Transaction Script that we are trying to avoid (we want to avoid both ARs (Account and Payment Period) forcibly be invoked in the same transaction - it hurts system scalability).
Lets think of our ARs on higher level. They belong to different contexts/services (virtual Account Service and Payment Service). The way to communicate between different contexts (services) is to use Domain Events!

Events to the rescue

We already have implemented raising of the AccountActivatedEvent in activate() method of Account AR. Now we must create Event Listener that will listen for this event and will send PaymentPeriodCreate command.
With Axon it is as simple as creating new class:


Of course, we need to implement a command handler that will handle PaymentPeriodCreateCommand by creating Payment Period AR and adding it to Repository.
Thats all. Now we have independent ARs that communicate with events.
This design leads us in direction of autonomous components (services) communicating asynchronously in publish-subscribe model (aka: push integration model), possibly via some kind of EventBus or Broker (see: Avoid a Failed SOA: Business & Autonomous Components to the Rescue by Udi Dahan)
But we will not go so far.

There are many other benefits from applying EDA. One of them is ability to keep detailed history of Events:

History of Events (Audit)

By storing Events in database (Event Store) we keep log of changes. We can easily create additional table containing following data:
- aggregate root class
- aggregate root id
- event class
- user

The table like this can serve basic reporting purposes. If we want to create more sophisticated reports in the future, we can reply events stored in Event Store and populate any report table we need. All history of changes is kept in Event Store.

Now lets see how we can model long running process with SAGA! In case you forgot the requirements, short reminder: new Payment Period must be created after the current one expires.

Enter SAGA

Saga is a stateful component (its state is persisted across invocations) that is capable of receiving events (including timeout events) (similar to Event Listener). Saga represents business process instance, in other words business process associated with particular AR(s).


First method will be invoked on PaymentPeriodCreatedEvent and will result in creation of new Saga associated with Payment Period being created and related Account. Inside method body we schedule the PaymentPeriodExpiredEvent that will be triggered when validity interval of Payment Period ends (Axon provides Quartz-based implementation of Event Scheduler) .
The second method is called when payment expiration happens (when PaymentPeriodExpiredEvent is triggered by the Event Scheduler).
The only thing this method does is sending a command that will be processed by our Account Service (currentPaymentPeriod must be increased) and eventually by Payment Service (new Payment Period will be created).

Lets see how easy we can test our Saga with use of Test Fixture provided by Axon:


Finally, I want to discuss one more topic related to DDD.

Don't pollute your core domain model


What is common mistake DDD beginners make is that they try to apply DDD totally (put all application logic into ARs boundaries). Let's take an example and add new requirement to our application:
All entities (including Account) are separated by Sales Areas. Any operation on Account (creation, activation, etc.) can be performed only if the owning Sales Area is in status ACTIVE.

First, we will modify our model by adding the following JPA mapping to the Account AR:


Now lets think of the requirement. Where should we put the checking if the Sales Area is active? The activate() method of Account AR seems to be the perfect place. But if we think more, we realize that Sales Area does not belong to our core domain! Checking status of the Sales Area inside Account AR will pollute the code (checking must be done before any modification of Account's state). So our new model is broken! There should be no Account -> Sales Area mapping. But we can not remove it, because we reuse the same model for serving queries (we don't follow CQRS in this aspect) and we need to be able to filter Accounts by Sales Area easily.
Ok, so the better place to put the checking would be a Command Handler (AccountCommandHandler). But it may be necessary to reuse this logic across different commands. What we need is some kind of interceptor that will prevent particular commands (account related or other) reaching Command Handlers. Not surprisingly Axon provides CommandHandlerInterceptor interface that allows for customized command handler invocation chains. No example this time, as it is quite easy to imagine:)