Events Priming/Migration

Hi,

DB migration tools such as Flyway and Liquibase and other alike are very useful, especially in priming database systems.

Is there something similar in AXON? A system starts with no events, when this may need priming. If this feature exists already, can you please point me to the documentation as I was not able to find it. On the other hand, if this feature does not yet exists and is something that interests you, I am more than happy to contribute.

Thank you in advance,

Albert Attard

Hi Albert,

at the moment, there are no table creation scripts in Axon. For the JPA based components, the JPA implementation is capable of creating the tables (based on naming conventions that have been configured with it). For the JDBC components, the table and column names are configurable.

However, having some Flyway and/or Liquibase definitions to create the tables (assuming defaults) would be nice to have. Having them would be better than SQL scripts, as they are database-specific.

If you’re willing to contribute this, that would be great.
Cheers,

Allard

Thanks for your prompt reply Allard.

I did not explain myself properly. Here I am not referring to the database migration scripts, but to the priming and/or migration of commands and/or events. AXON uses the database, but it does not depend on one. I understand you are developing a file based persistence layer which keeps up the performance over time despite the vast number of events. Furthermore, others may decide to develop their custom persistence layer and this needs to be compatible with that.

Say that I have a system which requires an admin account and some basic information, for example. I would like to have means to send a group of command and/or events while the system starts (similar to how Flyway and Liquibase works). I do not want to trigger these commands/events every time the system starts, but only if these have not yet been triggered before. These can also be corrective events that needs to be triggered once following a bug fix deployment.

Following is a suggestion

@SomeAnnotation(“V1.1.7”)
public class SomeClassName {

/* Injection like Saga? */
@Autowired
private CommandGateway commandGateway;

@PossiblySomeotherAnnotation
public void run() {
commandGateway.send(new CreateUserCommand(/parameters/));
}
}

AXON will then guarantee that these commands are only executed once. Resources can be autowired in a similar fashon to sagas. These are short live objects and they can be discarded once executed.

This is just a thought and you are more than welcome to bake this as best fits framework, always if you like the idea. Again, I am more that happy to contribute to this or anything else.

With reference to one of your sentences:

However, having some Flyway and/or Liquibase definitions to create the tables (assuming defaults) would be nice to have. Having them would be better than SQL scripts, as they are database-specific.

I have a Flyway script which can be used (attached), but I do not think that this should be included in AXON because the persistence layer is quite dependent on the project. I used string UUID which are CHAR(36), but these can be saved as BINARY(16) (if I recall correctly), which are even smaller and faster. Some others may use numeric ids instead, in which case these need to be UNSIGNED BIGINT.

Would like to take this opportunity to wish you and your loved ones all the best.

Albert

V1__init_axon.sql (3.59 KB)

We actually use Flyway for this in our Axon application. We have two instances of Flyway pointed at two separate sets of migrations, tracked in two separate tables.

The first is invoked early in the application’s startup sequence, just after the database connection is opened but before Axon initializes. It’s used for low-level database changes (creating query model tables, etc.) and consists solely of SQL scripts.

The second is invoked after all the Axon components have initialized but before the application starts accepting requests from clients. It’s used for application-level things like you describe, or for event-replay migrations when we need one of those. With a few exceptions, all the migrations in the second phase are Java classes implementing Flyway’s JdbcMigration interface. They’re free to call all the Axon APIs including dispatching commands and publishing events.

For the second phase, we just have to instantiate it and set some properties, like this:

Flyway flyway = new Flyway();
flyway.setBaselineOnMigrate(true);
flyway.setBaselineVersionAsString("0");
flyway.setDataSource(dataSource);
flyway.setLocations("classpath:" + getClass().getPackage().getName().replace('.', '/'));
flyway.setTable("application_schema_versions");

The setLocations() call in that snippet is so it will look for migration classes in the same package that code snippet lives, but you could set it to something else instead.

Flyway ends up doing the trick nicely for this; it has all the version tracking logic we need and fully supports executing arbitrary code to perform a migration.

-Steve

Thank you very much for your feedback and please accept my apologies for taking so long to reply.

I will think about your recommendation and see how this fits best my scenario. To be honest I do not want to rely on the database at all as AXON does not depend on the database. I understand that you are developing (or maybe it is in production by now) a file-based persistence layer which keeps the performance despite the sheer number of events. The solution recommended before will not work in such case.

Nevertheless, thank you very much for sharing this with the community.