Class MultiTenantTrackingToken
- All Implemented Interfaces:
TrackingToken
TrackingToken holding one position per tenant, positioning the merged read stream that feeds event
processors across all tenants.
It reuses a MultiSourceTrackingToken for the per-tenant positions, their aggregation, and their
serialization, and adds only what that token deliberately refuses: tolerance for a changing set of tenants. The set
of tenants grows and shrinks as tenants are added and removed, so when a processor compares a stored token (written
for an earlier set of tenants) with a live token (for the current set), the two carry different tenants. This token
tolerates that: its lowerBound(org.axonframework.messaging.eventhandling.processing.streaming.token.TrackingToken), upperBound(org.axonframework.messaging.eventhandling.processing.streaming.token.TrackingToken), covers(org.axonframework.messaging.eventhandling.processing.streaming.token.TrackingToken), and samePositionAs(org.axonframework.messaging.eventhandling.processing.streaming.token.TrackingToken) operate
over the union of both tokens' tenants, treating a tenant present in only one of them as being at its beginning in
the other. A tenant added since the stored token was written therefore streams from its beginning. Confining the
tolerance here keeps the shared MultiSourceTrackingToken's strict guardrail intact.
The fully qualified class name is written into every multi-tenant processor's token store when the token is serialized. Renaming or moving this class therefore breaks existing token stores, so it can only be done together with a token migration.
- Since:
- 5.3.0
- Author:
- Laura Devriendt
-
Field Summary
Fields inherited from interface org.axonframework.messaging.eventhandling.processing.streaming.token.TrackingToken
BATCH_END_RESOURCE_KEY, FIRST, LATEST, RESOURCE_KEY -
Constructor Summary
ConstructorsConstructorDescriptionMultiTenantTrackingToken(Map<String, @Nullable TrackingToken> tenantTokens) Constructs a token holding the giventenantTokens, keyed by tenant id. -
Method Summary
Modifier and TypeMethodDescriptionadvancedTo(String tenantId, TrackingToken newToken) Returns a copy of this token with the giventenantIdadvanced tonewToken.booleancovers(TrackingToken other) Indicates whether this token covers theothertoken completely.static MultiTenantTrackingTokenempty()Returns an empty token, holding no tenant positions.booleanstatic MultiTenantTrackingTokenfrom(@Nullable TrackingToken token) Adapts the giventokento aMultiTenantTrackingToken: an empty token whennull, or the token itself when it already is one.inthashCode()lowerBound(TrackingToken other) Returns a token that represents the lower bound between this and theothertoken.position()Return the estimated relative position this token represents.booleansamePositionAs(TrackingToken other) Indicates whetherthistoken is at the exact same spot in the event stream as theothertoken.@Nullable TrackingTokentokenForTenant(String tenantId) Returns the position of the giventenantId, ornullwhen this token holds no position for it.toString()upperBound(TrackingToken other) Returns the token that represents the furthest possible position in a stream that either this token or the givenotherrepresents.
-
Constructor Details
-
MultiTenantTrackingToken
Constructs a token holding the giventenantTokens, keyed by tenant id.- Parameters:
tenantTokens- the position per tenant, keyed by tenant id
-
-
Method Details
-
empty
Returns an empty token, holding no tenant positions.- Returns:
- an empty
MultiTenantTrackingToken
-
from
Adapts the giventokento aMultiTenantTrackingToken: an empty token whennull, or the token itself when it already is one.- Parameters:
token- the token to adapt- Returns:
- the token as a
MultiTenantTrackingToken - Throws:
IllegalArgumentException- if the token is a different, incompatible type
-
advancedTo
Returns a copy of this token with the giventenantIdadvanced tonewToken.- Parameters:
tenantId- the tenant whose position is advancednewToken- the new position for the tenant- Returns:
- a token holding the advanced position for the tenant
-
tokenForTenant
Returns the position of the giventenantId, ornullwhen this token holds no position for it.- Parameters:
tenantId- the tenant to return the position of- Returns:
- the tenant's position, or
nullwhen absent
-
lowerBound
Description copied from interface:TrackingTokenReturns a token that represents the lower bound between this and theothertoken. Effectively, the returned token will cause events not received by both this and theothertoken to be redelivered.- Specified by:
lowerBoundin interfaceTrackingToken- Parameters:
other- The token to compare to this one- Returns:
- The token representing the lower bound of the two
-
upperBound
Description copied from interface:TrackingTokenReturns the token that represents the furthest possible position in a stream that either this token or the givenotherrepresents. Effectively, this means this token will only deliver events that neither this, nor the other have been received.- Specified by:
upperBoundin interfaceTrackingToken- Parameters:
other- The token to compare this token to- Returns:
- a token that represents the furthest position of this or the other stream
-
covers
Description copied from interface:TrackingTokenIndicates whether this token covers theothertoken completely. That means that this token represents a position in a stream that has received all the events that a stream represented by theothertoken has received.Note that this operation is only safe when comparing tokens obtained from events from the same
StreamableEventSource.- Specified by:
coversin interfaceTrackingToken- Parameters:
other- The token to compare to this one- Returns:
trueif this token covers the other, otherwisefalse
-
samePositionAs
Description copied from interface:TrackingTokenIndicates whetherthistoken is at the exact same spot in the event stream as theothertoken.This method is particularly useful when comparing tokens from different points in time, such as during replay detection, where token implementations may naturally differ.
By default, this method checks bidirectional coverage:
this.covers(other) && other.covers(this), which ensures both tokens are at the same position.- Specified by:
samePositionAsin interfaceTrackingToken- Parameters:
other- The token to validate againstthistoken.- Returns:
trueif this token is at the same location as the other token, otherwisefalse. Returnsfalseifotherisnull.- See Also:
-
position
Description copied from interface:TrackingTokenReturn the estimated relative position this token represents. In case no estimation can be given anOptionalLong.empty()will be returned.- Specified by:
positionin interfaceTrackingToken- Returns:
- the estimated relative position of this token
-
equals
-
hashCode
public int hashCode() -
toString
-