Axon 3: Event Replaying

 
Axon is a lightweight framework that supports the implemenation of CQRS patterns by providing commonly used building blocks. One of those patterns is an event sourced application architecture. Even though Event Sourcing and CQRS are orthogonal concepts they fit together very well and are often used together. Event sourcing in an ES/CQRS architecture means that all changes to the application state are done via domain events and the current state can always be rebuilt from the series of events available in a persistent event store. In addition to the event store there might also be one or more read models, for example to achieve opimtized query performance. No matter if there are read models or not, the event store is considered the single source of truth.

Event Replaying: what and why?

Besides rebuilding current application state from the stored events we can employ a technique called Event Replaying to achieve several other goals. For this purpose we need a mechanism to read all events from the event store and send them to a set of components which are interested in handling them. This implies selecting and registering those components.
Some use cases where event replaying can be applied are: generating new read models, removing inconsistencies by rebuilding an existing read model, or for analysis and debugging purposes.

Adding new read models

Suppose you have a library managemenent application where you can track and add meta data about your books. Sometime you might want to switch from your table based search implementation to Elasticsearch. This can be done with event replaying: all you have to do is to implement one or more event handlers that are responsible for extracting appropriate information from the domain events and inserting them into the Elasticsearch index.

Removing inconsistencies from existing read models

As software developers we may have to deal with bugs in our software even though we try hard to avoid them. Nevertheless, bugs are inevitable. Imagine there is a bug in one of the event handling components that are supposed to rebuild the aforementioned Elasticsearch index. In such a situation, first the bug must be fixed (in code) and then all domain events simply have to be replayed to the now well behaving event handler again.

Debugging purposes

Sometimes you want to know exactly when an inconsistent application state has been introduced. One approach to achieve this could be to replay all events up to a certain point in time and examine the corresponding application state.

How?

Introducing event replaying in an application that already uses the Axon 3 framework is fairly easy. Axon provides all building blocks needed to achieve this, in particular there are event handlers and event processors. Event handlers implement all business logic, whereas event processors are responsible for taking care of the technical aspects of event processing.
There are two types of event processors: Subscribing Event Processors and Tracking Event Processors. From the Axon documentation:

The Subscribing Event Processors subscribe themselves to a source of Events and are invoked by the thread managed by the publishing mechanism. Tracking Event Processors, on the other hand, pull their messages from a source using a thread that it manages itself.

It’s the tracking event processors that provide event replaying capabilities. They’re keeping track of which events have already been processed by means of storing a token. So let’s configure Axon to use tracking processors (instead of the default subscribing processors):

eventHandlingConfiguration.usingTrackingProcessors();

This will automatically create tracking event processors for your event handlers. Axon uses a token store to determine whether there are events that need to be processed. This token store will be checked regulary. If you’re using the Axon JPA provider there is already an entity class TokenEntry available. You have to tell your JPA provider where it is located. In Spring Boot this can be done with @EntityScan:

 @EntityScan(
   basePackages = {
     ...,
     "org.axonframework.eventhandling.tokenstore.jpa"
   }
 )

This is everything needed to configure your application to be able to do event replaying.
In order to trigger an event replay in production you just need to delete the tracking tokens associated with an event processor from the token_entry table. The corresponding event processor then pulls all events from the event store.
This is a really simple configuration. It’s also possible to configure seperate tracking event processors for different replaying use cases. See the EventHandlingConfiguration class for more detail.

Common pitfalls

Event replaying is a very useful technique but you have to be aware of some common pitfalls.

Replaying events to external services

Make sure that replayed events never get processed accidentally by the wrong event handlers. For example events might be transformed into messages and published to a messaging middleware, and eventually consumed by external systems. In this case you want to exclude the corresponding event handlers from event replaying because messages should only be published once.

Eventual Consistency

If you’ve used the default subscribing event processors and switch to tracking event processors remember that they are pulling for events in a thread managed on their own. If your user interface relies on everything being handled in one thread, the user interface will break now. In this case, consider using subscribing event processors for business-as-usual actions and only use tracking ones if you intent to trigger an event replay. This requires some more elaborate configuration for when event replaying is executed. Another option could be to let your user interface pull for updates.

Conclusion

Event replaying in Axon 3 is supported by tracking event processors: they keep track of the last position in the event log. In order to replay all events all you have to do is resetting the corresponding tracking token.