Importing data from an old system -> Commands and Events with custom timestamps

We’re in the phase of rewriting an existing application (not CQRS based). This application has old data that we can use, and must use in the new system. Part of this data is used in the domain, in an aggregate root.

The new axon based system has a more extensive domain model than the old one (more business rules to handle).
One of the business rules is about an event must be received within X days of another event.

The old data has timestamps, so we could do an import which could check the previously mentioned business rule.

At the moment we do an import of all data, converting this data to an command which will be handled by the system. But the previously mentioned business rule could never be triggered, because the timestamp of the command, and the resulting event, will be the timestamp of the current import, and not that of the data of the old system

Is it possible to somehow add metadata to the command (only during import), that will be picked up by the events created, WITHOUT cluttering the code of the aggregate root with “if import then” code paths?

If not, should this be an feature request for axon? Because importing old data is a very common use case, and being able to correctly set the timestamp of the events generated would be a plus, in mine opinion.

I’m very interested in your opinion(s).

Kind regards,

Joep

Hi Joep,

when importing data, you’re actually storing data related to decisions already made. Considering that, the “pure” approach would be to import into the event store directly.

However, it’s not always practical. In similar situations in the past, we have sent commands to a system, based on records in legacy a application’s database. For backdating, we used JodaTimeUtils to set the timestamp to the time where the actual record was inserted. Since Axon uses JodaTime to figure out “now”, the events are timestamped with the time you set earlier.
It did bite us a bit in the *ss, because we didn’t properly backdate all events. In some cases, we have an update event that preceeds a creation event because of this. So if you’re going down backdating lane, make sure you get this right.

Also not that there may be a difference between the time a fact was recorded (event timestamp) and the time the fact occured (timestamp in payload of event). An import is a typical case where these diverge.

Cheers,

Allard

Hi,

Below approach of using DateTimeUtils is a bit tricky because it will backdate any other events that the system processes during the import. So it should be done on an “import-only” instance. Alternatively Axon could provide a factory or strategy for determining event time in GenericEventMessage. Would a patch for this be considered ?

Jorg

Hi Jorg,

such strategy is already in place, as far as I know. In the GenericEventMessage, you can configure the Clock that Axon should use to get the current time. You can change that to be your own Clock, if you’d want to. In Axon 2, you can use Joda’s ability to configure the current time.

However, backdating timestamps will eventually bite you. Trust me, my bite marks still haven’t disappeared ;-). In the end, the moment when things really were recorded, was when the import was done. If there is another timestamp involved (e.g. someone registration date), then that date should probably be part of the Event itself (i.e. the message payload).

Cheers,

Allard