How to set up distributed mode

This page explains how to configure Atoti What-If for distributed deployments where data is spread across multiple nodes.

What is distributed mode

In a distributed Atoti Server deployment, data is partitioned across multiple data nodes, with a query node coordinating requests. Atoti What-If supports this architecture by sending simulation operations to all data nodes via REST calls.

When distributed mode is enabled, the starter creates a RestDistributedDatabaseService that:

  • Discovers data node addresses from the distributed pivot
  • Forwards database operations to all nodes
  • Merges query results from multiple nodes
  • Handles authentication using JWT tokens

Prerequisites

Before enabling distributed mode:

  • Your Atoti Server application must be configured for distribution
  • A query node with IMultiVersionDistributedActivePivot must be available
  • JWT authentication must be configured
  • Data nodes must expose the Database Service REST API

How to enable distributed mode

Add the following properties to your application.yml:

atoti:
  what-if:
    distribution:
      enabled: true
      query-node-name: "MyQueryNode"

The query-node-name must match the name of your query node pivot as configured in your Atoti Server application.

Auto-configured beans

When distribution.enabled: true, the starter creates:

Bean Description
IDistributedQueryResultsMerger Merges results from multiple data nodes
AddressSupplier Supplies data node addresses from the distributed pivot
AuthenticatorSupplier Supplies JWT authenticators for REST calls
RestDistributedDatabaseService The distributed database service (marked as @Primary)

Configuration properties

Property Type Default Description
atoti.what-if.distribution.enabled boolean false Enables distributed mode
atoti.what-if.distribution.query-node-name String "" Name of the query node pivot
atoti.what-if.distribution.create-distributed-service boolean true Whether to auto-create RestDistributedDatabaseService

How to provide a custom address supplier

By default, the starter discovers data node addresses from the distributed pivot. To use a custom address supplier:

@Bean
public AddressSupplier customAddressSupplier() {
    return () -> Set.of(
        "http://data-node-1:8080/",
        "http://data-node-2:8080/",
        "http://data-node-3:8080/"
    );
}

How to provide a custom authenticator

By default, JWT authentication is used. To provide a custom authenticator:

@Bean
public AuthenticatorSupplier customAuthenticatorSupplier() {
    return () -> new MyCustomAuthenticator();
}

How to provide a custom distributed database service

To replace the auto-configured RestDistributedDatabaseService:

  1. Set create-distributed-service: false in your configuration:
atoti:
  what-if:
    distribution:
      enabled: true
      query-node-name: "MyQueryNode"
      create-distributed-service: false
  1. Define your custom bean:
@Bean
@Primary
public IDatabaseService customDistributedDatabaseService(
        IDistributedQueryResultsMerger resultsMerger,
        AddressSupplier addressSupplier,
        AuthenticatorSupplier authenticatorSupplier) {
    return new MyCustomDistributedDatabaseService(
            resultsMerger, addressSupplier, authenticatorSupplier);
}

How to customize result merging

The DefaultDistributedQueryResultsMerger combines query results from all data nodes. To customize merging logic:

@Bean
public IDistributedQueryResultsMerger customResultsMerger() {
    return new IDistributedQueryResultsMerger() {
        @Override
        public JsonDatabaseQueryResult mergeQueryResults(
                List<JsonDatabaseQueryResult> results) {
            // Custom merge logic
        }
        // Implement other methods as needed
    };
}

Error handling

The RestDistributedDatabaseService throws:

  • ActiveViamRuntimeException if no data node addresses are available
  • InternalServiceException if operations on distributed nodes fail

Ensure your error handling accounts for partial failures when some nodes are unreachable.