Configuring Snapshotting - Need help with configuring of AggregateSnapshot event Filtering

Hello !

I need help configuring the Filtering of AggregateSnapshot events persisted to the appropriate Event Store as described here AbstractSnapshotEventEntry (Axon Framework 4.6.1 API)

Which implementation that implements Interface DomainEventData<T> is the one for me to go for? What other config decisions could influence which one is the right implementation o DomainEventData<T> for me?

https://apidocs.axoniq.io/4.6/org/axonframework/eventhandling/DomainEventData.html

Here is the code example from the corresponding docs page

SnapshotFilter giftCardSnapshotFilter = snapshotData -> /* allow or disallow this snapshotData */;
 
AggregateConfigurer<GiftCard> giftCardConfigurer = 
        AggregateConfigurer.defaultConfiguration(GiftCard.class)
                           .configureSnapshotFilter(config -> giftCardSnapshotFilter);
Configurer configurer = DefaultConfigurer.defaultConfiguration()
                                         .configureAggregate(giftCardConfigurer);

First, I guess I have to use RevisionSnapshotFilter (Axon Framework 4.6.1 API)

and AbstractSnapshotEventEntry (Axon Framework 4.6.1 API)

SnapshotFilter giftCardSnapshotFilter = new RevisionSnapshotFilter.build().nowWhat(AbstractSnapshotEventEntry<GiftCard> arg)?
  • What is T in this case? The name of the Aggregate?

Thanks for your advice !

Yours sincerely,
ĂĽberSpotz :slightly_smiling_face:

This post concerns Axon 4.6

The T is the type of Snapshot Event in this case.
So, the payload stored inside the DomainEventData object.
This is, by default, the aggregate(s) you’re configuring the snapshotting.

Now, when it comes to configuring a SnapshotFilter, you’re guess on the RevisionSnapshotFilter is the easiest approach to take.
To configure this, all you have to do is add the @Revision annotation to your Aggregate class!

So, taking the GiftCard example:

@Revision("[your-current-revision]")
class GiftCard {
    // Omitting state, command handlers, and event sourcing handlers for simplicity
}

Adding the above annotation will let the framework know that you have a snapshot with revision “your-current-revision”. Hence, it will automatically filter out snapshots with another revision.

If you need more granular filtering on the DomainEventData, then the DomainEventData its interface should be sufficient to retrieve all the required information from.

I hope this helps you further, @uberSpotz!

Dear @Steven_van_Beelen,
thank you very much for your kind answer!

Your answer helps partly to be frank.

I don’t understand your JavaConfig example with the @Revision annotation.

@Revision("[your-current-revision]")
class GiftCard {
    // Omitting state, command handlers, and event sourcing handlers for simplicity
}

What is denoted by the placeholder ${your-current-revision} ? I guess it corresponds to the parameter in this method

https://apidocs.axoniq.io/4.6/org/axonframework/eventsourcing/snapshotting/RevisionSnapshotFilter.Builder.html#revision-java.lang.String-

Sets an aggregate revision this SnapshotFilter will allow.

But I can only guess that the possible arguments are the indizes of persisted AggregateSnapshot events. And the index that you pass as argument is the Snapshot event that you want to load, the others are skipped when loading.

Correct or not?

Additionally, I can only guess the correct constructor for AbstractSnapshotEventEntry<T>.

The problem that the segment describes is the accumulation of many AggregateSnapshot Events that are superfluous as it only takes one of these instances to be the snapshot of your Aggregate, right?

The key quotes in this docs entry on this aspect of Snapshotting are

When enabling snapshotting, several snapshots would be stored per Aggregate instance in the event store. At a certain stage, some of these snapshot events are no longer being used by the application as newer versions took their place. Especially if these snapshot events portray an old format of the aggregate by using the AggregateSnapshot event would it be smart to no longer load these.

and

It is also possible to filter out snapshot events when reading your Aggregate from the event store. To that end, a SnapshotFilter can be defined per Aggregate type or for the entire EventStore .

First: What is the <T> then of the AbstractSnapshotEventEntry<T> please ?

In general I really try to come more to terms with the Config API.

And I am really trying my best to puzzle something together that fits the code example from the docs page… but I have no luck with that.

Maybe you could please post a working config api example? I know this is much asked. But I really tried figuring it out myself. Don’t want to be spoon-fed. I am just at a dead end here. I think everybody has moments like this. Very frustrating. Too many unknowns to solve the riddle.

All best,
ĂĽberSpotz

I’ll capture a couple of your questions here, überSpotz, and respond to them.

That’s correct.
To be more exact, you have complete freedom over what the value of the revision is.
It’s a String to give the user complete freedom in whatever scheme they like.

The most reasonable is incrementing a number over releases.
But, if you so like, you can use the names of the Presidents of the United States.
Or cats living in your neighborhood.

It is entirely up to you, as Axon Framework cannot deduce for you what the most reasonable revision is.

Nope, that’s not correct.
The indices of the snapshot are used by Axon Framework to compare the position of the snapshot compared to the Aggregate’s Event Stream.
So, when your snapshot was taken based on an Aggregate who’s stream contains 10 events, the snapshot index becomes 10.
Through this, when the aggregate is loaded, and a snapshot is found, the framework knows from which index onwards it should retrieve more events.

Again, the revision is a value that you choose.
As stated, incremental numbers make sense.
More specifically, a number that increments with your production releases.
This rule of thumb applies as only production should be important enough to maintain old snapshots for. Hence, if there’s a state change compared to a production snapshot, you will increase the revision value.

A working sample is the one I gave in my previous comment. :wink:
You literally only have to set the Revision annotation on an Aggregate class, and you’re done.

After my reply, I checked out the Reference Guide around snapshot filtering. Although there’s a short section on the RevisionSnapshotFilter, nowhere does it explain the simplicity of configuring this…
As such, I’ve added a pull request to the guide to adjust this.
If you’re curious, you can find it here.

1 Like