Hi,
I have an app that needs to be multi-tenant - ie separate databases altogether for each tenant. Using axon, I’d like to have a separate event store for each tenant. Here’s how I’m planning to approach this - but would help to get some validation/feedback
I have reviewed thread on a similar question here: https://groups.google.com/forum/#!topic/axonframework/GNXJUOXyalY
However, there JPA was used. I’m using a JDBC event store (don’t know much about JPA and don’t think I need the complexity). As usual, the challenge is to be able to switch db connections based on the tenant while reading and writing the eventstream (and managing transactions). I’m also using Spring currently if that is relevant.
Background:
- Each tenant has it’s own subdomain - tenA.app.com, tenB.app.com; however, it’s served by a single instance of the application.
- When a request comes in to a particular subdomain, a request filter sets an attribute
- From the controller when a command is sent, it picks up the tenant Id and includes it in the command.
- When a command is dispatched, the tenant Id is included (either in metadata or payload)
Now, in the command handler, the event sourcing repository should point to a different database based on the tenant.
I plan to extract the tenant Id and stick it into a ThreadLocal in the command handler;
Then, set up a jdbc-event-store with a ConnectionProvider that reads the tenant id from the thread local and creates and returns a database connection. Looking at JdbcEventStore and DefaultEventEntryStore, this seems like it should do the trick. A couple of areas where I’m uncomfortable/have doubts
- The Unit Of Work wrapper - since I’d provide a connectionprovider directly, it won’t be wrapped in a UoW. What are the implications?
`
public JdbcEventStore(ConnectionProvider connectionProvider) {
this(new DefaultEventEntryStore(connectionProvider), new XStreamSerializer());
}
public JdbcEventStore(DataSource dataSource) {
this(new DefaultEventEntryStore(
new UnitOfWorkAwareConnectionProviderWrapper(new DataSourceConnectionProvider(dataSource))),
new XStreamSerializer()
);
}
`
- Implementing ConnectionProvider correctly (transactions) - currently since I use spring, the SpringDataSourceConnectionProvider is used; That automatically picks up a spring txn aware connection; Is it ok to implement a ConnectionProvider that takes a DataSourceProvider which has a getDataSource(tenantId) and have a pretty much identical implementation?
Thanks for reading!
Raghu