Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright (c) 2025 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY
* All Rights Reserved.
*/

package client;

// --8<-- [start:all]

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();
}
}

// --8<-- [end:all]
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2025 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY
* All Rights Reserved.
*/

package client;

// --8<-- [start:all]

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();
}
}

// --8<-- [end:all]
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright (c) 2025 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY
* All Rights Reserved.
*/

package client;

// --8<-- [start:all]

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();
}
}

// --8<-- [end:all]
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
title: Connecting to Tarantool cluster via crud
---

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

=== "tarantool-java-sdk"

```title="Подключенние к кластеру при помощи TJSDK"
--8<-- "client/TarantoolDBClusterConnectionTJSDKExample.java:all"
```

```title="Абстрактный класс для создания кластера в docker"
--8<-- "client/TarantoolDBClusterConnectionAbstractExample.java:all"
```

=== "cartridge-driver"

```title="Подключенние к кластеру при помощи Cartridge java"
--8<-- "client/TarantoolDBClusterConnectionCartridgeDriverExample.java:all"
```

```title="Абстрактный класс для создания кластера в docker"
--8<-- "client/TarantoolDBClusterConnectionAbstractExample.java:all"
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
title: Подключение к класетру Tarantool через crud
---

Следующий пример демонстрирует подключение к кластеру `Tarantool` через маршрутизаторы с
использованием модуля `crud`:

=== "tarantool-java-sdk"

```title="Подключенние к кластеру при помощи TJSDK"
--8<-- "client/TarantoolDBClusterConnectionTJSDKExample.java:all"
```

```title="Абстрактный класс для создания кластера в docker"
--8<-- "client/TarantoolDBClusterConnectionAbstractExample.java:all"
```

=== "cartridge-driver"

```title="Подключенние к кластеру при помощи Cartridge java"
--8<-- "client/TarantoolDBClusterConnectionCartridgeDriverExample.java:all"
```

```title="Абстрактный класс для создания кластера в docker"
--8<-- "client/TarantoolDBClusterConnectionAbstractExample.java:all"
```
1 change: 1 addition & 0 deletions documentation/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ nav:
- Подключение к узлам:
- pages/client/examples/connection/index.md
- pages/client/examples/connection/single-node.md
- pages/client/examples/connection/crud-cluster.md
- Tarantool Testcontainers:
- pages/testcontainers/index.md
- Одиночный узел:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,4 +392,27 @@ public static void bootstrap(
throw new ContainerLaunchException("Timed out waiting for cluster to bootstrap", exc);
}
}

/**
* Adds additional users into global section of passed configuration.
*
* @return copy instance of passed configuration
*/
public static Tarantool3Configuration addUsers(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Нужны тесты на этот метод

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Сделано

Tarantool3Configuration old, Map<String, UsersProperty> users) {
if (old == null) {
return null;
}
final Tarantool3Configuration copy =
ConfigurationUtils.create(ConfigurationUtils.writeAsString(old));

final Credentials credentials = copy.getCredentials().orElseGet(Credentials::new);
final Users oldUsers = credentials.getUsers().orElseGet(Users::new);

users.forEach(oldUsers::setAdditionalProperty);

credentials.setUsers(oldUsers);
copy.setCredentials(credentials);
return copy;
}
}
Loading