Tenant-Aware Event Storage
Tenant-aware event storage covers how events and snapshots are stored per tenant. Each tenant keeps its events in its own Axon Server context, so no tenant can read or write another tenant’s events.
Sourcing and appending events
With multi-tenancy enabled, the event store is automatically tenant-aware. No changes to how an event-sourced entity is loaded or how you append events are required.
With multi-tenancy enabled, the module registers the tenant-routing EventStorageEngine itself, so an application cannot register an EventStorageEngine of its own.
A single engine would serve every tenant from one place, giving up the per-tenant isolation this module exists for, so such a registration fails the configuration at startup.
Register a TenantEventStorageEngineFactory instead to control how each tenant’s engine is built.
When an entity is used in the context of a message handler, the tenant information is already available in the ProcessingContext. Source and append operations are automatically routed to the event store of the related tenant.
Publishing events without a context in contrast requires resolution of the tenant as described in the tenant resolution section.
|
Appending and sourcing require a resolvable tenant.
If no tenant can be resolved, the operation fails with a |
Aggregate-based Axon Server storage
The default tenant event-storage factory uses Axon Server’s tag-based storage and requires contexts with Dynamic Consistency Boundary (DCB) support.
For legacy Axon Server contexts without DCB support, replace that factory with AggregateBasedAxonServerTenantEventStorageEngineFactory.
It creates and caches one aggregate-based event storage engine per tenant context; the tenant-routing EventStorageEngine remains unchanged.
-
Declarative - Configuration API
-
Spring Boot
Register the aggregate-based factory while configuring event sourcing:
public void configure(EventSourcingConfigurer configurer) {
configurer.componentRegistry(registry -> registry.registerComponent(
TenantEventStorageEngineFactory.class, (1)
config -> new AggregateBasedAxonServerTenantEventStorageEngineFactory( (2)
config.getComponent(AxonServerConnectionManager.class),
config.getComponent(EventConverter.class),
config.getOptionalComponent(EventTypeResolver.class).orElse(EventTypeResolver.DEFAULT),
config.getOptionalComponent(new TypeReference<TenantComponentProvider<Converter>>() {
}).orElse(null))
));
}
| 1 | Replace the default factory that builds each tenant’s event storage engine. |
| 2 | Construct an aggregate-based engine for each tenant’s Axon Server context. |
Expose the factory as a Spring bean:
@Bean
public TenantEventStorageEngineFactory tenantEventStorageEngineFactory(Configuration configuration) {
return new AggregateBasedAxonServerTenantEventStorageEngineFactory( (1)
configuration.getComponent(AxonServerConnectionManager.class),
configuration.getComponent(EventConverter.class),
configuration.getOptionalComponent(EventTypeResolver.class).orElse(EventTypeResolver.DEFAULT),
configuration.getOptionalComponent(new TypeReference<TenantComponentProvider<Converter>>() {
}).orElse(null)
);
}
| 1 | The factory selects the aggregate-based event storage engine for every tenant context. |
Use this option only for non-DCB contexts. Applications using DCB contexts need no configuration and should retain the default tag-based factory.
Snapshots
Snapshots follow the events they summarize. A snapshot is stored in, and loaded from, the snapshot store of the same tenant as the entity it belongs to. This happens automatically whenever snapshotting is configured, with no tenant-specific setup.
As with the event storage engine, an application cannot register a SnapshotStore of its own.
Register a TenantSnapshotStoreFactory instead to control how each tenant’s snapshot store is built.
Reading across tenants
Sourcing and appending act on a single tenant, resolved from the message being handled. Reading events across tenants, for example to build read models, is provided by the multi-tenant pooled-streaming support rather than by a single-tenant sourcing call. See tenant-aware event processing for details.