Class MultiTenantAxonServerCommandBusConnector

java.lang.Object
io.axoniq.framework.messaging.multitenancy.axonserver.commandhandling.MultiTenantAxonServerCommandBusConnector
All Implemented Interfaces:
ConnectorLifecycle, CommandBusConnector, MultiTenantAwareComponent, DescribableComponent

@Internal public class MultiTenantAxonServerCommandBusConnector extends Object implements CommandBusConnector, MultiTenantAwareComponent, ConnectorLifecycle
Multi-tenant Axon Server CommandBusConnector.

The connector composes one AxonServerCommandBusConnector per TenantDescriptor, each owning its own Axon Server connection, command handler subscriptions, and in-flight command tracking. Command subscription state and the incoming-command handler are replayed onto newly registered tenants.

Internal, because the connector is wired by AxonServerMultiTenancyConfigurationDefaults and reached through the CommandBusConnector component, never constructed by an application itself.

Since:
5.3.0
Author:
Jan Galinski, Jakob Hatzl
  • Constructor Details

  • Method Details

    • start

      public void start()
      Description copied from interface: ConnectorLifecycle
      Starts the connector.
      Specified by:
      start in interface ConnectorLifecycle
    • dispatch

      public CompletableFuture<CommandResultMessage> dispatch(CommandMessage command, @Nullable ProcessingContext processingContext)
      Resolves the connector of the tenant the given command belongs to and dispatches the command to it.
      Specified by:
      dispatch in interface CommandBusConnector
      Parameters:
      command - the command message to dispatch
      processingContext - the processing context for the command
      Returns:
      a CompletableFuture that will complete with the result of the command handling
    • subscribe

      public CompletableFuture<Void> subscribe(QualifiedName commandName, int loadFactor)
      Subscribes to a command on each tenant-specific connector with the given commandName and a loadFactor.

      The MultiTenantAxonServerCommandBusConnector keeps track of all known subscriptions and replays them on tenants dynamically added at runtime.

      Specified by:
      subscribe in interface CommandBusConnector
      Parameters:
      commandName - the QualifiedName of the command to subscribe to
      loadFactor - the load factor for the command, which can be used to control the distribution of command handling across multiple instances; should be a positive integer
      Returns:
      a CompletableFuture that completes successfully when this connector subscribed to the given commandName with the given loadFactor
    • unsubscribe

      public boolean unsubscribe(QualifiedName commandName)
      Unsubscribes from a command with the given commandName from each tenant-specific connector.
      Specified by:
      unsubscribe in interface CommandBusConnector
      Parameters:
      commandName - the QualifiedName of the command to unsubscribe from
      Returns:
      true if the unsubscription was successful, false otherwise
    • onIncomingCommand

      public void onIncomingCommand(CommandBusConnector.Handler handler)
      Registers a handler that will be called when an incoming command is received. The handler should process the command and call the provided ResultCallback to indicate success or failure.

      The handler is registered for each tenant-specific connection to make sure incoming commands from each tenant trigger the handling.

      Specified by:
      onIncomingCommand in interface CommandBusConnector
      Parameters:
      handler - a BiConsumer that takes a CommandMessage and a CommandBusConnector.ResultCallback
    • shutdownDispatching

      public CompletableFuture<Void> shutdownDispatching()
      Description copied from interface: ConnectorLifecycle
      Shuts down the connector gracefully.
      Specified by:
      shutdownDispatching in interface ConnectorLifecycle
      Returns:
      a CompletableFuture that completes when the connector has been shutdown.
    • disconnect

      public CompletableFuture<Void> disconnect()
      Description copied from interface: ConnectorLifecycle
      Disconnects the connector.
      Specified by:
      disconnect in interface ConnectorLifecycle
      Returns:
      a CompletableFuture that completes when the connector has been disconnected.
    • registerTenant

      public Registration registerTenant(TenantDescriptor tenantDescriptor)
      Description copied from interface: MultiTenantAwareComponent
      Registers the given tenantDescriptor as a known tenant with this multi-tenant aware component.

      The caller must retain the returned Registration and cancel it when the tenant is removed, since releasing the component's per-tenant resources rides on that cancellation.

      Specified by:
      registerTenant in interface MultiTenantAwareComponent
      Parameters:
      tenantDescriptor - The TenantDescriptor to register with this component.
      Returns:
      A Registration used to deregister the given tenantDescriptor.
    • registerAndStartTenant

      public Registration registerAndStartTenant(TenantDescriptor tenantDescriptor)
      Description copied from interface: MultiTenantAwareComponent
      Registers the given tenantDescriptor as a known tenant with this multi-tenant aware component. If applicable, this task will construct a tenant segment and start it.
      Specified by:
      registerAndStartTenant in interface MultiTenantAwareComponent
      Parameters:
      tenantDescriptor - The TenantDescriptor to register with this component.
      Returns:
      A Registration used to deregister the given tenantDescriptor.
    • describeTo

      public void describeTo(ComponentDescriptor descriptor)
      Description copied from interface: DescribableComponent
      Describe the properties of this DescribableComponent with the given descriptor.

      Components should call the appropriate describeProperty methods on the descriptor to register their properties. The descriptor is responsible for determining how these properties are formatted and structured in the final output.

      Best Practices: As a general rule, all relevant fields of a DescribableComponent implementation should be described in this method. However, developers have discretion to include only the fields that make sense in the context. Not every field may be meaningful for description purposes, especially internal implementation details. Furthermore, components might want to expose different information based on their current state. The final decision on what properties to include lies with the person implementing the describeTo method, who should focus on providing information that is useful for understanding the component's configuration and state.

      Example implementation:

       public void describeTo(ComponentDescriptor descriptor) {
           descriptor.describeProperty("name", this.name);
           descriptor.describeProperty("enabled", this.enabled);
           descriptor.describeProperty("configuration", this.configuration); // A nested component
           descriptor.describeProperty("handlers", this.eventHandlers);      // A collection
       }
       
      Specified by:
      describeTo in interface DescribableComponent
      Parameters:
      descriptor - The component descriptor to describe this DescribableComponentn its properties in.