University Multi-Tenancy Example
A runnable example application exercises multi-tenancy end to end.
The university-multi-tenancy-examples demo opens courses and enrolls students for several tenants at once, and shows that each tenant keeps its own events, snapshots, projections and read models while no handler names a tenant.
The samples on the other pages are written for the documentation, so each one shows a single idea on its own. This demo wires the same features into a working application, which is the place to look for how they fit together.
See the university-multi-tenancy-examples example for the full source.
Its README covers running it in memory or against a multi-context Axon Server.
How it is put together
The demo is three Maven modules, so the same domain can be configured in both styles:
| Module | Contents |
|---|---|
The university domain and everything both variants share: the write slices, the statistics projection and read model, the audit log, and the tenant-scoped providers in |
|
The Configuration API variant. Its |
|
The Spring Boot variant. Its |
What it demonstrates
| Demo element | Feature |
|---|---|
|
The tenant lifecycle, with tenants known at startup, added at runtime, and removed again |
|
Disabling multi-tenancy through |
|
Tenant resolution from message metadata, the default resolver’s source |
|
Refusal to resolve a tenant, identical for an unknown tenant, a removed one, and a message naming none |
|
Describing a tenant-scoped component with a |
|
Registering providers, declaratively and as Spring beans |
|
One provider per component type, with a second provider for the same type refused at configuration time |
|
Tenant-aware command handling, with the course sourced from and appended to the command’s tenant |
|
Per-tenant event storage, with the same course identifier full in one tenant, and still open in another |
|
Per-tenant snapshots, stored in and read from the snapshot store of the entity’s own tenant |
|
Tenant-aware event processing, one processor projecting every tenant’s events into that tenant’s own read model |
|
An idempotent projection, deriving statistics from the identifiers in the event so a redelivery changes nothing |
|
The processor restart timeout, registered at its default so the knob is visible |
|
Tenant-aware query handling, reading back only the querying tenant’s data |
|
Tenant-aware subscription queries, where an update reaches only the subscriptions of the tenant it was emitted for |