MongoTokenStore Usage

Hi,

I updated our spring boot project on version 3.1.1 of axon framework
and tried to use the new MongoTokenStore in order to store the trackingtokens of a read model service.

The service itself is registered as trackingprocessor with a specific processing group.

When I start the service all events are proccessed and everything seems fine.

If I now restart the service, there occur many error messages (possible one for each event):

2018-01-11 15:54:43.226 INFO 15044 — [omain.events]-0] o.a.e.TrackingEventProcessor : An error occurred while attempting to claim a token for segment: 0. Will retry later…
2018-01-11 15:54:43.228 INFO 15044 — [omain.events]-0] o.a.e.TrackingEventProcessor : An error occurred while attempting to claim a token for segment: 0. Will retry later…
2018-01-11 15:54:43.229 INFO 15044 — [omain.events]-0] o.a.e.TrackingEventProcessor : An error occurred while attempting to claim a token for segment: 0. Will retry later…
2018-01-11 15:54:43.231 INFO 15044 — [omain.events]-0] o.a.e.TrackingEventProcessor : An error occurred while attempting to claim a token for segment: 0. Will retry later…

Does anyone know, what could be the reason for this behaviour ?

Thanks in advance,

Benjamin

I forgot to mention that we use the following serializer:

@Bean

public Serializer serializer(ObjectMapper objectMapper)
{
objectMapper.registerModule(new KotlinModule());
return new JacksonSerializer(objectMapper);
}

Maybe it could be a part of the problem.

Hi Benjamin,

apparently, the MongoTrackingToken isn’t compatible with Jackson.
I suppose you want the JacksonSerializer to serialize your events to JSON?

Try the following configuration:

@Qualifier(“eventSerializer”)

@Bean

public Serializer serializer(ObjectMapper objectMapper)
{
objectMapper.registerModule(new KotlinModule());
return new JacksonSerializer(objectMapper);
}

This will keep the default (XStream) serializer for anything that isn’t an Event.
Cheers,

Allard

PS. It’s annoying that this error doesn’t log the exception itself. Will fix that.

Hi Allard,

I tried what you suggested, but then I get parsing errors from the XStream Serializer.
Is this because the existing events are serialized already completely with Json ?

Our complete AxonConfig looks like this:

`
@Bean
public MongoTemplate template(MongoClient mongoClient)
{
return new DefaultMongoTemplate(mongoClient, “service-eventstore”);
}

// @Qualifier(“eventSerializer”)
@Bean
public Serializer serializer(ObjectMapper objectMapper)
{
objectMapper.registerModule(new KotlinModule());
return new JacksonSerializer(objectMapper);
}

@Bean
public EventStorageEngine eventStore(MongoTemplate template, Serializer serializer)
{
return new MongoEventStorageEngine(serializer, null, template, new DocumentPerEventStorageStrategy());
}

@Autowired
public void configure(EventHandlingConfiguration configuration)
{
configuration.registerTrackingProcessor(“org.my.events”);
}

@Bean
public TokenStore tokenStore(MongoTemplate template, Serializer serializer)
{
return new MongoTokenStore(template, serializer);
}
`

Any ideas ?

Thanks.

Benjamin

Hi Benjamin,

Your suggestion is very likely true.

If you’ve already serialized events/sagas/snapshots/trackingTokens/assocationValues using another serializer and you change the serializer you’re using, you’ll get serialization errors.

So your config seems to suggest you were already using the JacksonSerializer, which in most scenarios is more than okay.

What Allard was mentioning however was to only use the JacksonSerializer for events, and use the ‘default’ serializer for the other entities (sagas/snapshots/trackingTokens/assocationValues).

The way to do that is to specify adjust your current serializer() function with the @Qualifier("eventSerializer"), like Allard suggested.

If that’s set up, then Axon will create a ‘default serializer’ for the other entities, which by default uses the XStreamSerializer implementation.

Thus, I’d imagine you could get serialization errors for sagas/snapshots/trackingTokens/assocationValues in adjusting your configuration like that, but your events should still use the JacksonSerializer in that scenario.

Lastly I’d like to note that the EventStorageEngine is the level were you’re able to provide both a default (for snapshots) and a event serializer.

As you’re specifying your own MongoEventStorageEngine, you’ll thus have to wire both the default and the event serializer, by using one of the more fine grained constructors of the MongoEventStorageEngine.

Hope this helps you out Benjamin!

Chees,

Steven

Hi Steven,

you are completely right, I changed it to:

`
@Qualifier(“eventSerializer”)
@Bean
public Serializer eventSerializer(ObjectMapper objectMapper)
{
objectMapper.registerModule(new KotlinModule());
return new JacksonSerializer(objectMapper);
}

@Bean
public EventStorageEngine eventStore(MongoTemplate template, Serializer serializer, @Qualifier(“eventSerializer”) Serializer eventSerializer)
{
return new MongoEventStorageEngine(serializer, null, eventSerializer, template, new DocumentPerEventStorageStrategy());
}
`

Now it seems to work as supposed.

Thank you :slight_smile:

Benjamin

Hi Benjamin,

Happy to hear that solved your issue!

Good luck with further development and maybe 'till your next question! :wink:

Cheers,

Steven