Cedric Goffin
Cedric Goffin

Reputation: 33

How to replay events from database before application startup?

I'm a student who is quite new to the Axon framework for event-sourcing, so bear with me please. I'm currently having issues that when my QueryHandler needs access to events that have been created before the spring application was started, it won't include them.

So for example, the following event gets created:

(The event creates a new Webshop and sets it balance to 100). That event gets persisted to my database. When I query the current webshop balance, I can return that the current balance is 100. (Code for event and query is shown below)

If I restart the application however and I try to query the current balance once again, previous events don't get replayed, so I can't get the current balance (after restart the events are still there in the database, so I think it is just a problem with the framework not retrieving all the previous events).

I currently use the default configuration, Axon 4.0.3 for Spring and a H2 database that stores the events to a file locally (H2 isn't the best choice, I know, but this is all for a small proof of concept showing Event Sourcing and CQRS in action, so no need for big and scalable).

@Service
@NoArgsConstructor
public class WebshopsEventHandler {

    private final Map<String, Webshop> webshops = new HashMap<>();

    // ... some other unrelated code

    @EventSourcingHandler
    public void on(ShopCreatedEvent shopCreatedEvent) {
        this.webshops.put(
                shopCreatedEvent.getId(),
                new Webshop(
                        shopCreatedEvent.getId(),
                        shopCreatedEvent.getName(),
                        shopCreatedEvent.getBalance() // Balance is 100 as default
                )
        );
    }

    // ... some more unrelated code

    @QueryHandler
    protected Optional handle(GetCurrentBalanceQuery getCurrentBalanceQuery) {
        System.out.println("Balance query");
        if (webshops.containsKey(getCurrentBalanceQuery.getShopId())) {
            return Optional.of(webshops.get(getCurrentBalanceQuery.getShopId()).getBalance());
        } else {
            return Optional.empty();
        }
    }
}

How can I configure Axon 4 to retrieve all the previous events after a restart?

Upvotes: 1

Views: 1134

Answers (1)

Steven
Steven

Reputation: 7275

I think I can help you in this scenario. Let me first give you a little background on why your 'query model store', the private final Map<String, Webshop>, isn't filled on each start up.

The technical mechanism which provides the events to your @EventHandler annotated functions, is called the Event Processor. As off version 4.0, Axon Framework defaults to a TrackingEventProcessor.

The TrackingEventProcessor, as the name already suggests, keeps track of it's own event processing. It does so by storing a TrackingToken - in your set up this means it will be stored in the H2 database file. This TrackingToken stores (among other things) the last event a given TrackingEventProcessor has handled.

The TrackingToken is what allows you to replay events, as you can point it to a different point in time on the event stream. Adjusting the position of the token is thus key in this scenario.

You could do this by initiating a replay on the TrackingEventProcessor, which is explained in some detail here. As you're however just showing how it works rather than making a persistent system, I'd suggest something more pragmatic.

If you adjust the TokenStore (the component in charge of storing your tokens) to be an InMemoryTokenStore, you'll be insured your application does not keep track of a Tracking Event Processors progress between shutdowns of your application. To do that, you can do the following in a configuration file or the @SpringBootApplication annotated class (assuming you're using Spring Boot):

@Autowired
public void configureInMemoryTokenStore(EventProcessingConfigurer configurer) {
    configurer.registerTokenStore(configuration -> new InMemoryTokenStore());
}

Hope this helps!

Upvotes: 3

Related Questions