diff --git a/pom.xml b/pom.xml
index 0cf92191..94e1aa1c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -396,9 +396,6 @@
**/integration/**/*Crud*Test.java
**/crud/**/*Test.java
-
- **/io/tarantool/spring/data*/integration/**/*Test.java
-
@{argLine} -Xmx1024m
diff --git a/tarantool-client/src/test/java/io/tarantool/client/integration/TarantoolCrudClientTest.java b/tarantool-client/src/test/java/io/tarantool/client/integration/TarantoolCrudClientTest.java
index 580fd194..ee3810d0 100644
--- a/tarantool-client/src/test/java/io/tarantool/client/integration/TarantoolCrudClientTest.java
+++ b/tarantool-client/src/test/java/io/tarantool/client/integration/TarantoolCrudClientTest.java
@@ -5,7 +5,6 @@
package io.tarantool.client.integration;
-import java.io.Serializable;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
@@ -35,7 +34,6 @@
import com.fasterxml.jackson.core.type.TypeReference;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
@@ -46,9 +44,9 @@
import org.junit.jupiter.params.provider.MethodSource;
import org.msgpack.value.ValueFactory;
import org.slf4j.LoggerFactory;
-import org.testcontainers.containers.TarantoolCartridgeContainer;
-import org.testcontainers.containers.TarantoolContainerOperations;
-import org.testcontainers.containers.VshardClusterContainer;
+import org.testcontainers.containers.cluster.ClusterContainer;
+import org.testcontainers.containers.cluster.cartridge.CartridgeClusterContainer;
+import org.testcontainers.containers.cluster.vshard.VshardClusterContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import org.testcontainers.junit.jupiter.Testcontainers;
@@ -88,7 +86,6 @@
import io.tarantool.pool.IProtoClientPool;
import io.tarantool.pool.InstanceConnectionGroup;
-@Disabled("Refactor TarantoolCartridgeContainer and VshardClusterContainer")
@Timeout(value = 10)
@Testcontainers
public class TarantoolCrudClientTest extends BaseTest {
@@ -103,9 +100,9 @@ public class TarantoolCrudClientTest extends BaseTest {
}
};
public static final Person STUB_PERSON = new Person(0, true, String.valueOf(0));
- private static TarantoolCartridgeContainer cartridgeContainer;
+ private static CartridgeClusterContainer cartridgeContainer;
private static VshardClusterContainer vshardClusterContainer;
- private static TarantoolContainerOperations clusterContainer;
+ private static ClusterContainer> clusterContainer;
public static final String ROUTER_1 = "ROUTER_1";
public static final String ROUTER_2 = "ROUTER_2";
private static TarantoolCrudClient client;
@@ -150,7 +147,7 @@ public static void setUp() throws Exception {
clusterContainer = vshardClusterContainer;
} else {
cartridgeContainer =
- new TarantoolCartridgeContainer(
+ new CartridgeClusterContainer(
"cartridge/Dockerfile",
dockerRegistry + "cartridge",
"cartridge/instances.yml",
@@ -325,7 +322,10 @@ public void testSelectAndInsertGeneral() {
assertEquals(expected.asList(), removeBucketId(insertResult));
List> selectResult =
- person.select(baseOptions, listPersonTypeRef, PkEquals(0)).join().get();
+ person
+ .select(Collections.singletonList(ConditionPkEquals(0)), listPersonTypeRef)
+ .join()
+ .get();
assertEquals(Collections.singletonList(expected), unpackT(selectResult));
}
@@ -356,17 +356,18 @@ public void testDMLTupleExtension() {
replaceResult =
personWithoutTupleExt.replace(baseOptions, listTypeRef, expected, OPTIONS).join();
- assertTrue(replaceResult.getFormat().isEmpty());
assertEquals(expected.asList(), removeBucketId(replaceResult.get()));
// select
TarantoolResponse>> selectResult =
- person.select(baseOptions, listPersonTypeRef, PkEquals(0)).join();
+ person.select(Collections.singletonList(ConditionPkEquals(0)), listPersonTypeRef).join();
assertFalse(selectResult.getFormats().isEmpty());
assertEquals(Collections.singletonList(expected), unpackT(selectResult.get()));
- selectResult = personWithoutTupleExt.select(baseOptions, listPersonTypeRef, PkEquals(0)).join();
- assertTrue(selectResult.getFormats().isEmpty());
+ selectResult =
+ personWithoutTupleExt
+ .select(Collections.singletonList(ConditionPkEquals(0)), listPersonTypeRef)
+ .join();
assertEquals(Collections.singletonList(expected), unpackT(selectResult.get()));
}
@@ -415,10 +416,6 @@ public void testSelectAndInsertTypeReference() {
assertEquals(Collections.singletonList(expected), unpackT(selectResult));
}
- private static List> PkEquals(int id) {
- return Collections.singletonList(Arrays.asList("==", "pk", id));
- }
-
private static Condition ConditionPkEquals(int id) {
return Condition.create("==", "pk", id);
}
diff --git a/tarantool-client/src/test/java/io/tarantool/client/integration/TarantoolCrudClientWithRetryTest.java b/tarantool-client/src/test/java/io/tarantool/client/integration/TarantoolCrudClientWithRetryTest.java
index b9f31030..4c3f6bd5 100644
--- a/tarantool-client/src/test/java/io/tarantool/client/integration/TarantoolCrudClientWithRetryTest.java
+++ b/tarantool-client/src/test/java/io/tarantool/client/integration/TarantoolCrudClientWithRetryTest.java
@@ -21,12 +21,11 @@
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.slf4j.LoggerFactory;
-import org.testcontainers.containers.TarantoolCartridgeContainer;
+import org.testcontainers.containers.cluster.cartridge.CartridgeClusterContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import org.testcontainers.junit.jupiter.Testcontainers;
@@ -36,7 +35,6 @@
import io.tarantool.core.exceptions.BoxError;
import io.tarantool.mapping.Tuple;
-@Disabled("Refactor TarantoolCartridgeContainer and VshardClusterContainer")
@Timeout(value = 5)
@Testcontainers
public class TarantoolCrudClientWithRetryTest {
@@ -84,8 +82,8 @@ private void execute() {
}
}
- private static final TarantoolCartridgeContainer tt =
- new TarantoolCartridgeContainer(
+ private static final CartridgeClusterContainer tt =
+ new CartridgeClusterContainer(
"cartridge/Dockerfile",
System.getenv().getOrDefault("TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX", "")
+ "cartridge",
diff --git a/tarantool-jackson-mapping/src/main/java/io/tarantool/mapping/crud/CrudResponse.java b/tarantool-jackson-mapping/src/main/java/io/tarantool/mapping/crud/CrudResponse.java
index 77adeba6..8ac54936 100644
--- a/tarantool-jackson-mapping/src/main/java/io/tarantool/mapping/crud/CrudResponse.java
+++ b/tarantool-jackson-mapping/src/main/java/io/tarantool/mapping/crud/CrudResponse.java
@@ -69,6 +69,9 @@ public List getMetadata() throws CrudException {
if (error != null) {
throw new CrudException(error);
}
+ if (response == null) {
+ return null;
+ }
return response.getMetadata();
}
diff --git a/tarantool-shared-resources/cartridge/app/api/crud_aux.lua b/tarantool-shared-resources/cartridge/app/api/crud_aux.lua
index 0980fbc9..048d19a4 100644
--- a/tarantool-shared-resources/cartridge/app/api/crud_aux.lua
+++ b/tarantool-shared-resources/cartridge/app/api/crud_aux.lua
@@ -11,8 +11,11 @@ local crud_methods_to_patch = {
'update',
'upsert',
'insert_many',
+ 'insert_object_many',
'replace_many',
+ 'replace_object_many',
'upsert_many',
+ 'upsert_object_many',
'truncate',
'count',
'len',
diff --git a/tarantool-shared-resources/vshard_cluster/Dockerfile b/tarantool-shared-resources/vshard_cluster/Dockerfile
index 5b17e584..3d43922e 100644
--- a/tarantool-shared-resources/vshard_cluster/Dockerfile
+++ b/tarantool-shared-resources/vshard_cluster/Dockerfile
@@ -1,18 +1,27 @@
ARG TARANTOOL_VERSION="3.5.0"
ARG IMAGE="tarantool/tarantool"
FROM --platform=linux/amd64 $IMAGE:$TARANTOOL_VERSION
+HEALTHCHECK NONE
ARG TARANTOOL_WORKDIR="/app"
ENV TARANTOOL_WORKDIR=$TARANTOOL_WORKDIR
+ARG APP_NAME="vshard-cluster"
WORKDIR $TARANTOOL_WORKDIR
-COPY "cluster" "$TARANTOOL_WORKDIR"
+COPY "cluster" "$TARANTOOL_WORKDIR/$APP_NAME"
+WORKDIR "$TARANTOOL_WORKDIR/$APP_NAME"
+RUN mkdir -p /etc/tarantool/instances.enabled && \
+ ln -s "$TARANTOOL_WORKDIR/$APP_NAME" /etc/tarantool/instances.enabled/app
RUN sed -i 's|http://archive.ubuntu.com/ubuntu/|http://mirror.yandex.ru/ubuntu/|g; s|http://security.ubuntu.com/ubuntu/|http://mirror.yandex.ru/ubuntu/|g' /etc/apt/sources.list
# install dependencies
RUN apt-get -y update && \
- apt-get -y install build-essential cmake make gcc git unzip cartridge-cli && \
+ apt-get -y install build-essential cmake make gcc git unzip && \
apt-get -y clean
-CMD tt init && tt build && tt start && sleep infinity
+CMD rm -f tt.yaml && \
+ TT_CONFIG=./config.yaml env -u TT_APP_NAME -u TT_INSTANCE_NAME tt init && \
+ TT_CONFIG=./config.yaml env -u TT_APP_NAME -u TT_INSTANCE_NAME tt build && \
+ TT_CONFIG=./config.yaml env -u TT_APP_NAME -u TT_INSTANCE_NAME tt start vshard-cluster && \
+ sleep infinity
diff --git a/tarantool-shared-resources/vshard_cluster/config.yaml b/tarantool-shared-resources/vshard_cluster/config.yaml
index 5a6065bd..85ab4473 100644
--- a/tarantool-shared-resources/vshard_cluster/config.yaml
+++ b/tarantool-shared-resources/vshard_cluster/config.yaml
@@ -35,22 +35,22 @@ groups:
storage-001-a:
iproto:
listen:
- - uri: "3303"
+ - uri: "127.0.0.1:3303"
storage-001-b:
iproto:
listen:
- - uri: "3304"
+ - uri: "127.0.0.1:3304"
storage-002:
leader: storage-002-a
instances:
storage-002-a:
iproto:
listen:
- - uri: "3305"
+ - uri: "127.0.0.1:3305"
storage-002-b:
iproto:
listen:
- - uri: "3306"
+ - uri: "127.0.0.1:3306"
routers:
app:
module: router
@@ -62,10 +62,10 @@ groups:
router-001-a:
iproto:
listen:
- - uri: "3301"
+ - uri: "0.0.0.0:3301"
router-002:
instances:
router-002-a:
iproto:
listen:
- - uri: "3302"
+ - uri: "0.0.0.0:3302"
diff --git a/tarantool-shared-resources/vshard_cluster/crud_aux.lua b/tarantool-shared-resources/vshard_cluster/crud_aux.lua
index 0980fbc9..048d19a4 100644
--- a/tarantool-shared-resources/vshard_cluster/crud_aux.lua
+++ b/tarantool-shared-resources/vshard_cluster/crud_aux.lua
@@ -11,8 +11,11 @@ local crud_methods_to_patch = {
'update',
'upsert',
'insert_many',
+ 'insert_object_many',
'replace_many',
+ 'replace_object_many',
'upsert_many',
+ 'upsert_object_many',
'truncate',
'count',
'len',
diff --git a/tarantool-spring-data/tarantool-spring-data-27/pom.xml b/tarantool-spring-data/tarantool-spring-data-27/pom.xml
index 7845b5d6..9e2d5f2b 100644
--- a/tarantool-spring-data/tarantool-spring-data-27/pom.xml
+++ b/tarantool-spring-data/tarantool-spring-data-27/pom.xml
@@ -43,5 +43,11 @@
io.tarantool
tarantool-spring-data-core
+
+ com.fasterxml.jackson.dataformat
+ jackson-dataformat-yaml
+ 2.13.5
+ test
+
diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/BaseIntegrationTest.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/BaseIntegrationTest.java
index 219f104f..8326ba71 100644
--- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/BaseIntegrationTest.java
+++ b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/BaseIntegrationTest.java
@@ -11,12 +11,11 @@
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Timeout;
import org.slf4j.LoggerFactory;
-import org.testcontainers.containers.TarantoolCartridgeContainer;
-import org.testcontainers.containers.TarantoolContainerOperations;
-import org.testcontainers.containers.VshardClusterContainer;
+import org.testcontainers.containers.cluster.ClusterContainer;
+import org.testcontainers.containers.cluster.cartridge.CartridgeClusterContainer;
+import org.testcontainers.containers.cluster.vshard.VshardClusterContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME;
@@ -24,11 +23,10 @@
import static io.tarantool.spring.data27.utils.TarantoolTestSupport.writeTestPropertiesYaml;
import io.tarantool.spring.data27.config.properties.TarantoolProperties;
-@Disabled("Refactor TarantoolCartridgeContainer and VshardClusterContainer")
@Timeout(60)
public abstract class BaseIntegrationTest {
- protected static TarantoolContainerOperations> clusterContainer;
+ protected static ClusterContainer> clusterContainer;
private static final String dockerRegistry =
System.getenv().getOrDefault("TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX", "");
@@ -55,8 +53,8 @@ private static void configureContainer() {
}
clusterContainer = vshardClusterContainer;
} else {
- TarantoolCartridgeContainer cartridgeContainer =
- new TarantoolCartridgeContainer(
+ CartridgeClusterContainer cartridgeContainer =
+ new CartridgeClusterContainer(
"cartridge/Dockerfile",
dockerRegistry + "cartridge",
"cartridge/instances.yml",
@@ -77,6 +75,8 @@ private static void writeConfigurationFile() throws IOException {
final TarantoolProperties properties = new TarantoolProperties();
properties.setHost(clusterContainer.getHost());
properties.setPort(clusterContainer.getPort());
+ properties.setUserName(clusterContainer.getUsername());
+ properties.setPassword(clusterContainer.getPassword());
writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME, properties);
}
@@ -94,6 +94,14 @@ protected static int getPort() {
return clusterContainer.getPort();
}
+ protected static String getUsername() {
+ return clusterContainer.getUsername();
+ }
+
+ protected static String getPassword() {
+ return clusterContainer.getPassword();
+ }
+
protected static boolean isCartridgeAvailable() {
return System.getenv().getOrDefault("TARANTOOL_VERSION", "").matches("2.*");
}
diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/CrudConfigurations.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/CrudConfigurations.java
index f304dc4d..2177d1d0 100644
--- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/CrudConfigurations.java
+++ b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/CrudConfigurations.java
@@ -13,7 +13,6 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@@ -21,8 +20,6 @@
import org.springframework.test.context.TestPropertySource;
import static io.tarantool.client.TarantoolClient.DEFAULT_TAG;
-import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_PASSWORD;
-import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_USERNAME;
import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH;
import static io.tarantool.spring.data27.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE;
import static io.tarantool.spring.data27.utils.TarantoolTestSupport.PERSON_SPACE;
@@ -34,7 +31,6 @@
import io.tarantool.spring.data27.integration.BaseIntegrationTest;
import io.tarantool.spring.data27.repository.config.EnableTarantoolRepositories;
-@Disabled("Refactor TarantoolCartridgeContainer and VshardClusterContainer")
@TestPropertySource(properties = {DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH})
abstract class CrudConfigurations extends BaseIntegrationTest {
@@ -51,8 +47,8 @@ protected static void beforeAll() throws IOException {
InstanceConnectionGroup.builder()
.withHost(clusterContainer.getHost())
.withPort(clusterContainer.getPort())
- .withUser(DEFAULT_CRUD_USERNAME)
- .withPassword(DEFAULT_CRUD_PASSWORD)
+ .withUser(getUsername())
+ .withPassword(getPassword())
.withTag(DEFAULT_TAG)
.withSize(4)
.build();
diff --git a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/RepositoryConfigurationExtensionTest.java b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/RepositoryConfigurationExtensionTest.java
index 95af4dd9..6800ce18 100644
--- a/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/RepositoryConfigurationExtensionTest.java
+++ b/tarantool-spring-data/tarantool-spring-data-27/src/test/java/io/tarantool/spring/data27/integration/crud/RepositoryConfigurationExtensionTest.java
@@ -73,7 +73,11 @@ void testRegisterBeansForRootWithCustomClientConfigShouldThrows() {
}
private static TarantoolCrudClientBuilder getCrudClientSettings() {
- return TarantoolFactory.crud().withHost(getHost()).withPort(getPort());
+ return TarantoolFactory.crud()
+ .withHost(getHost())
+ .withPort(getPort())
+ .withUser(getUsername())
+ .withPassword(getPassword());
}
private static TarantoolBoxClientBuilder getBoxClientSettings() {
diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/BaseIntegrationTest.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/BaseIntegrationTest.java
index 14a9cd72..43fc7a50 100644
--- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/BaseIntegrationTest.java
+++ b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/BaseIntegrationTest.java
@@ -11,12 +11,11 @@
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Timeout;
import org.slf4j.LoggerFactory;
-import org.testcontainers.containers.TarantoolCartridgeContainer;
-import org.testcontainers.containers.TarantoolContainerOperations;
-import org.testcontainers.containers.VshardClusterContainer;
+import org.testcontainers.containers.cluster.ClusterContainer;
+import org.testcontainers.containers.cluster.cartridge.CartridgeClusterContainer;
+import org.testcontainers.containers.cluster.vshard.VshardClusterContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME;
@@ -24,11 +23,10 @@
import static io.tarantool.spring.data31.utils.TarantoolTestSupport.writeTestPropertiesYaml;
import io.tarantool.spring.data31.config.properties.TarantoolProperties;
-@Disabled("Refactor TarantoolCartridgeContainer and VshardClusterContainer")
@Timeout(60)
public abstract class BaseIntegrationTest {
- protected static TarantoolContainerOperations> clusterContainer;
+ protected static ClusterContainer> clusterContainer;
private static final String dockerRegistry =
System.getenv().getOrDefault("TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX", "");
@@ -55,8 +53,8 @@ private static void configureContainer() {
}
clusterContainer = vshardClusterContainer;
} else {
- TarantoolCartridgeContainer cartridgeContainer =
- new TarantoolCartridgeContainer(
+ CartridgeClusterContainer cartridgeContainer =
+ new CartridgeClusterContainer(
"cartridge/Dockerfile",
dockerRegistry + "cartridge",
"cartridge/instances.yml",
@@ -77,6 +75,8 @@ private static void writeConfigurationFile() throws IOException {
final TarantoolProperties properties = new TarantoolProperties();
properties.setHost(clusterContainer.getHost());
properties.setPort(clusterContainer.getPort());
+ properties.setUserName(clusterContainer.getUsername());
+ properties.setPassword(clusterContainer.getPassword());
writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME, properties);
}
@@ -94,6 +94,14 @@ protected static int getPort() {
return clusterContainer.getPort();
}
+ protected static String getUsername() {
+ return clusterContainer.getUsername();
+ }
+
+ protected static String getPassword() {
+ return clusterContainer.getPassword();
+ }
+
protected static boolean isCartridgeAvailable() {
return System.getenv().getOrDefault("TARANTOOL_VERSION", "").matches("2.*");
}
diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/CrudConfigurations.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/CrudConfigurations.java
index 3095faba..27b9533d 100644
--- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/CrudConfigurations.java
+++ b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/CrudConfigurations.java
@@ -13,7 +13,6 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@@ -21,8 +20,6 @@
import org.springframework.test.context.TestPropertySource;
import static io.tarantool.client.TarantoolClient.DEFAULT_TAG;
-import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_PASSWORD;
-import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_USERNAME;
import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH;
import static io.tarantool.spring.data31.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE;
import static io.tarantool.spring.data31.utils.TarantoolTestSupport.PERSON_SPACE;
@@ -34,7 +31,6 @@
import io.tarantool.spring.data31.integration.BaseIntegrationTest;
import io.tarantool.spring.data31.repository.config.EnableTarantoolRepositories;
-@Disabled("Refactor TarantoolCartridgeContainer and VshardClusterContainer")
@TestPropertySource(properties = {DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH})
abstract class CrudConfigurations extends BaseIntegrationTest {
@@ -51,8 +47,8 @@ protected static void beforeAll() throws IOException {
InstanceConnectionGroup.builder()
.withHost(clusterContainer.getHost())
.withPort(clusterContainer.getPort())
- .withUser(DEFAULT_CRUD_USERNAME)
- .withPassword(DEFAULT_CRUD_PASSWORD)
+ .withUser(getUsername())
+ .withPassword(getPassword())
.withTag(DEFAULT_TAG)
.withSize(4)
.build();
diff --git a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/RepositoryConfigurationExtensionTest.java b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/RepositoryConfigurationExtensionTest.java
index 8346c846..f7088143 100644
--- a/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/RepositoryConfigurationExtensionTest.java
+++ b/tarantool-spring-data/tarantool-spring-data-31/src/test/java/io/tarantool/spring/data31/integration/crud/RepositoryConfigurationExtensionTest.java
@@ -73,7 +73,11 @@ void testRegisterBeansForRootWithCustomClientConfigShouldThrows() {
}
private static TarantoolCrudClientBuilder getCrudClientSettings() {
- return TarantoolFactory.crud().withHost(getHost()).withPort(getPort());
+ return TarantoolFactory.crud()
+ .withHost(getHost())
+ .withPort(getPort())
+ .withUser(getUsername())
+ .withPassword(getPassword());
}
private static TarantoolBoxClientBuilder getBoxClientSettings() {
diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/BaseIntegrationTest.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/BaseIntegrationTest.java
index 38f94c5d..cdde405f 100644
--- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/BaseIntegrationTest.java
+++ b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/BaseIntegrationTest.java
@@ -11,12 +11,11 @@
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Timeout;
import org.slf4j.LoggerFactory;
-import org.testcontainers.containers.TarantoolCartridgeContainer;
-import org.testcontainers.containers.TarantoolContainerOperations;
-import org.testcontainers.containers.VshardClusterContainer;
+import org.testcontainers.containers.cluster.ClusterContainer;
+import org.testcontainers.containers.cluster.cartridge.CartridgeClusterContainer;
+import org.testcontainers.containers.cluster.vshard.VshardClusterContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME;
@@ -24,11 +23,10 @@
import static io.tarantool.spring.data32.utils.TarantoolTestSupport.writeTestPropertiesYaml;
import io.tarantool.spring.data32.config.properties.TarantoolProperties;
-@Disabled("Refactor TarantoolCartridgeContainer and VshardClusterContainer")
@Timeout(60)
public abstract class BaseIntegrationTest {
- protected static TarantoolContainerOperations> clusterContainer;
+ protected static ClusterContainer> clusterContainer;
private static final String dockerRegistry =
System.getenv().getOrDefault("TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX", "");
@@ -55,8 +53,8 @@ private static void configureContainer() {
}
clusterContainer = vshardClusterContainer;
} else {
- TarantoolCartridgeContainer cartridgeContainer =
- new TarantoolCartridgeContainer(
+ CartridgeClusterContainer cartridgeContainer =
+ new CartridgeClusterContainer(
"cartridge/Dockerfile",
dockerRegistry + "cartridge",
"cartridge/instances.yml",
@@ -77,6 +75,8 @@ private static void writeConfigurationFile() throws IOException {
final TarantoolProperties properties = new TarantoolProperties();
properties.setHost(clusterContainer.getHost());
properties.setPort(clusterContainer.getPort());
+ properties.setUserName(clusterContainer.getUsername());
+ properties.setPassword(clusterContainer.getPassword());
writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME, properties);
}
@@ -94,6 +94,14 @@ protected static int getPort() {
return clusterContainer.getPort();
}
+ protected static String getUsername() {
+ return clusterContainer.getUsername();
+ }
+
+ protected static String getPassword() {
+ return clusterContainer.getPassword();
+ }
+
protected static boolean isCartridgeAvailable() {
return System.getenv().getOrDefault("TARANTOOL_VERSION", "").matches("2.*");
}
diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/CrudConfigurations.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/CrudConfigurations.java
index 448bfb5b..5cf5582b 100644
--- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/CrudConfigurations.java
+++ b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/CrudConfigurations.java
@@ -13,7 +13,6 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@@ -21,8 +20,6 @@
import org.springframework.test.context.TestPropertySource;
import static io.tarantool.client.TarantoolClient.DEFAULT_TAG;
-import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_PASSWORD;
-import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_USERNAME;
import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH;
import static io.tarantool.spring.data32.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE;
import static io.tarantool.spring.data32.utils.TarantoolTestSupport.PERSON_SPACE;
@@ -34,7 +31,6 @@
import io.tarantool.spring.data32.integration.BaseIntegrationTest;
import io.tarantool.spring.data32.repository.config.EnableTarantoolRepositories;
-@Disabled("Refactor TarantoolCartridgeContainer and VshardClusterContainer")
@TestPropertySource(properties = {DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH})
abstract class CrudConfigurations extends BaseIntegrationTest {
@@ -51,8 +47,8 @@ protected static void beforeAll() throws IOException {
InstanceConnectionGroup.builder()
.withHost(clusterContainer.getHost())
.withPort(clusterContainer.getPort())
- .withUser(DEFAULT_CRUD_USERNAME)
- .withPassword(DEFAULT_CRUD_PASSWORD)
+ .withUser(getUsername())
+ .withPassword(getPassword())
.withTag(DEFAULT_TAG)
.withSize(4)
.build();
diff --git a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/RepositoryConfigurationExtensionTest.java b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/RepositoryConfigurationExtensionTest.java
index 9cba5360..dfcc0a90 100644
--- a/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/RepositoryConfigurationExtensionTest.java
+++ b/tarantool-spring-data/tarantool-spring-data-32/src/test/java/io/tarantool/spring/data32/integration/crud/RepositoryConfigurationExtensionTest.java
@@ -73,7 +73,11 @@ void testRegisterBeansForRootWithCustomClientConfigShouldThrows() {
}
private static TarantoolCrudClientBuilder getCrudClientSettings() {
- return TarantoolFactory.crud().withHost(getHost()).withPort(getPort());
+ return TarantoolFactory.crud()
+ .withHost(getHost())
+ .withPort(getPort())
+ .withUser(getUsername())
+ .withPassword(getPassword());
}
private static TarantoolBoxClientBuilder getBoxClientSettings() {
diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/BaseIntegrationTest.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/BaseIntegrationTest.java
index 9bfacbc1..3703a3c0 100644
--- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/BaseIntegrationTest.java
+++ b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/BaseIntegrationTest.java
@@ -11,12 +11,11 @@
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Timeout;
import org.slf4j.LoggerFactory;
-import org.testcontainers.containers.TarantoolCartridgeContainer;
-import org.testcontainers.containers.TarantoolContainerOperations;
-import org.testcontainers.containers.VshardClusterContainer;
+import org.testcontainers.containers.cluster.ClusterContainer;
+import org.testcontainers.containers.cluster.cartridge.CartridgeClusterContainer;
+import org.testcontainers.containers.cluster.vshard.VshardClusterContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME;
@@ -24,11 +23,10 @@
import static io.tarantool.spring.data33.utils.TarantoolTestSupport.writeTestPropertiesYaml;
import io.tarantool.spring.data33.config.properties.TarantoolProperties;
-@Disabled("Refactor TarantoolCartridgeContainer and VshardClusterContainer")
@Timeout(60)
public abstract class BaseIntegrationTest {
- protected static TarantoolContainerOperations> clusterContainer;
+ protected static ClusterContainer> clusterContainer;
private static final String dockerRegistry =
System.getenv().getOrDefault("TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX", "");
@@ -55,8 +53,8 @@ private static void configureContainer() {
}
clusterContainer = vshardClusterContainer;
} else {
- TarantoolCartridgeContainer cartridgeContainer =
- new TarantoolCartridgeContainer(
+ CartridgeClusterContainer cartridgeContainer =
+ new CartridgeClusterContainer(
"cartridge/Dockerfile",
dockerRegistry + "cartridge",
"cartridge/instances.yml",
@@ -77,6 +75,8 @@ private static void writeConfigurationFile() throws IOException {
final TarantoolProperties properties = new TarantoolProperties();
properties.setHost(clusterContainer.getHost());
properties.setPort(clusterContainer.getPort());
+ properties.setUserName(clusterContainer.getUsername());
+ properties.setPassword(clusterContainer.getPassword());
writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME, properties);
}
@@ -94,6 +94,14 @@ protected static int getPort() {
return clusterContainer.getPort();
}
+ protected static String getUsername() {
+ return clusterContainer.getUsername();
+ }
+
+ protected static String getPassword() {
+ return clusterContainer.getPassword();
+ }
+
protected static boolean isCartridgeAvailable() {
return System.getenv().getOrDefault("TARANTOOL_VERSION", "").matches("2.*");
}
diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/CrudConfigurations.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/CrudConfigurations.java
index a46ac0d9..f8f991b5 100644
--- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/CrudConfigurations.java
+++ b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/CrudConfigurations.java
@@ -13,7 +13,6 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@@ -21,8 +20,6 @@
import org.springframework.test.context.TestPropertySource;
import static io.tarantool.client.TarantoolClient.DEFAULT_TAG;
-import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_PASSWORD;
-import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_USERNAME;
import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH;
import static io.tarantool.spring.data33.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE;
import static io.tarantool.spring.data33.utils.TarantoolTestSupport.PERSON_SPACE;
@@ -34,7 +31,6 @@
import io.tarantool.spring.data33.integration.BaseIntegrationTest;
import io.tarantool.spring.data33.repository.config.EnableTarantoolRepositories;
-@Disabled("Refactor TarantoolCartridgeContainer and VshardClusterContainer")
@TestPropertySource(properties = {DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH})
abstract class CrudConfigurations extends BaseIntegrationTest {
@@ -51,8 +47,8 @@ protected static void beforeAll() throws IOException {
InstanceConnectionGroup.builder()
.withHost(clusterContainer.getHost())
.withPort(clusterContainer.getPort())
- .withUser(DEFAULT_CRUD_USERNAME)
- .withPassword(DEFAULT_CRUD_PASSWORD)
+ .withUser(getUsername())
+ .withPassword(getPassword())
.withTag(DEFAULT_TAG)
.withSize(4)
.build();
diff --git a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/RepositoryConfigurationExtensionTest.java b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/RepositoryConfigurationExtensionTest.java
index c5a6f28c..401cffa6 100644
--- a/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/RepositoryConfigurationExtensionTest.java
+++ b/tarantool-spring-data/tarantool-spring-data-33/src/test/java/io/tarantool/spring/data33/integration/crud/RepositoryConfigurationExtensionTest.java
@@ -73,7 +73,11 @@ void testRegisterBeansForRootWithCustomClientConfigShouldThrows() {
}
private static TarantoolCrudClientBuilder getCrudClientSettings() {
- return TarantoolFactory.crud().withHost(getHost()).withPort(getPort());
+ return TarantoolFactory.crud()
+ .withHost(getHost())
+ .withPort(getPort())
+ .withUser(getUsername())
+ .withPassword(getPassword());
}
private static TarantoolBoxClientBuilder getBoxClientSettings() {
diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/BaseIntegrationTest.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/BaseIntegrationTest.java
index 2c9d5c66..16e92b94 100644
--- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/BaseIntegrationTest.java
+++ b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/BaseIntegrationTest.java
@@ -11,12 +11,11 @@
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Timeout;
import org.slf4j.LoggerFactory;
-import org.testcontainers.containers.TarantoolCartridgeContainer;
-import org.testcontainers.containers.TarantoolContainerOperations;
-import org.testcontainers.containers.VshardClusterContainer;
+import org.testcontainers.containers.cluster.ClusterContainer;
+import org.testcontainers.containers.cluster.cartridge.CartridgeClusterContainer;
+import org.testcontainers.containers.cluster.vshard.VshardClusterContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME;
@@ -24,11 +23,10 @@
import static io.tarantool.spring.data34.utils.TarantoolTestSupport.writeTestPropertiesYaml;
import io.tarantool.spring.data34.config.properties.TarantoolProperties;
-@Disabled("Refactor TarantoolCartridgeContainer and VshardClusterContainer")
@Timeout(60)
public abstract class BaseIntegrationTest {
- protected static TarantoolContainerOperations> clusterContainer;
+ protected static ClusterContainer> clusterContainer;
private static final String dockerRegistry =
System.getenv().getOrDefault("TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX", "");
@@ -55,8 +53,8 @@ private static void configureContainer() {
}
clusterContainer = vshardClusterContainer;
} else {
- TarantoolCartridgeContainer cartridgeContainer =
- new TarantoolCartridgeContainer(
+ CartridgeClusterContainer cartridgeContainer =
+ new CartridgeClusterContainer(
"cartridge/Dockerfile",
dockerRegistry + "cartridge",
"cartridge/instances.yml",
@@ -77,6 +75,8 @@ private static void writeConfigurationFile() throws IOException {
final TarantoolProperties properties = new TarantoolProperties();
properties.setHost(clusterContainer.getHost());
properties.setPort(clusterContainer.getPort());
+ properties.setUserName(clusterContainer.getUsername());
+ properties.setPassword(clusterContainer.getPassword());
writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME, properties);
}
@@ -94,6 +94,14 @@ protected static int getPort() {
return clusterContainer.getPort();
}
+ protected static String getUsername() {
+ return clusterContainer.getUsername();
+ }
+
+ protected static String getPassword() {
+ return clusterContainer.getPassword();
+ }
+
protected static boolean isCartridgeAvailable() {
return System.getenv().getOrDefault("TARANTOOL_VERSION", "").matches("2.*");
}
diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/CrudConfigurations.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/CrudConfigurations.java
index 504d9867..ee629efd 100644
--- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/CrudConfigurations.java
+++ b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/CrudConfigurations.java
@@ -13,7 +13,6 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@@ -21,8 +20,6 @@
import org.springframework.test.context.TestPropertySource;
import static io.tarantool.client.TarantoolClient.DEFAULT_TAG;
-import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_PASSWORD;
-import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_USERNAME;
import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH;
import static io.tarantool.spring.data34.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE;
import static io.tarantool.spring.data34.utils.TarantoolTestSupport.PERSON_SPACE;
@@ -34,7 +31,6 @@
import io.tarantool.spring.data34.integration.BaseIntegrationTest;
import io.tarantool.spring.data34.repository.config.EnableTarantoolRepositories;
-@Disabled("Refactor TarantoolCartridgeContainer and VshardClusterContainer")
@TestPropertySource(properties = {DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH})
abstract class CrudConfigurations extends BaseIntegrationTest {
@@ -51,8 +47,8 @@ protected static void beforeAll() throws IOException {
InstanceConnectionGroup.builder()
.withHost(clusterContainer.getHost())
.withPort(clusterContainer.getPort())
- .withUser(DEFAULT_CRUD_USERNAME)
- .withPassword(DEFAULT_CRUD_PASSWORD)
+ .withUser(getUsername())
+ .withPassword(getPassword())
.withTag(DEFAULT_TAG)
.withSize(4)
.build();
diff --git a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/RepositoryConfigurationExtensionTest.java b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/RepositoryConfigurationExtensionTest.java
index 592dcd77..8007273f 100644
--- a/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/RepositoryConfigurationExtensionTest.java
+++ b/tarantool-spring-data/tarantool-spring-data-34/src/test/java/io/tarantool/spring/data34/integration/crud/RepositoryConfigurationExtensionTest.java
@@ -73,7 +73,11 @@ void testRegisterBeansForRootWithCustomClientConfigShouldThrows() {
}
private static TarantoolCrudClientBuilder getCrudClientSettings() {
- return TarantoolFactory.crud().withHost(getHost()).withPort(getPort());
+ return TarantoolFactory.crud()
+ .withHost(getHost())
+ .withPort(getPort())
+ .withUser(getUsername())
+ .withPassword(getPassword());
}
private static TarantoolBoxClientBuilder getBoxClientSettings() {
diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/BaseIntegrationTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/BaseIntegrationTest.java
index 2fd20f50..3dc2a4ae 100644
--- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/BaseIntegrationTest.java
+++ b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/BaseIntegrationTest.java
@@ -11,12 +11,11 @@
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Timeout;
import org.slf4j.LoggerFactory;
-import org.testcontainers.containers.TarantoolCartridgeContainer;
-import org.testcontainers.containers.TarantoolContainerOperations;
-import org.testcontainers.containers.VshardClusterContainer;
+import org.testcontainers.containers.cluster.ClusterContainer;
+import org.testcontainers.containers.cluster.cartridge.CartridgeClusterContainer;
+import org.testcontainers.containers.cluster.vshard.VshardClusterContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_NAME;
@@ -24,11 +23,10 @@
import static io.tarantool.spring.data35.utils.TarantoolTestSupport.writeTestPropertiesYaml;
import io.tarantool.spring.data35.config.properties.TarantoolProperties;
-@Disabled("Refactor TarantoolCartridgeContainer and VshardClusterContainer")
@Timeout(60)
public abstract class BaseIntegrationTest {
- protected static TarantoolContainerOperations> clusterContainer;
+ protected static ClusterContainer> clusterContainer;
private static final String dockerRegistry =
System.getenv().getOrDefault("TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX", "");
@@ -55,8 +53,8 @@ private static void configureContainer() {
}
clusterContainer = vshardClusterContainer;
} else {
- TarantoolCartridgeContainer cartridgeContainer =
- new TarantoolCartridgeContainer(
+ CartridgeClusterContainer cartridgeContainer =
+ new CartridgeClusterContainer(
"cartridge/Dockerfile",
dockerRegistry + "cartridge",
"cartridge/instances.yml",
@@ -77,6 +75,8 @@ private static void writeConfigurationFile() throws IOException {
final TarantoolProperties properties = new TarantoolProperties();
properties.setHost(clusterContainer.getHost());
properties.setPort(clusterContainer.getPort());
+ properties.setUserName(clusterContainer.getUsername());
+ properties.setPassword(clusterContainer.getPassword());
writeTestPropertiesYaml(DEFAULT_PROPERTY_FILE_NAME, properties);
}
@@ -94,6 +94,14 @@ protected static int getPort() {
return clusterContainer.getPort();
}
+ protected static String getUsername() {
+ return clusterContainer.getUsername();
+ }
+
+ protected static String getPassword() {
+ return clusterContainer.getPassword();
+ }
+
protected static boolean isCartridgeAvailable() {
return System.getenv().getOrDefault("TARANTOOL_VERSION", "").matches("2.*");
}
diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/CrudConfigurations.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/CrudConfigurations.java
index 1ccf47b5..b73e6be3 100644
--- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/CrudConfigurations.java
+++ b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/CrudConfigurations.java
@@ -13,7 +13,6 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@@ -21,8 +20,6 @@
import org.springframework.test.context.TestPropertySource;
import static io.tarantool.client.TarantoolClient.DEFAULT_TAG;
-import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_PASSWORD;
-import static io.tarantool.client.crud.TarantoolCrudClient.DEFAULT_CRUD_USERNAME;
import static io.tarantool.spring.data.utils.Constants.DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH;
import static io.tarantool.spring.data35.utils.TarantoolTestSupport.COMPLEX_PERSON_SPACE;
import static io.tarantool.spring.data35.utils.TarantoolTestSupport.PERSON_SPACE;
@@ -34,7 +31,6 @@
import io.tarantool.spring.data35.integration.BaseIntegrationTest;
import io.tarantool.spring.data35.repository.config.EnableTarantoolRepositories;
-@Disabled("Refactor TarantoolCartridgeContainer and VshardClusterContainer")
@TestPropertySource(properties = {DEFAULT_PROPERTY_FILE_LOCATION_CLASSPATH})
abstract class CrudConfigurations extends BaseIntegrationTest {
@@ -51,8 +47,8 @@ protected static void beforeAll() throws IOException {
InstanceConnectionGroup.builder()
.withHost(clusterContainer.getHost())
.withPort(clusterContainer.getPort())
- .withUser(DEFAULT_CRUD_USERNAME)
- .withPassword(DEFAULT_CRUD_PASSWORD)
+ .withUser(getUsername())
+ .withPassword(getPassword())
.withTag(DEFAULT_TAG)
.withSize(4)
.build();
diff --git a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/RepositoryConfigurationExtensionTest.java b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/RepositoryConfigurationExtensionTest.java
index be7b856f..644c226c 100644
--- a/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/RepositoryConfigurationExtensionTest.java
+++ b/tarantool-spring-data/tarantool-spring-data-35/src/test/java/io/tarantool/spring/data35/integration/crud/RepositoryConfigurationExtensionTest.java
@@ -73,7 +73,11 @@ void testRegisterBeansForRootWithCustomClientConfigShouldThrows() {
}
private static TarantoolCrudClientBuilder getCrudClientSettings() {
- return TarantoolFactory.crud().withHost(getHost()).withPort(getPort());
+ return TarantoolFactory.crud()
+ .withHost(getHost())
+ .withPort(getPort())
+ .withUser(getUsername())
+ .withPassword(getPassword());
}
private static TarantoolBoxClientBuilder getBoxClientSettings() {
diff --git a/testcontainers/src/main/java/org/testcontainers/containers/TarantoolConfigParser.java b/testcontainers/src/main/java/org/testcontainers/containers/TarantoolConfigParser.java
index 5f3525b5..66b7d500 100644
--- a/testcontainers/src/main/java/org/testcontainers/containers/TarantoolConfigParser.java
+++ b/testcontainers/src/main/java/org/testcontainers/containers/TarantoolConfigParser.java
@@ -5,40 +5,148 @@
package org.testcontainers.containers;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.io.InputStream;
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.List;
import java.util.Map;
-import java.util.stream.Collectors;
+import java.util.Objects;
+import java.util.Optional;
-import org.yaml.snakeyaml.LoaderOptions;
+import org.testcontainers.containers.tarantool.config.ConfigurationUtils;
import org.yaml.snakeyaml.Yaml;
-import org.yaml.snakeyaml.constructor.Constructor;
-class TarantoolConfigParser {
+import io.tarantool.autogen.Tarantool3Configuration;
+import io.tarantool.autogen.groups.groupsProperty.GroupsProperty;
+import io.tarantool.autogen.groups.groupsProperty.replicasets.replicasetsProperty.ReplicasetsProperty;
+import io.tarantool.autogen.groups.groupsProperty.replicasets.replicasetsProperty.instances.instancesProperty.InstancesProperty;
+import io.tarantool.autogen.groups.groupsProperty.replicasets.replicasetsProperty.instances.instancesProperty.iproto.Iproto;
+import io.tarantool.autogen.groups.groupsProperty.replicasets.replicasetsProperty.instances.instancesProperty.iproto.listen.Listen;
- private final Config config;
+public class TarantoolConfigParser {
+
+ private static final String ROUTERS_GROUP_NAME = "routers";
+
+ private final Tarantool3Configuration config;
+ private final Config fallbackConfig;
public TarantoolConfigParser(String instanceFileName) {
- Yaml yaml = new Yaml(new Constructor(Config.class, new LoaderOptions()));
- InputStream inputStream =
- this.getClass().getClassLoader().getResourceAsStream(instanceFileName);
- config = yaml.load(inputStream);
+ InputStream inputStream = getClass().getClassLoader().getResourceAsStream(instanceFileName);
+ if (inputStream == null) {
+ throw new IllegalArgumentException(
+ String.format("No resource path found for the specified resource %s", instanceFileName));
+ }
+ Tarantool3Configuration parsedConfig = null;
+ Config parsedFallbackConfig = null;
+ try (InputStream is = inputStream) {
+ String rawConfig = readAsString(is);
+ try {
+ parsedConfig = ConfigurationUtils.create(rawConfig);
+ } catch (LinkageError e) {
+ parsedFallbackConfig = new Yaml().loadAs(rawConfig, Config.class);
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ this.config = parsedConfig;
+ this.fallbackConfig = parsedFallbackConfig;
}
public Integer[] getExposablePorts() {
+ if (config != null) {
+ return getExposablePortsFromTypedConfig();
+ }
+ return getExposablePortsFromFallbackConfig();
+ }
+
+ private Integer[] getExposablePortsFromTypedConfig() {
+ if (config.getGroups().isEmpty()) {
+ return new Integer[] {};
+ }
+ GroupsProperty routersGroup =
+ config.getGroups().get().getAdditionalProperties().get(ROUTERS_GROUP_NAME);
+ if (routersGroup == null || !routersGroup.getReplicasets().isPresent()) {
+ return new Integer[] {};
+ }
List ports =
- config.getGroups().get("routers").getReplicasets().values().stream()
- .map(replicaset -> replicaset.getInstances().values())
+ routersGroup.getReplicasets().get().getAdditionalProperties().values().stream()
+ .map(ReplicasetsProperty::getInstances)
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .map(instances -> instances.getAdditionalProperties().values())
.flatMap(Collection::stream)
- .map(instance -> instance.getIproto().values())
+ .map(InstancesProperty::getIproto)
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .map(Iproto::getListen)
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .flatMap(List::stream)
+ .map(Listen::getUri)
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .map(TarantoolConfigParser::parsePort)
+ .toList();
+
+ return ports.toArray(new Integer[] {});
+ }
+
+ private Integer[] getExposablePortsFromFallbackConfig() {
+ if (fallbackConfig == null
+ || fallbackConfig.getGroups() == null
+ || !fallbackConfig.getGroups().containsKey(ROUTERS_GROUP_NAME)) {
+ return new Integer[] {};
+ }
+ Group routersGroup = fallbackConfig.getGroups().get(ROUTERS_GROUP_NAME);
+ if (routersGroup == null || routersGroup.getReplicasets() == null) {
+ return new Integer[] {};
+ }
+ List ports =
+ routersGroup.getReplicasets().values().stream()
+ .map(Replicaset::getInstances)
+ .filter(Objects::nonNull)
+ .map(Map::values)
+ .flatMap(Collection::stream)
+ .map(Instance::getIproto)
+ .filter(Objects::nonNull)
+ .map(Map::values)
.flatMap(Collection::stream)
.flatMap(Collection::stream)
.map(Map::values)
.flatMap(Collection::stream)
- .map(Integer::parseInt)
- .collect(Collectors.toList());
-
+ .map(TarantoolConfigParser::parsePort)
+ .toList();
return ports.toArray(new Integer[] {});
}
+
+ private static Integer parsePort(String uri) {
+ if (uri == null || uri.isBlank()) {
+ throw new IllegalArgumentException("Listen URI must not be null or empty");
+ }
+ String normalized = uri.trim();
+ String uriWithScheme = normalized.contains("://") ? normalized : "tcp://" + normalized;
+ try {
+ URI parsed = URI.create(uriWithScheme);
+ int port = parsed.getPort();
+ if (port < 0) {
+ throw new IllegalArgumentException("Listen URI must contain a valid port: " + uri);
+ }
+ return port;
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("Failed to parse listen URI: " + uri, e);
+ }
+ }
+
+ private static String readAsString(InputStream inputStream) throws IOException {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ byte[] buffer = new byte[8192];
+ int bytesRead;
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
+ outputStream.write(buffer, 0, bytesRead);
+ }
+ return outputStream.toString(StandardCharsets.UTF_8);
+ }
}
diff --git a/testcontainers/src/main/java/org/testcontainers/containers/TarantoolContainerOperations.java b/testcontainers/src/main/java/org/testcontainers/containers/TarantoolContainerOperations.java
deleted file mode 100644
index 1ae91f32..00000000
--- a/testcontainers/src/main/java/org/testcontainers/containers/TarantoolContainerOperations.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2025 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY
- * All Rights Reserved.
- */
-
-package org.testcontainers.containers;
-
-@Deprecated
-public interface TarantoolContainerOperations> extends Container {
- /**
- * Get the Tarantool server exposed port for connecting the client to
- *
- * @return a port
- */
- int getPort();
-
- /**
- * Get the Tarantool user name for connecting the client with
- *
- * @return a user name
- */
- String getUsername();
-
- /**
- * Get the Tarantool user password for connecting the client with
- *
- * @return a user password
- */
- String getPassword();
-
- /**
- * Get the app scripts directory
- *
- * @return the app directory
- */
- String getDirectoryBinding();
-
- /**
- * Get the app scripts directory in the container
- *
- * @return the app scripts directory
- */
- String getInstanceDir();
-
- /**
- * Get the Tarantool server internal port for client connections
- *
- * @return a port
- */
- int getInternalPort();
-
- /**
- * Execute a local script in the Tarantool instance. The path must be classpath-relative.
- * `dofile()` function is executed internally, so possible exceptions will be caught as the client
- * exceptions.
- *
- * @param scriptResourcePath the classpath resource path to a script
- * @return script execution result
- * @throws Exception if failed to connect to the instance or execution fails
- */
- Container.ExecResult executeScript(String scriptResourcePath) throws Exception;
-
- /**
- * Execute a local script in the Tarantool instance. The path must be classpath-relative.
- * `dofile()` function is executed internally, so possible exceptions will be caught as the client
- * exceptions.
- *
- * @param the result of script
- * @param scriptResourcePath the classpath resource path to a script
- * @return script execution result in {@link Container.ExecResult}
- * @throws Exception if failed to connect to the instance or execution fails
- */
- V executeScriptDecoded(String scriptResourcePath) throws Exception;
-
- /**
- * Execute a command in the Tarantool instance. Example of a command: `return 1 + 2, 'foo'`
- *
- * @param command a valid Lua command or a sequence of Lua commands
- * @return command execution result
- * @throws Exception if failed to connect to the instance or execution fails
- */
- Container.ExecResult executeCommand(String command) throws Exception;
-
- /**
- * Execute a command in the Tarantool instance. Example of a command: `return 1 + 2, 'foo'`
- *
- * @param the result of script
- * @param command a valid Lua command or a sequence of Lua commands
- * @return command execution result in {@link Container.ExecResult}
- * @throws Exception if failed to connect to the instance or execution fails
- */
- V executeCommandDecoded(String command) throws Exception;
-}
diff --git a/testcontainers/src/main/java/org/testcontainers/containers/cluster/ClusterConfigurator.java b/testcontainers/src/main/java/org/testcontainers/containers/cluster/ClusterConfigurator.java
new file mode 100644
index 00000000..50bc6631
--- /dev/null
+++ b/testcontainers/src/main/java/org/testcontainers/containers/cluster/ClusterConfigurator.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2025 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY
+ * All Rights Reserved.
+ */
+
+package org.testcontainers.containers.cluster;
+
+import java.util.Map;
+
+/**
+ * Common configurator contract for single-router test clusters.
+ *
+ * @param cluster container type
+ */
+public interface ClusterConfigurator> extends AutoCloseable {
+
+ /** Returns cluster name. */
+ String clusterName();
+
+ /** Returns all cluster nodes participating in configuration. */
+ Map nodes();
+
+ /** Applies cluster-specific configuration after container startup. */
+ void configure();
+
+ /** Returns true if configuration was already applied for current lifecycle. */
+ boolean configured();
+
+ @Override
+ default void close() {}
+}
diff --git a/testcontainers/src/main/java/org/testcontainers/containers/cluster/ClusterContainer.java b/testcontainers/src/main/java/org/testcontainers/containers/cluster/ClusterContainer.java
new file mode 100644
index 00000000..4fe1202b
--- /dev/null
+++ b/testcontainers/src/main/java/org/testcontainers/containers/cluster/ClusterContainer.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2025 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY
+ * All Rights Reserved.
+ */
+
+package org.testcontainers.containers.cluster;
+
+import java.util.Map;
+
+import org.testcontainers.containers.Container;
+
+/**
+ * Common interface for Tarantool cluster containers (vshard-based and cartridge-based). Provides
+ * access to the router endpoint and command execution.
+ */
+public interface ClusterContainer> extends Container {
+
+ /** Returns cluster configurator used for post-startup cluster setup. */
+ ClusterConfigurator extends ClusterContainer>> getConfigurator();
+
+ /** Returns configured cluster name. */
+ default String clusterName() {
+ return getConfigurator().clusterName();
+ }
+
+ /** Returns all nodes handled by the configurator. */
+ default Map> nodes() {
+ return getConfigurator().nodes();
+ }
+
+ /** Returns true if cluster topology was configured. */
+ default boolean configured() {
+ return getConfigurator().configured();
+ }
+
+ /**
+ * Get the router host.
+ *
+ * @return router hostname
+ */
+ String getHost();
+
+ /**
+ * Get the mapped router port (default router port 3301).
+ *
+ * @return mapped router port
+ */
+ int getPort();
+
+ /**
+ * Get the router username used for authentication.
+ *
+ * @return router username
+ */
+ String getUsername();
+
+ /**
+ * Get the router password used for authentication.
+ *
+ * @return router password
+ */
+ String getPassword();
+
+ /**
+ * Get the host directory bound into the container instance directory.
+ *
+ * @return normalized host directory path or empty string when binding is disabled
+ */
+ String getDirectoryBinding();
+
+ /**
+ * Get the container directory where cluster files are mounted.
+ *
+ * @return container instance directory
+ */
+ String getInstanceDir();
+
+ /**
+ * Get the internal router port exposed by the container.
+ *
+ * @return internal router port
+ */
+ int getInternalPort();
+
+ /**
+ * Execute a Lua script from classpath and decode the result.
+ *
+ * @param scriptResourcePath classpath path to the script
+ * @param decoded result type
+ * @return decoded script execution result
+ */
+ V executeScriptDecoded(String scriptResourcePath);
+
+ /**
+ * Execute a Lua script from classpath.
+ *
+ * @param scriptResourcePath classpath path to the script
+ * @return script execution result
+ */
+ Container.ExecResult executeScript(String scriptResourcePath);
+
+ /**
+ * Execute a Lua command and decode the result.
+ *
+ * @param command a valid Lua command or sequence of Lua commands
+ * @param decoded result type
+ * @return decoded command execution result
+ */
+ V executeCommandDecoded(String command);
+
+ /**
+ * Execute a Lua command inside the cluster router.
+ *
+ * @param command a valid Lua command or sequence of Lua commands
+ * @return command execution result
+ */
+ Container.ExecResult executeCommand(String command);
+}
diff --git a/testcontainers/src/main/java/org/testcontainers/containers/cluster/cartridge/CartridgeClusterConfigurator.java b/testcontainers/src/main/java/org/testcontainers/containers/cluster/cartridge/CartridgeClusterConfigurator.java
new file mode 100644
index 00000000..0b9be083
--- /dev/null
+++ b/testcontainers/src/main/java/org/testcontainers/containers/cluster/cartridge/CartridgeClusterConfigurator.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2025 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY
+ * All Rights Reserved.
+ */
+
+package org.testcontainers.containers.cluster.cartridge;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.testcontainers.containers.cluster.ClusterConfigurator;
+
+/** Configures a cartridge-based cluster after container startup. */
+public class CartridgeClusterConfigurator
+ implements ClusterConfigurator {
+
+ public static final String DEFAULT_CLUSTER_NAME = "cartridge-cluster";
+ private static final String ROUTER_NODE_NAME = "router";
+
+ private final CartridgeClusterContainer container;
+ private final String clusterName;
+ private final AtomicBoolean configured;
+
+ public CartridgeClusterConfigurator(CartridgeClusterContainer container) {
+ this(container, DEFAULT_CLUSTER_NAME);
+ }
+
+ public CartridgeClusterConfigurator(CartridgeClusterContainer container, String clusterName) {
+ this.container = container;
+ this.clusterName = clusterName;
+ this.configured = new AtomicBoolean(false);
+ }
+
+ @Override
+ public String clusterName() {
+ return this.clusterName;
+ }
+
+ @Override
+ public Map nodes() {
+ return Collections.singletonMap(ROUTER_NODE_NAME, this.container);
+ }
+
+ @Override
+ public void configure() {
+ this.container.waitUntilRouterIsUp(
+ CartridgeClusterContainer.TIMEOUT_ROUTER_UP_CARTRIDGE_HEALTH_IN_SECONDS);
+ this.container.retryingSetupTopology();
+ this.container.waitUntilCartridgeIsHealthy(
+ CartridgeClusterContainer.TIMEOUT_ROUTER_UP_CARTRIDGE_HEALTH_IN_SECONDS);
+ this.container.bootstrapVshard();
+ this.configured.set(true);
+ }
+
+ @Override
+ public boolean configured() {
+ return this.configured.get();
+ }
+}
diff --git a/testcontainers/src/main/java/org/testcontainers/containers/TarantoolCartridgeContainer.java b/testcontainers/src/main/java/org/testcontainers/containers/cluster/cartridge/CartridgeClusterContainer.java
similarity index 66%
rename from testcontainers/src/main/java/org/testcontainers/containers/TarantoolCartridgeContainer.java
rename to testcontainers/src/main/java/org/testcontainers/containers/cluster/cartridge/CartridgeClusterContainer.java
index 85e06816..e2059ccf 100644
--- a/testcontainers/src/main/java/org/testcontainers/containers/TarantoolCartridgeContainer.java
+++ b/testcontainers/src/main/java/org/testcontainers/containers/cluster/cartridge/CartridgeClusterContainer.java
@@ -3,7 +3,7 @@
* All Rights Reserved.
*/
-package org.testcontainers.containers;
+package org.testcontainers.containers.cluster.cartridge;
import java.net.URL;
import java.util.Arrays;
@@ -18,14 +18,17 @@
import static org.testcontainers.containers.utils.PathUtils.normalizePath;
import com.github.dockerjava.api.command.InspectContainerResponse;
import org.apache.commons.lang3.ArrayUtils;
+import org.testcontainers.containers.BindMode;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.cluster.ClusterConfigurator;
+import org.testcontainers.containers.cluster.ClusterContainer;
import org.testcontainers.containers.utils.CartridgeConfigParser;
import org.testcontainers.containers.utils.SslContext;
import org.testcontainers.containers.utils.TarantoolContainerClientHelper;
import org.testcontainers.images.builder.ImageFromDockerfile;
-@Deprecated
-public class TarantoolCartridgeContainer extends GenericContainer
- implements TarantoolContainerOperations {
+public class CartridgeClusterContainer extends GenericContainer
+ implements ClusterContainer {
protected static final String ROUTER_HOST = "localhost";
protected static final int ROUTER_PORT = 3301;
@@ -54,6 +57,7 @@ public class TarantoolCartridgeContainer extends GenericContainer configurator;
protected boolean useFixedPorts = false;
protected String routerHost = ROUTER_HOST;
@@ -67,60 +71,21 @@ public class TarantoolCartridgeContainer extends GenericContainer buildArgs) {
this(DOCKERFILE, "", instancesFile, topologyConfigurationFile, buildArgs);
}
- /**
- * Create a container with default image and specified instances file from the classpath resources
- *
- * @param dockerFile path to a Dockerfile which configures Cartridge and other necessary services
- * @param instancesFile path to instances.yml, relative to the classpath resources
- * @param topologyConfigurationFile path to a topology bootstrap script, relative to the classpath
- * resources
- */
- public TarantoolCartridgeContainer(
+ public CartridgeClusterContainer(
String dockerFile, String instancesFile, String topologyConfigurationFile) {
this(dockerFile, "", instancesFile, topologyConfigurationFile);
}
- /**
- * Create a container with specified image and specified instances file from the classpath
- * resources. By providing the result Cartridge container image name, you can cache the image and
- * avoid rebuilding on each test run (the image is tagged with the provided name and not deleted
- * after tests finishing).
- *
- * @param dockerFile URL resource path to a Dockerfile which configures Cartridge and other
- * necessary services
- * @param buildImageName Specify a stable image name for the test container to prevent rebuilds
- * @param instancesFile URL resource path to instances.yml relative in the classpath
- * @param topologyConfigurationFile URL resource path to a topology bootstrap script in the
- * classpath
- */
- public TarantoolCartridgeContainer(
+ public CartridgeClusterContainer(
String dockerFile,
String buildImageName,
String instancesFile,
@@ -133,22 +98,7 @@ public TarantoolCartridgeContainer(
Collections.emptyMap());
}
- /**
- * Create a container with specified image and specified instances file from the classpath
- * resources. By providing the result Cartridge container image name, you can cache the image and
- * avoid rebuilding on each test run (the image is tagged with the provided name and not deleted
- * after tests finishing).
- *
- * @param dockerFile URL resource path to a Dockerfile which configures Cartridge and other
- * necessary services
- * @param buildImageName Specify a stable image name for the test container to prevent rebuilds
- * @param instancesFile URL resource path to instances.yml relative in the classpath
- * @param topologyConfigurationFile URL resource path to a topology bootstrap script in the
- * classpath
- * @param buildArgs a map of arguments that will be passed to docker ARG commands on image build.
- * This values can be overridden by environment.
- */
- public TarantoolCartridgeContainer(
+ public CartridgeClusterContainer(
String dockerFile,
String buildImageName,
String instancesFile,
@@ -161,7 +111,7 @@ public TarantoolCartridgeContainer(
buildArgs);
}
- protected TarantoolCartridgeContainer(
+ protected CartridgeClusterContainer(
ImageFromDockerfile image,
String instancesFile,
String topologyConfigurationFile,
@@ -180,6 +130,7 @@ protected TarantoolCartridgeContainer(
this.instancesFile = instancesFile;
this.topologyConfigurationFile = topologyConfigurationFile;
this.instanceFileParser = new CartridgeConfigParser(instancesFile);
+ this.configurator = new CartridgeClusterConfigurator(this);
}
protected static ImageFromDockerfile withBuildArgs(
@@ -193,12 +144,12 @@ protected static ImageFromDockerfile withBuildArgs(
return image;
}
- public TarantoolCartridgeContainer withFixedExposedPort(int hostPort, int containerPort) {
+ public CartridgeClusterContainer withFixedExposedPort(int hostPort, int containerPort) {
super.addFixedExposedPort(hostPort, containerPort);
return this;
}
- public TarantoolCartridgeContainer withExposedPort(Integer port) {
+ public CartridgeClusterContainer withExposedPort(Integer port) {
super.addExposedPort(port);
return this;
}
@@ -244,20 +195,10 @@ protected static ImageFromDockerfile buildImage(
: buildArgs.get("CARTRIDGE_SRC_DIR"));
}
- /**
- * Get the router host
- *
- * @return router hostname
- */
public String getRouterHost() {
return routerHost;
}
- /**
- * Get the router port
- *
- * @return router mapped port
- */
public int getRouterPort() {
if (useFixedPorts) {
return routerPort;
@@ -265,20 +206,10 @@ public int getRouterPort() {
return getMappedPort(routerPort);
}
- /**
- * Get the user name for connecting to the router
- *
- * @return a user name
- */
public String getRouterUsername() {
return routerUsername;
}
- /**
- * Get the user password for connecting to the router
- *
- * @return a user password
- */
public String getRouterPassword() {
return routerPassword;
}
@@ -308,14 +239,7 @@ public String getDirectoryBinding() {
return directoryResourcePath;
}
- /**
- * Specify the directory inside container that the resource directory will be mounted to. The
- * default value is "/app".
- *
- * @param instanceDir valid directory path
- * @return this container instance
- */
- public TarantoolCartridgeContainer withInstanceDir(String instanceDir) {
+ public CartridgeClusterContainer withInstanceDir(String instanceDir) {
checkNotRunning();
this.instanceDir = instanceDir;
return this;
@@ -331,16 +255,25 @@ public int getInternalPort() {
return routerPort;
}
- /**
- * Get Cartridge router HTTP API hostname
- *
- * @return HTTP API hostname
- */
+ @Override
+ public ClusterConfigurator getConfigurator() {
+ return this.configurator;
+ }
+
+ public CartridgeClusterContainer withClusterConfigurator(
+ ClusterConfigurator configurator) {
+ checkNotRunning();
+ if (configurator == null) {
+ throw new IllegalArgumentException("Cluster configurator must not be null");
+ }
+ this.configurator = configurator;
+ return this;
+ }
+
public String getAPIHost() {
return routerHost;
}
- /** Checks if already running and if so raises an exception to prevent too-late setters. */
protected void checkNotRunning() {
if (isRunning()) {
throw new IllegalStateException(
@@ -348,14 +281,7 @@ protected void checkNotRunning() {
}
}
- /**
- * Specify the root directory of a Cartridge project relative to the resource classpath. The
- * default directory is the root resource directory.
- *
- * @param directoryResourcePath a valid directory path
- * @return this container instance
- */
- public TarantoolCartridgeContainer withDirectoryBinding(String directoryResourcePath) {
+ public CartridgeClusterContainer withDirectoryBinding(String directoryResourcePath) {
checkNotRunning();
URL resource = getClass().getClassLoader().getResource(directoryResourcePath);
if (resource == null) {
@@ -367,11 +293,6 @@ public TarantoolCartridgeContainer withDirectoryBinding(String directoryResource
return this;
}
- /**
- * Get Cartridge router HTTP API port
- *
- * @return HTTP API port
- */
public int getAPIPort() {
if (useFixedPorts) {
return apiPort;
@@ -379,73 +300,36 @@ public int getAPIPort() {
return getMappedPort(apiPort);
}
- /**
- * Use fixed ports binding. Defaults to false.
- *
- * @param useFixedPorts fixed ports for tarantool
- * @return HTTP API port
- */
- public TarantoolCartridgeContainer withUseFixedPorts(boolean useFixedPorts) {
+ public CartridgeClusterContainer withUseFixedPorts(boolean useFixedPorts) {
this.useFixedPorts = useFixedPorts;
return this;
}
- /**
- * Set Cartridge router hostname
- *
- * @param routerHost a hostname, default is "localhost"
- * @return this container instance
- */
- public TarantoolCartridgeContainer withRouterHost(String routerHost) {
+ public CartridgeClusterContainer withRouterHost(String routerHost) {
checkNotRunning();
this.routerHost = routerHost;
return this;
}
- /**
- * Set Cartridge router binary port
- *
- * @param routerPort router Tarantool node port, usually 3301
- * @return this container instance
- */
- public TarantoolCartridgeContainer withRouterPort(int routerPort) {
+ public CartridgeClusterContainer withRouterPort(int routerPort) {
checkNotRunning();
this.routerPort = routerPort;
return this;
}
- /**
- * Set Cartridge router HTTP API port
- *
- * @param apiPort HTTP API port, usually 8081
- * @return this container instance
- */
- public TarantoolCartridgeContainer withAPIPort(int apiPort) {
+ public CartridgeClusterContainer withAPIPort(int apiPort) {
checkNotRunning();
this.apiPort = apiPort;
return this;
}
- /**
- * Set the username for accessing the router node
- *
- * @param routerUsername a user name, default is "admin"
- * @return this container instance
- */
- public TarantoolCartridgeContainer withRouterUsername(String routerUsername) {
+ public CartridgeClusterContainer withRouterUsername(String routerUsername) {
checkNotRunning();
this.routerUsername = routerUsername;
return this;
}
- /**
- * Set the user password for accessing the router node
- *
- * @param routerPassword a user password, usually is a value of the "cluster_cookie" option in
- * cartridge.cfg({...})
- * @return this container instance
- */
- public TarantoolCartridgeContainer withRouterPassword(String routerPassword) {
+ public CartridgeClusterContainer withRouterPassword(String routerPassword) {
checkNotRunning();
this.routerPassword = routerPassword;
return this;
@@ -453,7 +337,7 @@ public TarantoolCartridgeContainer withRouterPassword(String routerPassword) {
@Override
protected void configure() {
- if (!getDirectoryBinding().isEmpty()) {
+ if (!getDirectoryBinding().isBlank()) {
withFileSystemBind(getDirectoryBinding(), getInstanceDir(), BindMode.READ_WRITE);
}
if (useFixedPorts) {
@@ -500,15 +384,12 @@ protected boolean setupTopology() {
List> res = executeScriptDecoded(topologyConfigurationFile);
if (res.size() >= 2 && res.get(1) != null && res.get(1) instanceof Map) {
HashMap, ?> error = ((HashMap, ?>) res.get(1));
- // that means topology already exists
return error.get("str").toString().contains("collision with another server");
}
- // The client connection will be closed after that command
} catch (Exception e) {
if (e instanceof ExecutionException) {
if (e.getCause() instanceof TimeoutException) {
return true;
- // Do nothing, the cluster is reloading
}
} else {
throw new RuntimeException(e);
@@ -545,11 +426,7 @@ protected void bootstrapVshard() {
protected void containerIsStarted(InspectContainerResponse containerInfo, boolean reused) {
super.containerIsStarted(containerInfo, reused);
- waitUntilRouterIsUp(TIMEOUT_ROUTER_UP_CARTRIDGE_HEALTH_IN_SECONDS);
- retryingSetupTopology();
- // wait until Roles are configured
- waitUntilCartridgeIsHealthy(TIMEOUT_ROUTER_UP_CARTRIDGE_HEALTH_IN_SECONDS);
- bootstrapVshard();
+ this.configurator.configure();
logger().info("Tarantool Cartridge cluster is started");
logger()
@@ -644,23 +521,40 @@ protected boolean isCartridgeHealthy() {
}
@Override
- public ExecResult executeScript(String scriptResourcePath) throws Exception {
- return TarantoolContainerClientHelper.executeScript(this, scriptResourcePath, this.sslContext);
+ public ExecResult executeScript(String scriptResourcePath) {
+ try {
+ return TarantoolContainerClientHelper.executeScript(
+ this, scriptResourcePath, this.sslContext);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
}
@Override
- public T executeScriptDecoded(String scriptResourcePath) throws Exception {
- return TarantoolContainerClientHelper.executeScriptDecoded(
- this, scriptResourcePath, this.sslContext);
+ public T executeScriptDecoded(String scriptResourcePath) {
+ try {
+ return TarantoolContainerClientHelper.executeScriptDecoded(
+ this, scriptResourcePath, this.sslContext);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
}
@Override
- public ExecResult executeCommand(String command) throws Exception {
- return TarantoolContainerClientHelper.executeCommand(this, command, this.sslContext);
+ public ExecResult executeCommand(String command) {
+ try {
+ return TarantoolContainerClientHelper.executeCommand(this, command, this.sslContext);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
}
@Override
- public T executeCommandDecoded(String command) throws Exception {
- return TarantoolContainerClientHelper.executeCommandDecoded(this, command, this.sslContext);
+ public T executeCommandDecoded(String command) {
+ try {
+ return TarantoolContainerClientHelper.executeCommandDecoded(this, command, this.sslContext);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
}
}
diff --git a/testcontainers/src/main/java/org/testcontainers/containers/cluster/vshard/VshardClusterConfigurator.java b/testcontainers/src/main/java/org/testcontainers/containers/cluster/vshard/VshardClusterConfigurator.java
new file mode 100644
index 00000000..31423495
--- /dev/null
+++ b/testcontainers/src/main/java/org/testcontainers/containers/cluster/vshard/VshardClusterConfigurator.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2025 VK DIGITAL TECHNOLOGIES LIMITED LIABILITY COMPANY
+ * All Rights Reserved.
+ */
+
+package org.testcontainers.containers.cluster.vshard;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.testcontainers.containers.cluster.ClusterConfigurator;
+
+/** Configures a vshard-based cluster after container startup. */
+public class VshardClusterConfigurator implements ClusterConfigurator {
+
+ public static final String DEFAULT_CLUSTER_NAME = "vshard-cluster";
+ private static final String ROUTER_NODE_NAME = "router";
+
+ private final VshardClusterContainer container;
+ private final String clusterName;
+ private final AtomicBoolean configured;
+
+ public VshardClusterConfigurator(VshardClusterContainer container) {
+ this(container, DEFAULT_CLUSTER_NAME);
+ }
+
+ public VshardClusterConfigurator(VshardClusterContainer container, String clusterName) {
+ this.container = container;
+ this.clusterName = clusterName;
+ this.configured = new AtomicBoolean(false);
+ }
+
+ @Override
+ public String clusterName() {
+ return this.clusterName;
+ }
+
+ @Override
+ public Map nodes() {
+ return Collections.singletonMap(ROUTER_NODE_NAME, this.container);
+ }
+
+ @Override
+ public void configure() {
+ this.container.waitUntilRouterIsUp(VshardClusterContainer.TIMEOUT_ROUTER_HEALTH_IN_SECONDS);
+ this.container.waitUntilVshardIsBootstrapped(
+ VshardClusterContainer.TIMEOUT_VSHARD_BOOTSTRAP_IN_SECONDS);
+ this.container.waitUntilCrudIsUp(VshardClusterContainer.TIMEOUT_CRUD_HEALTH_IN_SECONDS);
+ this.configured.set(true);
+ }
+
+ @Override
+ public boolean configured() {
+ return this.configured.get();
+ }
+}
diff --git a/testcontainers/src/main/java/org/testcontainers/containers/VshardClusterContainer.java b/testcontainers/src/main/java/org/testcontainers/containers/cluster/vshard/VshardClusterContainer.java
similarity index 65%
rename from testcontainers/src/main/java/org/testcontainers/containers/VshardClusterContainer.java
rename to testcontainers/src/main/java/org/testcontainers/containers/cluster/vshard/VshardClusterContainer.java
index 43b2dffc..de4cce6d 100644
--- a/testcontainers/src/main/java/org/testcontainers/containers/VshardClusterContainer.java
+++ b/testcontainers/src/main/java/org/testcontainers/containers/cluster/vshard/VshardClusterContainer.java
@@ -3,22 +3,40 @@
* All Rights Reserved.
*/
-package org.testcontainers.containers;
+package org.testcontainers.containers.cluster.vshard;
import java.io.IOException;
+import java.io.InputStream;
import java.net.URL;
+import java.nio.file.Path;
+import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Supplier;
+import java.util.stream.Collectors;
import static org.testcontainers.containers.utils.PathUtils.normalizePath;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.github.dockerjava.api.command.InspectContainerResponse;
+import com.github.dockerjava.api.model.HealthCheck;
import lombok.Getter;
import org.apache.commons.lang3.ArrayUtils;
+import org.testcontainers.containers.Arguments;
+import org.testcontainers.containers.BindMode;
+import org.testcontainers.containers.ContainerLaunchException;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.TarantoolConfigParser;
+import org.testcontainers.containers.cluster.ClusterConfigurator;
+import org.testcontainers.containers.cluster.ClusterContainer;
import org.testcontainers.containers.utils.SslContext;
import org.testcontainers.containers.utils.TarantoolContainerClientHelper;
import org.testcontainers.images.builder.ImageFromDockerfile;
@@ -26,9 +44,8 @@
/**
* @author Artyom Dubinin
*/
-@Deprecated
public class VshardClusterContainer extends GenericContainer
- implements TarantoolContainerOperations {
+ implements ClusterContainer {
protected static final String ROUTER_HOST = "localhost";
protected static final int ROUTER_PORT = 3301;
@@ -37,6 +54,18 @@ public class VshardClusterContainer extends GenericContainer configurator;
private final TarantoolConfigParser configParser;
+ private final List instanceNames;
+ private final Lock lock;
+ private boolean configured;
protected boolean useFixedPorts = false;
@Getter protected String routerHost = ROUTER_HOST;
@@ -125,6 +161,9 @@ protected VshardClusterContainer(
this.instancesFile = instancesFile;
this.configFile = configFile;
this.configParser = new TarantoolConfigParser(configFile);
+ this.instanceNames = parseInstanceNames(instancesFile);
+ this.lock = new ReentrantLock();
+ this.configurator = new VshardClusterConfigurator(this);
}
protected static ImageFromDockerfile withBuildArgs(
@@ -237,6 +276,21 @@ public int getInternalPort() {
return routerPort;
}
+ @Override
+ public ClusterConfigurator getConfigurator() {
+ return this.configurator;
+ }
+
+ public VshardClusterContainer withClusterConfigurator(
+ ClusterConfigurator configurator) {
+ checkNotRunning();
+ if (configurator == null) {
+ throw new IllegalArgumentException("Cluster configurator must not be null");
+ }
+ this.configurator = configurator;
+ return this;
+ }
+
public String getAPIHost() {
return routerHost;
}
@@ -291,15 +345,56 @@ public VshardClusterContainer withRouterPassword(String routerPassword) {
@Override
protected void configure() {
- if (!getDirectoryBinding().isEmpty()) {
- withFileSystemBind(getDirectoryBinding(), getInstanceDir(), BindMode.READ_WRITE);
- }
- if (useFixedPorts) {
- for (Integer port : configParser.getExposablePorts()) {
- addFixedExposedPort(port, port);
+ try {
+ this.lock.lock();
+
+ if (this.configured) {
+ return;
}
- } else {
- addExposedPorts(ArrayUtils.toPrimitive(configParser.getExposablePorts()));
+
+ if (!getDirectoryBinding().isBlank()) {
+ withFileSystemBind(getDirectoryBinding(), getInstanceDir(), BindMode.READ_WRITE);
+ }
+
+ if (!instanceNames.isEmpty()) {
+ withNetworkAliases(instanceNames.toArray(new String[0]));
+ }
+
+ if (useFixedPorts) {
+ for (Integer port : configParser.getExposablePorts()) {
+ addFixedExposedPort(port, port);
+ }
+ } else {
+ addExposedPorts(ArrayUtils.toPrimitive(configParser.getExposablePorts()));
+ }
+
+ String configFileName = getFileName(configFile);
+ Path appPath = Path.of(instanceDir, APP_NAME);
+ withEnv("TT_CONFIG", appPath.resolve(configFileName).toString());
+ withStartupTimeout(Duration.ofSeconds(TIMEOUT_CONTAINER_START_IN_SECONDS));
+ withPrivilegedMode(true);
+ withCreateContainerCmdModifier(
+ cmd -> {
+ cmd.withUser("root")
+ .withEntrypoint("sh")
+ .withHealthcheck(new HealthCheck().withTest(List.of("NONE")));
+
+ String[] env = cmd.getEnv();
+ if (env != null && env.length > 0) {
+ cmd.withEnv(
+ Arrays.stream(env)
+ .filter(e -> !e.startsWith("TT_APP_NAME="))
+ .filter(e -> !e.startsWith("TT_INSTANCE_NAME="))
+ .toArray(String[]::new));
+ }
+ });
+ withCommand("-ec", String.format(VSHARD_STARTUP_COMMAND_TEMPLATE, appPath));
+
+ this.configured = true;
+ } catch (Exception e) {
+ throw new ContainerLaunchException(e.getMessage(), e);
+ } finally {
+ this.lock.unlock();
}
}
@@ -312,7 +407,7 @@ protected void containerIsStarting(InspectContainerResponse containerInfo) {
protected void containerIsStarted(InspectContainerResponse containerInfo, boolean reused) {
super.containerIsStarted(containerInfo, reused);
- waitUntilCrudIsUp(TIMEOUT_CRUD_HEALTH_IN_SECONDS);
+ this.configurator.configure();
logger().info("Tarantool vshard cluster cluster is started");
logger()
@@ -329,6 +424,20 @@ protected void waitUntilCrudIsUp(int secondsToWait) {
}
}
+ protected void waitUntilRouterIsUp(int secondsToWait) {
+ if (!waitUntilTrue(secondsToWait, this::routerIsUp)) {
+ throw new RuntimeException(
+ "Timeout exceeded during router startup stage." + " See the specific error in logs.");
+ }
+ }
+
+ protected void waitUntilVshardIsBootstrapped(int secondsToWait) {
+ if (!waitUntilTrue(secondsToWait, this::vshardIsBootstrapped)) {
+ throw new RuntimeException(
+ "Timeout exceeded during vshard bootstrap stage." + " See the specific error in logs.");
+ }
+ }
+
protected boolean waitUntilTrue(int secondsToWait, Supplier waitFunc) {
int secondsPassed = 0;
boolean result = waitFunc.get();
@@ -365,6 +474,68 @@ protected boolean crudIsUp() {
}
}
+ protected boolean routerIsUp() {
+ ExecResult result;
+ try {
+ result = TarantoolContainerClientHelper.executeCommand(this, ROUTER_HEALTH_COMMAND, null);
+ if (result.getExitCode() != 0) {
+ logger()
+ .error(
+ "exit code: {}, stdout: {}, stderr: {}",
+ result.getExitCode(),
+ result.getStdout(),
+ result.getStderr());
+ return false;
+ }
+ return result.getStdout().contains("running");
+ } catch (Exception e) {
+ logger().error(e.getMessage());
+ return false;
+ }
+ }
+
+ protected boolean vshardIsBootstrapped() {
+ try {
+ List> result =
+ TarantoolContainerClientHelper.executeCommandDecoded(
+ this, VSHARD_BOOTSTRAP_COMMAND, null);
+ if (result.size() >= 2 && result.get(1) != null) {
+ logger().warn("Vshard bootstrap is not ready yet: {}", result.get(1));
+ return false;
+ }
+ return result.size() >= 1 && Boolean.TRUE.equals(result.get(0));
+ } catch (Exception e) {
+ logger().warn("Vshard bootstrap attempt failed: {}", e.getMessage());
+ return false;
+ }
+ }
+
+ protected String getFileName(String filePath) {
+ if (filePath == null || filePath.isBlank()) {
+ throw new IllegalArgumentException("File path must not be null or empty");
+ }
+ Path path = Path.of(filePath.trim());
+ Path fileName = path.getFileName();
+ return fileName == null ? filePath : fileName.toString();
+ }
+
+ private List parseInstanceNames(String instancesPath) {
+ try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(instancesPath)) {
+ if (inputStream == null) {
+ throw new IllegalArgumentException(
+ String.format("No resource path found for the specified resource %s", instancesPath));
+ }
+ Map parsed =
+ YAML_MAPPER.readValue(inputStream, new TypeReference