Connecting to Tarantool cluster via crud

The following example demonstrates connecting to a Tarantool cluster via routers with using the crud module:

Connect to cluster using TJSDK
import java.net.InetSocketAddress;
import java.util.Arrays;
import java.util.List;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import io.tarantool.client.crud.TarantoolCrudClient;
import io.tarantool.client.factory.TarantoolCrudClientBuilder;
import io.tarantool.client.factory.TarantoolFactory;
import io.tarantool.pool.InstanceConnectionGroup;

public class TarantoolDBClusterConnectionTJSDKExample
    extends TarantoolDBClusterConnectionAbstractExample {

  @Test
  @Override
  protected void simpleCrudConnection() {

    try (final TarantoolCrudClient crudClient = setupClient()) {
      final String helloWorld = "hello world";

      // Evals return instruction in Tarantool lua
      final List<String> helloResponse =
          crudClient.eval(String.format("return '%s'", helloWorld), String.class).join().get();
      Assertions.assertEquals(1, helloResponse.size());
      Assertions.assertEquals(helloWorld, helloResponse.get(0));
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  private static TarantoolCrudClient setupClient() throws Exception {

    // Returns routers addresses mapped from docker
    final InetSocketAddress firstRouterAddress = getRouterAddress(FIRST_ROUTER_CONTAINER_NAME);
    final InetSocketAddress secondRouterAddress = getRouterAddress(SECOND_ROUTER_CONTAINER_NAME);

    final TarantoolCrudClientBuilder crudClientBuilder = TarantoolFactory.crud();

    // Setup first connection group with "seller-user" user and 2 connection to first router
    final InstanceConnectionGroup firstRouterConnectionGroup =
        InstanceConnectionGroup.builder()
            .withHost(firstRouterAddress.getHostName())
            .withPort(firstRouterAddress.getPort())
            .withUser(SELLER_USER)
            .withPassword(SELLER_USER_PWD)
            .withSize(2)
            .withTag(SELLER_USER + "-connection")
            .build();

    // Setup second connection group with "user-1182" user and 3 connection to first router
    final InstanceConnectionGroup secondRouterConnectionGroup =
        InstanceConnectionGroup.builder()
            .withHost(secondRouterAddress.getHostName())
            .withPort(secondRouterAddress.getPort())
            .withUser(USER_1182)
            .withPassword(USER_1182_PWD)
            .withSize(3)
            .withTag(USER_1182 + "-connection")
            .build();

    final List<InstanceConnectionGroup> connectionGroupsList =
        Arrays.asList(firstRouterConnectionGroup, secondRouterConnectionGroup);

    // Create crud client instance and connect to routers
    // Two connection groups with different users in one client instance
    return crudClientBuilder.withGroups(connectionGroupsList).build();
  }
}
Abstract class to create cluster in docker
import java.net.InetSocketAddress;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.testcontainers.containers.tarantool.TarantoolContainer;
import org.testcontainers.containers.tarantool.config.ConfigurationUtils;
import org.testcontainers.containers.tdb.TDB2ClusterImpl;
import org.testcontainers.containers.tdb.TDBCluster;

import io.tarantool.autogen.Tarantool3Configuration;
import io.tarantool.autogen.credentials.users.usersProperty.UsersProperty;

public abstract class TarantoolDBClusterConnectionAbstractExample {

  private static final List<String> ROLES = List.of("super");

  protected static final String TARANTOOL_DB_IMAGE =
      System.getenv().getOrDefault("TARANTOOL_REGISTRY", "") + "tarantooldb:2.2.1";

  protected static final String SELLER_USER = "seller-user";
  protected static final String SELLER_USER_PWD = "pwd-1";

  protected static final String USER_1182 = "user-1182";
  protected static final String USER_1182_PWD = "pwd-2";

  protected static final String FIRST_ROUTER_CONTAINER_NAME = "router-1";
  protected static final String SECOND_ROUTER_CONTAINER_NAME = "router-2";

  protected static TDBCluster CLUSTER;

  protected abstract void simpleCrudConnection();

  @BeforeAll
  static void beforeAll() {
    CLUSTER = createTDBCluster();
    CLUSTER.start();
  }

  @AfterAll
  static void afterAll() {
    CLUSTER.close();
  }

  @SuppressWarnings("unchecked")
  private static TDBCluster createTDBCluster() {

    // Adds custom users to emulate documentation example
    Map<String, UsersProperty> users =
        Map.of(
            SELLER_USER,
            UsersProperty.builder().withPassword(SELLER_USER_PWD).withRoles(ROLES).build(),
            USER_1182,
            UsersProperty.builder().withPassword(USER_1182_PWD).withRoles(ROLES).build());

    final Tarantool3Configuration commonConfigWithoutCustomUsers =
        ConfigurationUtils.generateSimpleConfiguration(2, 3, 2);
    final Tarantool3Configuration config =
        ConfigurationUtils.addUsers(commonConfigWithoutCustomUsers, users);

    return TDB2ClusterImpl.builder(TARANTOOL_DB_IMAGE).withTDB2Configuration(config).build();
  }

  protected static InetSocketAddress getRouterAddress(String routerName) {
    final Map<String, TarantoolContainer<?>> routers = CLUSTER.routers();
    return routers.get(routerName).mappedAddress();
  }
}
Connect to cluster using cartridge-driver
import java.net.InetSocketAddress;
import java.util.List;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import io.tarantool.driver.api.TarantoolClient;
import io.tarantool.driver.api.TarantoolClientFactory;
import io.tarantool.driver.api.TarantoolResult;
import io.tarantool.driver.api.TarantoolServerAddress;
import io.tarantool.driver.api.tuple.TarantoolTuple;

public class TarantoolDBClusterConnectionCartridgeDriverExample
    extends TarantoolDBClusterConnectionAbstractExample {

  @Test
  @Override
  protected void simpleCrudConnection() {
    try (TarantoolClient<TarantoolTuple, TarantoolResult<TarantoolTuple>> crudClient =
        setupClient()) {
      final String helloWorld = "hello world";

      // Evals return instruction in Tarantool lua
      final List<?> helloResponse =
          crudClient.eval(String.format("return '%s'", helloWorld)).join();
      Assertions.assertEquals(1, helloResponse.size());
      Assertions.assertEquals(helloWorld, helloResponse.get(0));
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  private static TarantoolClient<TarantoolTuple, TarantoolResult<TarantoolTuple>> setupClient() {

    // Returns routers addresses mapped from docker
    final InetSocketAddress firstRouterAddress = getRouterAddress(FIRST_ROUTER_CONTAINER_NAME);
    final InetSocketAddress secondRouterAddress = getRouterAddress(SECOND_ROUTER_CONTAINER_NAME);

    // Create crud client instance and connect to routers
    return TarantoolClientFactory.createClient()
        .withAddresses(
            new TarantoolServerAddress(
                firstRouterAddress.getHostName(), firstRouterAddress.getPort()),
            new TarantoolServerAddress(
                secondRouterAddress.getHostName(), secondRouterAddress.getPort()))

        // Two connection groups with different users in one client instance
        .withCredentials(USER_1182, USER_1182_PWD)
        .withConnections(2)
        .withProxyMethodMapping()
        .build();
  }
}
Abstract class to create cluster in docker
import java.net.InetSocketAddress;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.testcontainers.containers.tarantool.TarantoolContainer;
import org.testcontainers.containers.tarantool.config.ConfigurationUtils;
import org.testcontainers.containers.tdb.TDB2ClusterImpl;
import org.testcontainers.containers.tdb.TDBCluster;

import io.tarantool.autogen.Tarantool3Configuration;
import io.tarantool.autogen.credentials.users.usersProperty.UsersProperty;

public abstract class TarantoolDBClusterConnectionAbstractExample {

  private static final List<String> ROLES = List.of("super");

  protected static final String TARANTOOL_DB_IMAGE =
      System.getenv().getOrDefault("TARANTOOL_REGISTRY", "") + "tarantooldb:2.2.1";

  protected static final String SELLER_USER = "seller-user";
  protected static final String SELLER_USER_PWD = "pwd-1";

  protected static final String USER_1182 = "user-1182";
  protected static final String USER_1182_PWD = "pwd-2";

  protected static final String FIRST_ROUTER_CONTAINER_NAME = "router-1";
  protected static final String SECOND_ROUTER_CONTAINER_NAME = "router-2";

  protected static TDBCluster CLUSTER;

  protected abstract void simpleCrudConnection();

  @BeforeAll
  static void beforeAll() {
    CLUSTER = createTDBCluster();
    CLUSTER.start();
  }

  @AfterAll
  static void afterAll() {
    CLUSTER.close();
  }

  @SuppressWarnings("unchecked")
  private static TDBCluster createTDBCluster() {

    // Adds custom users to emulate documentation example
    Map<String, UsersProperty> users =
        Map.of(
            SELLER_USER,
            UsersProperty.builder().withPassword(SELLER_USER_PWD).withRoles(ROLES).build(),
            USER_1182,
            UsersProperty.builder().withPassword(USER_1182_PWD).withRoles(ROLES).build());

    final Tarantool3Configuration commonConfigWithoutCustomUsers =
        ConfigurationUtils.generateSimpleConfiguration(2, 3, 2);
    final Tarantool3Configuration config =
        ConfigurationUtils.addUsers(commonConfigWithoutCustomUsers, users);

    return TDB2ClusterImpl.builder(TARANTOOL_DB_IMAGE).withTDB2Configuration(config).build();
  }

  protected static InetSocketAddress getRouterAddress(String routerName) {
    final Map<String, TarantoolContainer<?>> routers = CLUSTER.routers();
    return routers.get(routerName).mappedAddress();
  }
}