Migration to Axon 2

Hi,

we just started working at the migration of an existing application to Axon 2. We are JPA based, so we can make use of the provided migration tool.

We are now busy at making the source compile again after upgrading the Axon dependency. While fixing the event classes, I realized that we will need additional event upcasters to support the migration.

For example, we had to drop the AggregateIdentifier type which doesn’t exist in Axon 2, and choose a type as a replacement. We decided to systematically use specific id types (e.g. UserId). Now, the tool handles the task of enriching the XML serialization with an element containing the identifier of the aggregate which raised the event. For the more general case (i.e. any other field of an event which happens to store a reference to an aggregate), we’ll need to ‘help’ the tool by providing the serialization of the new type. It looks like job for an upcaster, which should act after the existing upcasters to fill this last gap. What do you think of this approach?

Also, from the way the tool works, by loading the XML serialization, applying upcasters to it and saving it to the new event table, I understand that we will be able to throw away the upcasters when we’re done. Is this correct? That would be a very nice side effect, possibly something to repeat in the future if the code base becomes again cluttered with upcasters.

After we are finished with migrating the event store, we need to verify that each of the rows in the new event store table can be successfully deserialized to an instance of the Axon 2 events. Does the migration tool perform such a check?

Kind regards,
Gianluca Ortelli

Hi Gianluca,

migrating away from Axon 1 to Axon 2 is always a good thing. Be sure to remember what you did, because Axon 3 is on its way :wink:

If you used the StringAggregateIdentifier in Axon 1, just use a String in Axon 2. If you used a strong typed (custom) identifier, you should be able to use that identifier in Axon 2 without too much modification. Perhaps you’ll need to tell XStream how to (de)serialize your identifier to/from a String. That’s fairly simple. You can use the JodaTime serializers as an example.

Once you ran the tool, you can throw away any upcasters you had used in Axon 1. There is no need to convert them to the new Axon 2 upcaster API.

The migration tool, unfortunately, does not verify the event store when converts the entries. I’m pretty sure it’s easy to put in. Otherwise, build an EventVisitor that does EventMessage.getPayload() on each incoming event and visit all events in the store. That guarantees all events are being deserialized.

Cheers,

Allard

Hi Allard,

thanks for the advice, we are at a good point with the migration of events and sagas.

I did a first test by running the Axon 2 version of our application on a migrated eventstore: events and sagas are now doing well, but I get an error with Quartz jobs at startup. Before the migration there were already data in the QRTZ_JOB_DETAILS table (and probably in other quartz tables), and Axon 2 cannot read jobs in the old format. The (summarized) exception that I get is:

org.springframework.context.ApplicationContextException: Failed to start bean ‘quartzScheduler’;
caused by
org.springframework.scheduling.SchedulingException: Could not start Quartz Scheduler;
caused by

org.quartz.SchedulerConfigException: Failure occured during job recovery.
caused by

org.quartz.JobPersistenceException: Couldn’t store trigger ‘DEFAULT.6da64b5bd2ee-3d5218b0-92bd-447e-92d1-f7304261b48d’ for ‘AxonFramework-Events.event-9d6378de-dbb7-47c8-b2ba-e46decfaf9d2’ job:org.axonframework.eventhandling.scheduling.quartz.Quartz2FireEventJob
caused by

java.lang.ClassNotFoundException: org.axonframework.eventhandling.scheduling.quartz.Quartz2FireEventJob

I don’t like the option of just throwing away the old jobs, we have hundred of them. How can I make them compatible with Axon 2?

Kind regards,
Gianluca

Hi Gianluca,

I’m afraid that’s not a very simple thing to do. Quartz uses Java Serialization to serialize jobs. In Axon 2, the task class has been renamed to org.axonframework.eventhandling.scheduling.quartz.FireEventJob. Perhaps you could write a little conversion tool that reads the jobs using your old event data and writes the jobs back using the new format.
That conversion tool would need to have the old events as well as the new ones on the classpath. Since they probably have the same name, that would be a challenge. Since those events are likely to be quite simple, it might be enough to output their contents somewhere (e.g. a file) and read that file back in to generate the new events to schedule.

I wish I had a better solution to this, but I have never been in the situation where I had to migrate Quartz jobs, yet.

Cheers,

Allard