From ede27d1724b6b8845d0ff837665b54fe5d2a4de6 Mon Sep 17 00:00:00 2001 From: aromanova Date: Sat, 22 Oct 2022 13:54:48 +0300 Subject: [PATCH 1/4] Add datetime converter Closes #214 --- .github/workflows/tests-ce.yml | 2 +- CHANGELOG.md | 1 + pom.xml | 2 +- .../driver/api/tuple/TarantoolTuple.java | 57 ++++++++++++------- .../driver/core/tuple/TarantoolTupleImpl.java | 11 ++++ ...faultInstantToExtensionValueConverter.java | 38 +++++++++++++ ...faultExtensionValueToInstantConverter.java | 36 ++++++++++++ .../DefaultMessagePackMapperFactory.java | 5 ++ .../io/tarantool/driver/TarantoolUtils.java | 30 ++++++---- .../ConvertersWithClusterClientIT.java | 21 ++++++- .../ConvertersWithProxyClientIT.java | 21 ++++++- .../integration/SharedTarantoolContainer.java | 6 +- .../mappers/DefaultInstantConverterTest.java | 54 ++++++++++++++++++ .../cartridge/app/roles/api_storage.lua | 17 ++++++ .../org/testcontainers/containers/server.lua | 28 +++++++++ 15 files changed, 293 insertions(+), 36 deletions(-) create mode 100644 src/main/java/io/tarantool/driver/mappers/converters/object/DefaultInstantToExtensionValueConverter.java create mode 100644 src/main/java/io/tarantool/driver/mappers/converters/value/defaults/DefaultExtensionValueToInstantConverter.java create mode 100644 src/test/java/io/tarantool/driver/mappers/DefaultInstantConverterTest.java diff --git a/.github/workflows/tests-ce.yml b/.github/workflows/tests-ce.yml index de0d9dc0d..cd0a9dcd2 100644 --- a/.github/workflows/tests-ce.yml +++ b/.github/workflows/tests-ce.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - tarantool-version: [ "1.10", "2.8" ] + tarantool-version: [ "1.x", "2.10.6", "2.x" ] fail-fast: false steps: - uses: actions/checkout@v2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 0429a3bf2..06579ca57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - Add deep copy instead of shallow copy in default message pack mapper ([#166](https://github.com/tarantool/cartridge-java/issues/166)) - Add a factory builder for constructing mapper hierarchies - Add "can convert value" check to TupleResultConverter +- Support Datetime type ([#293](https://github.com/tarantool/cartridge-java/pull/293)) ## [0.10.1] - 2023-01-13 diff --git a/pom.xml b/pom.xml index 5f818dbc9..c19bf56a4 100644 --- a/pom.xml +++ b/pom.xml @@ -264,7 +264,7 @@ io.tarantool testcontainers-java-tarantool - 0.5.3 + 0.5.4 test diff --git a/src/main/java/io/tarantool/driver/api/tuple/TarantoolTuple.java b/src/main/java/io/tarantool/driver/api/tuple/TarantoolTuple.java index d55257d15..359b931bc 100644 --- a/src/main/java/io/tarantool/driver/api/tuple/TarantoolTuple.java +++ b/src/main/java/io/tarantool/driver/api/tuple/TarantoolTuple.java @@ -1,13 +1,14 @@ package io.tarantool.driver.api.tuple; -import io.tarantool.driver.protocol.Packable; - import java.math.BigDecimal; +import java.time.Instant; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.UUID; +import io.tarantool.driver.protocol.Packable; + /** * Basic Tarantool atom of data * @@ -24,7 +25,7 @@ public interface TarantoolTuple extends Iterable, Packable { /** * Get a tuple field by its position * - * @param fieldPosition the field position from the the tuple start, starting from 0 + * @param fieldPosition the field position from the tuple start, starting from 0 * @return field or empty optional if the field position is out of tuple length */ Optional getField(int fieldPosition); @@ -47,7 +48,7 @@ public interface TarantoolTuple extends Iterable, Packable { /** * Get a tuple field value by its position specifying the target value type * - * @param fieldPosition field position from the the tuple start, starting from 0 + * @param fieldPosition field position from the tuple start, starting from 0 * @param objectClass target value type class * @param target value type * @return nullable value of a field wrapped in Optional, possibly converted to a Java type @@ -57,7 +58,7 @@ public interface TarantoolTuple extends Iterable, Packable { /** * Check if a tuple field exists and can be converted to the target value type * - * @param fieldPosition field position from the the tuple start, starting from 0 + * @param fieldPosition field position from the tuple start, starting from 0 * @param objectClass target value type class * @return true, if the field exists and can be converted to the given type, false otherwise */ @@ -85,7 +86,7 @@ public interface TarantoolTuple extends Iterable, Packable { /** * Get a tuple field value as a raw object * - * @param fieldPosition field position from the the tuple start, starting from 0 + * @param fieldPosition field position from the tuple start, starting from 0 * @return nullable value of a field wrapped in Optional */ Optional getObject(int fieldPosition); @@ -108,7 +109,7 @@ public interface TarantoolTuple extends Iterable, Packable { /** * Set a tuple field by field position * - * @param fieldPosition the field position from the the tuple start, starting from 0 + * @param fieldPosition the field position from the tuple start, starting from 0 * @param field new field */ void setField(int fieldPosition, TarantoolField field); @@ -124,7 +125,7 @@ public interface TarantoolTuple extends Iterable, Packable { /** * Set a tuple field value from an object by field position * - * @param fieldPosition the field position from the the tuple start, starting from 0 + * @param fieldPosition the field position from the tuple start, starting from 0 * @param value new field value */ void putObject(int fieldPosition, Object value); @@ -140,7 +141,7 @@ public interface TarantoolTuple extends Iterable, Packable { /** * Get the field value converted to {@code byte[]} * - * @param fieldPosition the field position from the the tuple start, starting from 0 + * @param fieldPosition the field position from the tuple start, starting from 0 * @return value */ byte[] getByteArray(int fieldPosition); @@ -156,7 +157,7 @@ public interface TarantoolTuple extends Iterable, Packable { /** * Get the field value converted to {@code Boolean} * - * @param fieldPosition the field position from the the tuple start, starting from 0 + * @param fieldPosition the field position from the tuple start, starting from 0 * @return value */ Boolean getBoolean(int fieldPosition); @@ -172,7 +173,7 @@ public interface TarantoolTuple extends Iterable, Packable { /** * Get the field value converted to {@code Double} * - * @param fieldPosition the field position from the the tuple start, starting from 0 + * @param fieldPosition the field position from the tuple start, starting from 0 * @return value */ Double getDouble(int fieldPosition); @@ -188,7 +189,7 @@ public interface TarantoolTuple extends Iterable, Packable { /** * Get the field value converted to {@code Float} * - * @param fieldPosition the field position from the the tuple start, starting from 0 + * @param fieldPosition the field position from the tuple start, starting from 0 * @return value */ Float getFloat(int fieldPosition); @@ -204,7 +205,7 @@ public interface TarantoolTuple extends Iterable, Packable { /** * Get the field value converted to {@code Integer} * - * @param fieldPosition the field position from the the tuple start, starting from 0 + * @param fieldPosition the field position from the tuple start, starting from 0 * @return value */ Integer getInteger(int fieldPosition); @@ -220,7 +221,7 @@ public interface TarantoolTuple extends Iterable, Packable { /** * Get the field value converted to {@code Long} * - * @param fieldPosition the field position from the the tuple start, starting from 0 + * @param fieldPosition the field position from the tuple start, starting from 0 * @return value */ Long getLong(int fieldPosition); @@ -236,7 +237,7 @@ public interface TarantoolTuple extends Iterable, Packable { /** * Get the field value converted to {@code String} * - * @param fieldPosition the field position from the the tuple start, starting from 0 + * @param fieldPosition the field position from the tuple start, starting from 0 * @return value */ String getString(int fieldPosition); @@ -252,7 +253,7 @@ public interface TarantoolTuple extends Iterable, Packable { /** * Get the field value converted to {@code Character} * - * @param fieldPosition the field position from the the tuple start, starting from 0 + * @param fieldPosition the field position from the tuple start, starting from 0 * @return value */ Character getCharacter(int fieldPosition); @@ -268,7 +269,7 @@ public interface TarantoolTuple extends Iterable, Packable { /** * Get the field value converted to {@link UUID} * - * @param fieldPosition the field position from the the tuple start, starting from 0 + * @param fieldPosition the field position from the tuple start, starting from 0 * @return value */ UUID getUUID(int fieldPosition); @@ -281,10 +282,26 @@ public interface TarantoolTuple extends Iterable, Packable { */ UUID getUUID(String fieldName); + /** + * Get the field value converted to {@link Instant} + * + * @param fieldPosition the field position from the tuple start, starting from 0 + * @return value + */ + Instant getInstant(int fieldPosition); + + /** + * Get the field value converted to {@link Instant} + * + * @param fieldName the field name, must not be null + * @return value + */ + Instant getInstant(String fieldName); + /** * Get the field value converted to {@link BigDecimal} * - * @param fieldPosition the field position from the the tuple start, starting from 0 + * @param fieldPosition the field position from the tuple start, starting from 0 * @return value */ BigDecimal getDecimal(int fieldPosition); @@ -300,7 +317,7 @@ public interface TarantoolTuple extends Iterable, Packable { /** * Get the field value converted to {@link List} * - * @param fieldPosition the field position from the the tuple start, starting from 0 + * @param fieldPosition the field position from the tuple start, starting from 0 * @return value */ List getList(int fieldPosition); @@ -316,7 +333,7 @@ public interface TarantoolTuple extends Iterable, Packable { /** * Get the field value converted to {@link Map} * - * @param fieldPosition the field position from the the tuple start, starting from 0 + * @param fieldPosition the field position from the tuple start, starting from 0 * @return value */ Map getMap(int fieldPosition); diff --git a/src/main/java/io/tarantool/driver/core/tuple/TarantoolTupleImpl.java b/src/main/java/io/tarantool/driver/core/tuple/TarantoolTupleImpl.java index 9042f812f..e4968ab46 100644 --- a/src/main/java/io/tarantool/driver/core/tuple/TarantoolTupleImpl.java +++ b/src/main/java/io/tarantool/driver/core/tuple/TarantoolTupleImpl.java @@ -18,6 +18,7 @@ import java.io.IOException; import java.math.BigDecimal; +import java.time.Instant; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -368,6 +369,16 @@ public UUID getUUID(String fieldName) { return getObject(fieldName, UUID.class).orElse(null); } + @Override + public Instant getInstant(int fieldPosition) { + return getObject(fieldPosition, Instant.class).orElse(null); + } + + @Override + public Instant getInstant(String fieldName) { + return getObject(fieldName, Instant.class).orElse(null); + } + @Override public BigDecimal getDecimal(int fieldPosition) { return getObject(fieldPosition, BigDecimal.class).orElse(null); diff --git a/src/main/java/io/tarantool/driver/mappers/converters/object/DefaultInstantToExtensionValueConverter.java b/src/main/java/io/tarantool/driver/mappers/converters/object/DefaultInstantToExtensionValueConverter.java new file mode 100644 index 000000000..c3d61534d --- /dev/null +++ b/src/main/java/io/tarantool/driver/mappers/converters/object/DefaultInstantToExtensionValueConverter.java @@ -0,0 +1,38 @@ +package io.tarantool.driver.mappers.converters.object; + +import io.tarantool.driver.mappers.converters.ObjectConverter; + +import org.msgpack.core.MessageBufferPacker; +import org.msgpack.core.MessagePack; +import org.msgpack.value.ExtensionValue; +import org.msgpack.value.ValueFactory; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.time.Instant; + +/** + * Default {@link java.time.Instant} to {@link ExtensionValue} converter + * + * @author Anastasiia Romanova + * @author Artyom Dubinin + */ +public class DefaultInstantToExtensionValueConverter implements ObjectConverter { + + private static final long serialVersionUID = 20221025L; + + private static final byte DATETIME_TYPE = 0x04; + + private byte[] toBytes(Instant value) { + ByteBuffer buffer = ByteBuffer.wrap(new byte[16]); + buffer.order(ByteOrder.LITTLE_ENDIAN); + buffer.putLong(value.getEpochSecond()); + buffer.putInt(value.getNano()); + return buffer.array(); + } + + @Override + public ExtensionValue toValue(Instant object) { + return ValueFactory.newExtension(DATETIME_TYPE, toBytes(object)); + } +} diff --git a/src/main/java/io/tarantool/driver/mappers/converters/value/defaults/DefaultExtensionValueToInstantConverter.java b/src/main/java/io/tarantool/driver/mappers/converters/value/defaults/DefaultExtensionValueToInstantConverter.java new file mode 100644 index 000000000..c9a099259 --- /dev/null +++ b/src/main/java/io/tarantool/driver/mappers/converters/value/defaults/DefaultExtensionValueToInstantConverter.java @@ -0,0 +1,36 @@ +package io.tarantool.driver.mappers.converters.value.defaults; + +import io.tarantool.driver.mappers.converters.ValueConverter; +import org.msgpack.value.ExtensionValue; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.time.Instant; + +/** + * Default {@link ExtensionValue} to {@link java.time.Instant} converter + * + * @author Anastasiia Romanova + * @author Artyom Dubinin + */ +public class DefaultExtensionValueToInstantConverter implements ValueConverter { + + private static final long serialVersionUID = 20221025L; + private static final byte DATETIME_TYPE = 0x04; + + private Instant fromBytes(byte[] bytes) { + ByteBuffer buffer = ByteBuffer.wrap(bytes); + buffer.order(ByteOrder.LITTLE_ENDIAN); + return Instant.ofEpochSecond(buffer.getLong()).plusNanos(buffer.getInt()); + } + + @Override + public Instant fromValue(ExtensionValue value) { + return fromBytes(value.getData()); + } + + @Override + public boolean canConvertValue(ExtensionValue value) { + return value.getType() == DATETIME_TYPE; + } +} diff --git a/src/main/java/io/tarantool/driver/mappers/factories/DefaultMessagePackMapperFactory.java b/src/main/java/io/tarantool/driver/mappers/factories/DefaultMessagePackMapperFactory.java index a5594c2b1..590205bdc 100644 --- a/src/main/java/io/tarantool/driver/mappers/factories/DefaultMessagePackMapperFactory.java +++ b/src/main/java/io/tarantool/driver/mappers/factories/DefaultMessagePackMapperFactory.java @@ -7,6 +7,7 @@ import io.tarantool.driver.mappers.converters.object.DefaultCharacterToStringValueConverter; import io.tarantool.driver.mappers.converters.object.DefaultDoubleToFloatValueConverter; import io.tarantool.driver.mappers.converters.object.DefaultFloatToFloatValueConverter; +import io.tarantool.driver.mappers.converters.object.DefaultInstantToExtensionValueConverter; import io.tarantool.driver.mappers.converters.object.DefaultIntegerToIntegerValueConverter; import io.tarantool.driver.mappers.converters.object.DefaultLongArrayToArrayValueConverter; import io.tarantool.driver.mappers.converters.object.DefaultLongToIntegerValueConverter; @@ -15,6 +16,7 @@ import io.tarantool.driver.mappers.converters.object.DefaultShortToIntegerValueConverter; import io.tarantool.driver.mappers.converters.object.DefaultStringToStringValueConverter; import io.tarantool.driver.mappers.converters.object.DefaultUUIDToExtensionValueConverter; +import io.tarantool.driver.mappers.converters.value.defaults.DefaultExtensionValueToInstantConverter; import io.tarantool.driver.mappers.converters.value.defaults.DefaultArrayValueToLongArrayConverter; import io.tarantool.driver.mappers.converters.value.defaults.DefaultBinaryValueToByteArrayConverter; import io.tarantool.driver.mappers.converters.value.defaults.DefaultBooleanValueToBooleanConverter; @@ -43,6 +45,7 @@ import org.msgpack.value.ValueType; import java.math.BigDecimal; +import java.time.Instant; import java.util.UUID; /** @@ -82,6 +85,7 @@ private DefaultMessagePackMapperFactory() { .withValueConverter(ValueType.EXTENSION, UUID.class, new DefaultExtensionValueToUUIDConverter()) .withValueConverter(ValueType.EXTENSION, BigDecimal.class, new DefaultExtensionValueToBigDecimalConverter()) + .withValueConverter(ValueType.EXTENSION, Instant.class, new DefaultExtensionValueToInstantConverter()) .withValueConverter(ValueType.NIL, Object.class, new DefaultNilValueToNullConverter()) //TODO: Potential issue https://github.com/tarantool/cartridge-java/issues/118 .withObjectConverter(Character.class, StringValue.class, new DefaultCharacterToStringValueConverter()) @@ -97,6 +101,7 @@ private DefaultMessagePackMapperFactory() { .withObjectConverter(UUID.class, ExtensionValue.class, new DefaultUUIDToExtensionValueConverter()) .withObjectConverter(BigDecimal.class, ExtensionValue.class, new DefaultBigDecimalToExtensionValueConverter()) + .withObjectConverter(Instant.class, ExtensionValue.class, new DefaultInstantToExtensionValueConverter()) .build(); } diff --git a/src/test/java/io/tarantool/driver/TarantoolUtils.java b/src/test/java/io/tarantool/driver/TarantoolUtils.java index 98fcf8c48..2bd79851b 100644 --- a/src/test/java/io/tarantool/driver/TarantoolUtils.java +++ b/src/test/java/io/tarantool/driver/TarantoolUtils.java @@ -15,7 +15,7 @@ public final class TarantoolUtils { private TarantoolUtils() { } - public static boolean versionGreaterThen(String tarantoolVersion) { + public static boolean versionGreaterOrEqualThen(String tarantoolVersion) { Assert.notNull(tarantoolVersion, "tarantoolVersion must not be null"); String tarantoolCiVersion = java.lang.System.getenv(TARANTOOL_VERSION); if (StringUtils.isEmpty(tarantoolCiVersion)) { @@ -23,29 +23,37 @@ public static boolean versionGreaterThen(String tarantoolVersion) { } TarantoolVersion ciVersion = new TarantoolVersion(tarantoolCiVersion); TarantoolVersion version = new TarantoolVersion(tarantoolVersion); - return ciVersion.getMajor() > version.getMajor() && - ciVersion.getMinor() > version.getMinor(); + return ciVersion.getMajor() >= version.getMajor() && + ciVersion.getMinor() >= version.getMinor(); } public static boolean versionWithUUID() { - return versionGreaterThen("2.4"); + return versionGreaterOrEqualThen("2.4"); + } + + public static boolean versionWithInstant() { + return versionGreaterOrEqualThen("2.10"); } public static boolean versionWithVarbinary() { - return versionGreaterThen("2.2.1"); + return versionGreaterOrEqualThen("2.2.1"); } public static class TarantoolVersion { - private final Integer major; - private final Integer minor; + private Integer major; + private Integer minor; public TarantoolVersion(String stringVersion) { - List majorMinor = StringUtils.isEmpty(stringVersion) ? Collections.emptyList() : + List majorMinor = StringUtils.isEmpty(stringVersion) ? Collections.emptyList() : Arrays.stream(stringVersion.split("\\.")) - .map(Integer::parseInt) .collect(Collectors.toList()); - major = majorMinor.size() >= 1 ? majorMinor.get(0) : 0; - minor = majorMinor.size() >= 2 ? majorMinor.get(1) : 0; + if (majorMinor.size() >= 1) { + major = Integer.parseInt(majorMinor.get(0)); + } + if (majorMinor.size() >= 2) { + String minorStr = majorMinor.get(1); + minor = minorStr.equals("x") ? 999 : Integer.parseInt(minorStr); + } } public Integer getMajor() { diff --git a/src/test/java/io/tarantool/driver/integration/ConvertersWithClusterClientIT.java b/src/test/java/io/tarantool/driver/integration/ConvertersWithClusterClientIT.java index 3a4e8db01..eb7392760 100644 --- a/src/test/java/io/tarantool/driver/integration/ConvertersWithClusterClientIT.java +++ b/src/test/java/io/tarantool/driver/integration/ConvertersWithClusterClientIT.java @@ -15,10 +15,12 @@ import org.junit.jupiter.api.condition.EnabledIf; import org.testcontainers.shaded.org.apache.commons.lang3.ArrayUtils; +import java.time.Instant; +import java.util.UUID; + import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; -import java.util.UUID; /** * @author Artyom Dubinin @@ -63,6 +65,23 @@ public void test_boxSelect_shouldReturnTupleWithUUID() throws Exception { Assertions.assertEquals(uuid, fields.getUUID("uuid_field")); } + @Test + @EnabledIf("io.tarantool.driver.TarantoolUtils#versionWithInstant") + public void test_boxSelect_shouldReturnTupleWithInstant() throws Exception { + //given + Instant instant = Instant.now(); + client.space("space_with_instant") + .insert(tupleFactory.create(1, instant)).get(); + + //when + TarantoolTuple fields = client + .space("space_with_instant") + .select(Conditions.equals("id", 1)).get().get(0); + + //then + Assertions.assertEquals(instant, fields.getInstant("instant_field")); + } + @Test @EnabledIf("io.tarantool.driver.TarantoolUtils#versionWithVarbinary") public void test_boxOperations_shouldWorkWithVarbinary() throws Exception { diff --git a/src/test/java/io/tarantool/driver/integration/ConvertersWithProxyClientIT.java b/src/test/java/io/tarantool/driver/integration/ConvertersWithProxyClientIT.java index 37c33d307..42487e993 100644 --- a/src/test/java/io/tarantool/driver/integration/ConvertersWithProxyClientIT.java +++ b/src/test/java/io/tarantool/driver/integration/ConvertersWithProxyClientIT.java @@ -15,10 +15,12 @@ import org.junit.jupiter.api.condition.EnabledIf; import org.testcontainers.shaded.org.apache.commons.lang3.ArrayUtils; +import java.time.Instant; +import java.util.UUID; + import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; -import java.util.UUID; /** * @author Artyom Dubinin @@ -64,6 +66,23 @@ public void test_crudSelect_shouldReturnTupleWithUUID() throws Exception { Assertions.assertEquals(uuid, fields.getUUID("uuid_field")); } + @Test + @EnabledIf("io.tarantool.driver.TarantoolUtils#versionWithInstant") + public void test_crudSelect_shouldReturnTupleWithInstant() throws Exception { + //given + Instant instant = Instant.now(); + client.space("space_with_instant") + .insert(tupleFactory.create(1, instant)).get(); + + //when + TarantoolTuple fields = client + .space("space_with_instant") + .select(Conditions.equals("id", 1)).get().get(0); + + //then + Assertions.assertEquals(instant, fields.getInstant("instant_field")); + } + @Test @Disabled("Until https://github.com/tarantool/tarantool/issues/1629 is fixed") @EnabledIf("io.tarantool.driver.TarantoolUtils#versionWithVarbinary") diff --git a/src/test/java/io/tarantool/driver/integration/SharedTarantoolContainer.java b/src/test/java/io/tarantool/driver/integration/SharedTarantoolContainer.java index 4a412c9b6..30b1b47fc 100644 --- a/src/test/java/io/tarantool/driver/integration/SharedTarantoolContainer.java +++ b/src/test/java/io/tarantool/driver/integration/SharedTarantoolContainer.java @@ -9,7 +9,11 @@ abstract class SharedTarantoolContainer { private static final Logger logger = LoggerFactory.getLogger(SharedTarantoolContainer.class); - protected static final TarantoolContainer container = new TarantoolContainer() + protected static final String tarantoolVersion = System.getenv().get("TARANTOOL_VERSION"); + protected static final TarantoolContainer container = + new TarantoolContainer( + String.format("tarantool/tarantool:%s-centos7", + tarantoolVersion != null ? tarantoolVersion : "2.10.5")) .withScriptFileName("org/testcontainers/containers/server.lua") .withLogConsumer(new Slf4jLogConsumer(logger)); diff --git a/src/test/java/io/tarantool/driver/mappers/DefaultInstantConverterTest.java b/src/test/java/io/tarantool/driver/mappers/DefaultInstantConverterTest.java new file mode 100644 index 000000000..b88e72361 --- /dev/null +++ b/src/test/java/io/tarantool/driver/mappers/DefaultInstantConverterTest.java @@ -0,0 +1,54 @@ +package io.tarantool.driver.mappers; + +import io.tarantool.driver.mappers.converters.object.DefaultInstantToExtensionValueConverter; +import io.tarantool.driver.mappers.converters.value.defaults.DefaultExtensionValueToInstantConverter; + +import org.junit.jupiter.api.Test; +import org.msgpack.core.MessageBufferPacker; +import org.msgpack.core.MessagePack; +import org.msgpack.core.MessagePacker; +import org.msgpack.value.ExtensionValue; +import org.msgpack.value.ImmutableExtensionValue; +import org.msgpack.value.ValueFactory; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.Base64; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class DefaultInstantConverterTest { + @Test + void toValue() throws IOException { + DefaultInstantToExtensionValueConverter converter = new DefaultInstantToExtensionValueConverter(); + MessagePacker packer = MessagePack.newDefaultBufferPacker(); + Base64.Encoder encoder = Base64.getEncoder(); + Instant instant = LocalDateTime.parse("2022-10-25T12:03:58").toInstant(ZoneOffset.UTC); + byte[] result = ((MessageBufferPacker) packer.packValue(converter.toValue(instant))).toByteArray(); + assertEquals("2ASu0FdjAAAAAAAAAAAAAAAA", encoder.encodeToString(result)); + } + + @Test + void fromValue() throws IOException { + DefaultExtensionValueToInstantConverter converter = new DefaultExtensionValueToInstantConverter(); + Base64.Decoder base64decoder = Base64.getDecoder(); + Instant instant = LocalDateTime.parse("2022-10-25T12:03:58").toInstant(ZoneOffset.UTC); + byte[] packed = base64decoder.decode("2ASu0FdjAAAAAAAAAAAAAAAA"); + ExtensionValue value = MessagePack.newDefaultUnpacker(packed).unpackValue().asExtensionValue(); + assertEquals(instant, converter.fromValue(value)); + } + + @Test + void canConvertValue() { + DefaultExtensionValueToInstantConverter converter = new DefaultExtensionValueToInstantConverter(); + assertFalse(converter.canConvertValue(ValueFactory.newExtension((byte) 100, new byte[]{0}))); + assertFalse(converter.canConvertValue(ValueFactory.newExtension((byte) 0x01, new byte[]{0}))); + ImmutableExtensionValue value = ValueFactory.newExtension((byte) 0x04, new byte[]{0}); + assertTrue(converter.canConvertValue(value)); + } +} diff --git a/src/test/resources/cartridge/app/roles/api_storage.lua b/src/test/resources/cartridge/app/roles/api_storage.lua index 75815205a..cd049e600 100644 --- a/src/test/resources/cartridge/app/roles/api_storage.lua +++ b/src/test/resources/cartridge/app/roles/api_storage.lua @@ -147,6 +147,23 @@ local function init_space() { parts = { 'bucket_id' }, unique = false, if_not_exists = true, }) end + if major >= 2 and minor >= 10 and patch > 1 then + -- test space for check instant + local space_with_instant = box.schema.space.create( + 'space_with_instant', + { + format = { + { 'id', 'unsigned' }, + { 'instant_field', 'datetime',}, + { 'bucket_id', 'unsigned' }, + }, + if_not_exists = true, + } + ) + space_with_instant:create_index('id', { parts = { 'id' }, if_not_exists = true, }) + space_with_instant:create_index('bucket_id', { parts = { 'bucket_id' }, unique = false, if_not_exists = true, }) + end + local space_with_string = box.schema.space.create( 'space_with_string', { diff --git a/src/test/resources/org/testcontainers/containers/server.lua b/src/test/resources/org/testcontainers/containers/server.lua index 41c704fa6..b52d58601 100755 --- a/src/test/resources/org/testcontainers/containers/server.lua +++ b/src/test/resources/org/testcontainers/containers/server.lua @@ -107,6 +107,34 @@ if major >= 2 and minor >= 2 and patch > 1 then ) space_with_varbinary:create_index('id', { parts = { 'id' }, if_not_exists = true, }) end +if major >= 2 and minor >= 10 and patch > 1 then + -- test space for check instant + local space_with_instant = box.schema.space.create( + 'space_with_instant', + { + format = { + { 'id', 'unsigned' }, + { 'instant_field', 'datetime',}, + }, + if_not_exists = true, + } + ) + space_with_instant:create_index('id', { parts = { 'id' }, if_not_exists = true, }) +end +if major >= 2 and minor >= 10 and patch > 1 then + -- test space for check instant + local space_with_instant = box.schema.space.create( + 'space_with_instant', + { + format = { + { 'id', 'unsigned' }, + { 'instant_field', 'datetime',}, + }, + if_not_exists = true, + } + ) + space_with_instant:create_index('id', { parts = { 'id' }, if_not_exists = true, }) +end --functions From f57bded852d5f67dc4f776e428f9d41b22c21ae0 Mon Sep 17 00:00:00 2001 From: Artyom Dubinin Date: Sun, 2 Apr 2023 14:01:09 +0300 Subject: [PATCH 2/4] Reuse tarantool container --- .../ClusterTarantoolTupleClientIT.java | 29 +--------- .../driver/integration/ClusterTruncateIT.java | 42 +------------- .../driver/integration/ConnectionIT.java | 58 ++++++++----------- .../driver/integration/OffsetCursorIT.java | 41 +------------ .../integration/SharedTarantoolContainer.java | 29 ++++++++++ 5 files changed, 61 insertions(+), 138 deletions(-) diff --git a/src/test/java/io/tarantool/driver/integration/ClusterTarantoolTupleClientIT.java b/src/test/java/io/tarantool/driver/integration/ClusterTarantoolTupleClientIT.java index 68cdbfb2d..fbbb9ffe1 100644 --- a/src/test/java/io/tarantool/driver/integration/ClusterTarantoolTupleClientIT.java +++ b/src/test/java/io/tarantool/driver/integration/ClusterTarantoolTupleClientIT.java @@ -49,22 +49,16 @@ import static org.junit.jupiter.api.Assertions.assertTrue; @Testcontainers -public class ClusterTarantoolTupleClientIT { +public class ClusterTarantoolTupleClientIT extends SharedTarantoolContainer { private static final String TEST_SPACE_NAME = "test_space"; private static final Logger log = LoggerFactory.getLogger(ClusterTarantoolTupleClientIT.class); - @Container - private static final TarantoolContainer tarantoolContainer = new TarantoolContainer() - .withScriptFileName("org/testcontainers/containers/server.lua") - .withLogConsumer(new Slf4jLogConsumer(log)); - - private static TarantoolClient> client; private static final DefaultMessagePackMapperFactory mapperFactory = DefaultMessagePackMapperFactory.getInstance(); @BeforeAll public static void setUp() { - assertTrue(tarantoolContainer.isRunning()); + startContainer(); initClient(); } @@ -73,25 +67,6 @@ public static void tearDown() throws Exception { assertThrows(TarantoolClientException.class, () -> client.metadata().getSpaceByName("_space")); } - private static void initClient() { - TarantoolCredentials credentials = new SimpleTarantoolCredentials( - tarantoolContainer.getUsername(), tarantoolContainer.getPassword()); - - TarantoolServerAddress serverAddress = new TarantoolServerAddress( - tarantoolContainer.getHost(), tarantoolContainer.getPort()); - - TarantoolClientConfig config = new TarantoolClientConfig.Builder() - .withCredentials(credentials) - .withConnectTimeout(1000 * 5) - .withReadTimeout(1000 * 5) - .withRequestTimeout(1000 * 5) - .build(); - - log.info("Attempting connect to Tarantool"); - client = new ClusterTarantoolTupleClient(config, serverAddress); - log.info("Successfully connected to Tarantool, version = {}", client.getVersion()); - } - @Test public void insertAndSelectRequests() throws Exception { TarantoolSpaceOperations> testSpace = diff --git a/src/test/java/io/tarantool/driver/integration/ClusterTruncateIT.java b/src/test/java/io/tarantool/driver/integration/ClusterTruncateIT.java index 5f766d911..6a4bc6501 100644 --- a/src/test/java/io/tarantool/driver/integration/ClusterTruncateIT.java +++ b/src/test/java/io/tarantool/driver/integration/ClusterTruncateIT.java @@ -1,26 +1,15 @@ package io.tarantool.driver.integration; -import io.tarantool.driver.api.TarantoolClient; -import io.tarantool.driver.api.TarantoolClientConfig; import io.tarantool.driver.api.TarantoolResult; -import io.tarantool.driver.api.TarantoolServerAddress; import io.tarantool.driver.api.conditions.Conditions; import io.tarantool.driver.api.space.TarantoolSpaceOperations; import io.tarantool.driver.api.tuple.TarantoolTuple; -import io.tarantool.driver.auth.SimpleTarantoolCredentials; -import io.tarantool.driver.auth.TarantoolCredentials; -import io.tarantool.driver.core.ClusterTarantoolTupleClient; import io.tarantool.driver.core.tuple.TarantoolTupleImpl; import io.tarantool.driver.exceptions.TarantoolClientException; import io.tarantool.driver.mappers.factories.DefaultMessagePackMapperFactory; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.testcontainers.containers.TarantoolContainer; -import org.testcontainers.containers.output.Slf4jLogConsumer; -import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.Arrays; @@ -33,22 +22,16 @@ import static org.junit.jupiter.api.Assertions.assertTrue; @Testcontainers -public class ClusterTruncateIT { +public class ClusterTruncateIT extends SharedTarantoolContainer { private static final String TEST_SPACE_NAME = "test_space"; - private static final Logger log = LoggerFactory.getLogger(ClusterTruncateIT.class); - @Container - private static final TarantoolContainer tarantoolContainer = new TarantoolContainer() - .withScriptFileName("org/testcontainers/containers/server.lua") - .withLogConsumer(new Slf4jLogConsumer(log)); - - private static TarantoolClient> client; private static final DefaultMessagePackMapperFactory mapperFactory = DefaultMessagePackMapperFactory.getInstance(); @BeforeAll public static void setUp() { - assertTrue(tarantoolContainer.isRunning()); + startContainer(); + assertTrue(container.isRunning()); initClient(); } @@ -57,25 +40,6 @@ public static void tearDown() throws Exception { assertThrows(TarantoolClientException.class, () -> client.metadata().getSpaceByName("_space")); } - private static void initClient() { - TarantoolCredentials credentials = new SimpleTarantoolCredentials( - tarantoolContainer.getUsername(), tarantoolContainer.getPassword()); - - TarantoolServerAddress serverAddress = new TarantoolServerAddress( - tarantoolContainer.getHost(), tarantoolContainer.getPort()); - - TarantoolClientConfig config = new TarantoolClientConfig.Builder() - .withCredentials(credentials) - .withConnectTimeout(1000 * 5) - .withReadTimeout(1000 * 5) - .withRequestTimeout(1000 * 5) - .build(); - - log.info("Attempting connect to Tarantool"); - client = new ClusterTarantoolTupleClient(config, serverAddress); - log.info("Successfully connected to Tarantool, version = {}", client.getVersion()); - } - @Test public void test_truncate2TimesOneSpace_shouldNotThrowExceptionsAndSpaceShouldBeEmptyAfterEtchCall() { TarantoolSpaceOperations> testSpace = diff --git a/src/test/java/io/tarantool/driver/integration/ConnectionIT.java b/src/test/java/io/tarantool/driver/integration/ConnectionIT.java index d839eb6cd..b1239ca39 100644 --- a/src/test/java/io/tarantool/driver/integration/ConnectionIT.java +++ b/src/test/java/io/tarantool/driver/integration/ConnectionIT.java @@ -19,9 +19,6 @@ import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.testcontainers.containers.TarantoolContainer; -import org.testcontainers.containers.output.Slf4jLogConsumer; -import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.shaded.com.fasterxml.jackson.databind.util.ClassUtil; @@ -45,24 +42,19 @@ * @author Artyom Dubinin */ @Testcontainers -public class ConnectionIT { +public class ConnectionIT extends SharedTarantoolContainer { private static final String TEST_SPACE_NAME = "test_space"; private static final String GUEST_USER = "guest"; private static final String EXISTING_USER_WITHOUT_PASSWORD = "empty_password_user"; private static final Logger log = LoggerFactory.getLogger(ConnectionIT.class); - @Container - private static final TarantoolContainer tarantoolContainer = new TarantoolContainer() - .withScriptFileName("org/testcontainers/containers/server.lua") - .withLogConsumer(new Slf4jLogConsumer(log)); - @Test public void connectAndCheckMetadata() throws Exception { TarantoolCredentials credentials = new SimpleTarantoolCredentials( - tarantoolContainer.getUsername(), tarantoolContainer.getPassword()); + container.getUsername(), container.getPassword()); TarantoolServerAddress serverAddress = new TarantoolServerAddress( - tarantoolContainer.getHost(), tarantoolContainer.getPort()); + container.getHost(), container.getPort()); try (ClusterTarantoolTupleClient client = new ClusterTarantoolTupleClient(credentials, serverAddress)) { ExecutorService executor = Executors.newFixedThreadPool(10); @@ -86,10 +78,10 @@ public void connectAndCheckMetadata() throws Exception { private CompletableFuture> connectAndEval(String command) throws Exception { TarantoolCredentials credentials = new SimpleTarantoolCredentials( - tarantoolContainer.getUsername(), tarantoolContainer.getPassword()); + container.getUsername(), container.getPassword()); TarantoolServerAddress serverAddress = new TarantoolServerAddress( - tarantoolContainer.getHost(), tarantoolContainer.getPort()); + container.getHost(), container.getPort()); ClusterTarantoolTupleClient client = new ClusterTarantoolTupleClient(credentials, serverAddress); CompletableFuture> future = client.eval(command); @@ -119,7 +111,7 @@ public void testGuestExplicit() throws Exception { TarantoolCredentials credentials = new SimpleTarantoolCredentials( GUEST_USER, ""); TarantoolServerAddress serverAddress = new TarantoolServerAddress( - tarantoolContainer.getHost(), tarantoolContainer.getPort()); + container.getHost(), container.getPort()); try (ClusterTarantoolTupleClient client = new ClusterTarantoolTupleClient(credentials, serverAddress)) { List resultList = client.eval("return box.session.user()").get(); String sessionUser = (String) resultList.get(0); @@ -133,7 +125,7 @@ public void testGuestExplicitWithPassword_shouldThrowException() throws Exceptio TarantoolCredentials credentials = new SimpleTarantoolCredentials( GUEST_USER, "abcd"); TarantoolServerAddress serverAddress = new TarantoolServerAddress( - tarantoolContainer.getHost(), tarantoolContainer.getPort()); + container.getHost(), container.getPort()); try (ClusterTarantoolTupleClient client = new ClusterTarantoolTupleClient(credentials, serverAddress)) { ExecutionException e = assertThrows(ExecutionException.class, () -> { client.eval("return box.session.user()").get(); @@ -152,7 +144,7 @@ public void testGuestImplicit() throws Exception { TarantoolCredentials credentials = new SimpleTarantoolCredentials( "", ""); TarantoolServerAddress serverAddress = new TarantoolServerAddress( - tarantoolContainer.getHost(), tarantoolContainer.getPort()); + container.getHost(), container.getPort()); try (ClusterTarantoolTupleClient client = new ClusterTarantoolTupleClient(credentials, serverAddress)) { List resultList = client.eval("return box.session.user()").get(); String sessionUser = (String) resultList.get(0); @@ -166,7 +158,7 @@ public void testGuestImplicitWithPassword_shouldThrowException() throws Exceptio TarantoolCredentials credentials = new SimpleTarantoolCredentials( "", "abcd"); TarantoolServerAddress serverAddress = new TarantoolServerAddress( - tarantoolContainer.getHost(), tarantoolContainer.getPort()); + container.getHost(), container.getPort()); try (ClusterTarantoolTupleClient client = new ClusterTarantoolTupleClient(credentials, serverAddress)) { ExecutionException e = assertThrows(ExecutionException.class, () -> { List resultList = client.eval("return box.session.user()").get(); @@ -185,7 +177,7 @@ public void testExistingUserWithoutPassword() throws Exception { TarantoolCredentials credentials = new SimpleTarantoolCredentials( EXISTING_USER_WITHOUT_PASSWORD, ""); TarantoolServerAddress serverAddress = new TarantoolServerAddress( - tarantoolContainer.getHost(), tarantoolContainer.getPort()); + container.getHost(), container.getPort()); try (ClusterTarantoolTupleClient client = new ClusterTarantoolTupleClient(credentials, serverAddress)) { List resultList = client.eval("return box.session.user()").get(); String sessionUser = (String) resultList.get(0); @@ -198,7 +190,7 @@ public void testRandomNameUserWithoutPassword_shouldThrowException() throws Exce TarantoolCredentials credentials = new SimpleTarantoolCredentials( "RandomUserName", ""); TarantoolServerAddress serverAddress = new TarantoolServerAddress( - tarantoolContainer.getHost(), tarantoolContainer.getPort()); + container.getHost(), container.getPort()); try (ClusterTarantoolTupleClient client = new ClusterTarantoolTupleClient(credentials, serverAddress)) { ExecutionException e = assertThrows(ExecutionException.class, () -> { client.eval("return box.session.user()").get(); @@ -213,9 +205,9 @@ public void testRandomNameUserWithoutPassword_shouldThrowException() throws Exce public void testIncorrectHostname_shouldThrowException() { assertThrows(TarantoolClientException.class, () -> { TarantoolCredentials credentials = new SimpleTarantoolCredentials( - tarantoolContainer.getUsername(), tarantoolContainer.getPassword()); + container.getUsername(), container.getPassword()); TarantoolServerAddress serverAddress = new TarantoolServerAddress( - "wronghost", tarantoolContainer.getPort()); + "wronghost", container.getPort()); ClusterTarantoolTupleClient client = new ClusterTarantoolTupleClient(credentials, serverAddress); // Connection is actually performed here client.getVersion(); @@ -226,9 +218,9 @@ public void testIncorrectHostname_shouldThrowException() { public void testIncorrectPort_shouldThrowException() { assertThrows(TarantoolClientException.class, () -> { TarantoolCredentials credentials = new SimpleTarantoolCredentials( - tarantoolContainer.getUsername(), tarantoolContainer.getPassword()); + container.getUsername(), container.getPassword()); TarantoolServerAddress serverAddress = new TarantoolServerAddress( - tarantoolContainer.getHost(), 9999); + container.getHost(), 9999); ClusterTarantoolTupleClient client = new ClusterTarantoolTupleClient(credentials, serverAddress); // Connection is actually performed here client.getVersion(); @@ -238,9 +230,9 @@ public void testIncorrectPort_shouldThrowException() { @Test public void testCloseAfterIncorrectPort_shouldThrowException() { TarantoolCredentials credentials = new SimpleTarantoolCredentials( - tarantoolContainer.getUsername(), tarantoolContainer.getPassword()); + container.getUsername(), container.getPassword()); TarantoolServerAddress serverAddress = new TarantoolServerAddress( - tarantoolContainer.getHost(), 9999); + container.getHost(), 9999); assertThrows(TarantoolClientException.class, () -> { try (ClusterTarantoolTupleClient client = new ClusterTarantoolTupleClient(credentials, serverAddress)) { // Connection is actually performed here @@ -252,9 +244,9 @@ public void testCloseAfterIncorrectPort_shouldThrowException() { @Test public void testCloseAfterIncorrectPassword_shouldThrowException() { TarantoolCredentials credentials = new SimpleTarantoolCredentials( - tarantoolContainer.getUsername(), "incorrect"); + container.getUsername(), "incorrect"); TarantoolServerAddress serverAddress = new TarantoolServerAddress( - tarantoolContainer.getHost(), tarantoolContainer.getPort()); + container.getHost(), container.getPort()); assertThrows(TarantoolClientException.class, () -> { try (ClusterTarantoolTupleClient client = new ClusterTarantoolTupleClient(credentials, serverAddress)) { // Connection is actually performed here @@ -266,9 +258,9 @@ public void testCloseAfterIncorrectPassword_shouldThrowException() { @Test public void testIncorrectPassword_secondRequestShouldNotHang() { TarantoolCredentials credentials = new SimpleTarantoolCredentials( - tarantoolContainer.getUsername(), "incorrect"); + container.getUsername(), "incorrect"); TarantoolServerAddress serverAddress = new TarantoolServerAddress( - tarantoolContainer.getHost(), tarantoolContainer.getPort()); + container.getHost(), container.getPort()); assertThrows(TarantoolClientException.class, () -> { try (ClusterTarantoolTupleClient client = new ClusterTarantoolTupleClient(credentials, serverAddress)) { // Connection is actually performed here @@ -286,9 +278,9 @@ public void testIncorrectPassword_secondRequestShouldNotHang() { @Test public void testIncorrectPassword_multipleRequestsShouldNotHang() { TarantoolCredentials credentials = new SimpleTarantoolCredentials( - tarantoolContainer.getUsername(), "incorrect"); + container.getUsername(), "incorrect"); TarantoolServerAddress serverAddress = new TarantoolServerAddress( - "neverwhere", tarantoolContainer.getPort()); + "neverwhere", container.getPort()); TarantoolClientConfig config = TarantoolClientConfig.builder() .withConnectTimeout(100) .withRequestTimeout(100) @@ -322,10 +314,10 @@ public void testIncorrectPassword_multipleRequestsShouldNotHang() { @Test public void testClientClosing_clientWithoutConnectionsShouldNotHang() throws Exception { TarantoolCredentials credentials = new SimpleTarantoolCredentials( - tarantoolContainer.getUsername(), tarantoolContainer.getPassword()); + container.getUsername(), container.getPassword()); TarantoolServerAddress serverAddress = new TarantoolServerAddress( - tarantoolContainer.getHost(), tarantoolContainer.getPort()); + container.getHost(), container.getPort()); ClusterTarantoolTupleClient client = new ClusterTarantoolTupleClient(credentials, serverAddress); client.close(); diff --git a/src/test/java/io/tarantool/driver/integration/OffsetCursorIT.java b/src/test/java/io/tarantool/driver/integration/OffsetCursorIT.java index e529b1463..44da9c79e 100644 --- a/src/test/java/io/tarantool/driver/integration/OffsetCursorIT.java +++ b/src/test/java/io/tarantool/driver/integration/OffsetCursorIT.java @@ -1,27 +1,16 @@ package io.tarantool.driver.integration; -import io.tarantool.driver.api.TarantoolClient; -import io.tarantool.driver.api.TarantoolClientConfig; -import io.tarantool.driver.api.TarantoolResult; -import io.tarantool.driver.api.TarantoolServerAddress; import io.tarantool.driver.api.conditions.Conditions; import io.tarantool.driver.api.cursor.TarantoolCursor; import io.tarantool.driver.api.space.TarantoolSpaceOperations; import io.tarantool.driver.api.tuple.TarantoolTuple; -import io.tarantool.driver.auth.SimpleTarantoolCredentials; -import io.tarantool.driver.auth.TarantoolCredentials; -import io.tarantool.driver.core.ClusterTarantoolTupleClient; import io.tarantool.driver.core.tuple.TarantoolTupleImpl; import io.tarantool.driver.exceptions.TarantoolClientException; import io.tarantool.driver.exceptions.TarantoolSpaceOperationException; import io.tarantool.driver.mappers.factories.DefaultMessagePackMapperFactory; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.testcontainers.containers.TarantoolContainer; -import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import java.util.ArrayList; @@ -37,23 +26,16 @@ import static org.junit.jupiter.api.Assertions.fail; @Testcontainers -public class OffsetCursorIT { +public class OffsetCursorIT extends SharedTarantoolContainer { private static final String TEST_SPACE_NAME = "cursor_test_space"; private static final String TEST_MULTIPART_KEY_SPACE_NAME = "cursor_test_space_multi_part_key"; - private static final Logger log = LoggerFactory.getLogger(OffsetCursorIT.class); - - @Container - private static final TarantoolContainer tarantoolContainer = new TarantoolContainer() - .withScriptFileName("org/testcontainers/containers/server.lua"); - - private static TarantoolClient> client; private static final DefaultMessagePackMapperFactory mapperFactory = DefaultMessagePackMapperFactory.getInstance(); @BeforeAll public static void setUp() { - assertTrue(tarantoolContainer.isRunning()); + startContainer(); initClient(); try { @@ -73,25 +55,6 @@ public static void tearDown() throws Exception { assertThrows(TarantoolClientException.class, () -> client.metadata().getSpaceByName("_space")); } - private static void initClient() { - TarantoolCredentials credentials = new SimpleTarantoolCredentials( - tarantoolContainer.getUsername(), tarantoolContainer.getPassword()); - - TarantoolServerAddress serverAddress = new TarantoolServerAddress( - tarantoolContainer.getHost(), tarantoolContainer.getPort()); - - TarantoolClientConfig config = new TarantoolClientConfig.Builder() - .withCredentials(credentials) - .withConnectTimeout(1000 * 5) - .withReadTimeout(1000 * 5) - .withRequestTimeout(1000 * 5) - .build(); - - log.info("Attempting connect to Tarantool"); - client = new ClusterTarantoolTupleClient(config, serverAddress); - log.info("Successfully connected to Tarantool, version = {}", client.getVersion()); - } - private interface ElementGenerator { List generate(int index); } diff --git a/src/test/java/io/tarantool/driver/integration/SharedTarantoolContainer.java b/src/test/java/io/tarantool/driver/integration/SharedTarantoolContainer.java index 30b1b47fc..62987e6d2 100644 --- a/src/test/java/io/tarantool/driver/integration/SharedTarantoolContainer.java +++ b/src/test/java/io/tarantool/driver/integration/SharedTarantoolContainer.java @@ -5,9 +5,19 @@ import org.testcontainers.containers.TarantoolContainer; import org.testcontainers.containers.output.Slf4jLogConsumer; +import io.tarantool.driver.api.TarantoolClient; +import io.tarantool.driver.api.TarantoolClientConfig; +import io.tarantool.driver.api.TarantoolResult; +import io.tarantool.driver.api.TarantoolServerAddress; +import io.tarantool.driver.api.tuple.TarantoolTuple; +import io.tarantool.driver.auth.SimpleTarantoolCredentials; +import io.tarantool.driver.auth.TarantoolCredentials; +import io.tarantool.driver.core.ClusterTarantoolTupleClient; + abstract class SharedTarantoolContainer { private static final Logger logger = LoggerFactory.getLogger(SharedTarantoolContainer.class); + protected static TarantoolClient> client; protected static final String tarantoolVersion = System.getenv().get("TARANTOOL_VERSION"); protected static final TarantoolContainer container = @@ -22,4 +32,23 @@ protected static void startContainer() { container.start(); } } + + protected static void initClient() { + TarantoolCredentials credentials = new SimpleTarantoolCredentials( + container.getUsername(), container.getPassword()); + + TarantoolServerAddress serverAddress = new TarantoolServerAddress( + container.getHost(), container.getPort()); + + TarantoolClientConfig config = new TarantoolClientConfig.Builder() + .withCredentials(credentials) + .withConnectTimeout(1000 * 5) + .withReadTimeout(1000 * 5) + .withRequestTimeout(1000 * 5) + .build(); + + logger.info("Attempting connect to Tarantool"); + client = new ClusterTarantoolTupleClient(config, serverAddress); + logger.info("Successfully connected to Tarantool, version = {}", client.getVersion()); + } } From bc227aad09fc5ec34505f3f2dcaf5e41c3a3487c Mon Sep 17 00:00:00 2001 From: Artyom Dubinin Date: Sun, 2 Apr 2023 14:15:54 +0300 Subject: [PATCH 3/4] Remove 2.x from CI matrix --- .github/workflows/tests-ce.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests-ce.yml b/.github/workflows/tests-ce.yml index cd0a9dcd2..1d2811d3a 100644 --- a/.github/workflows/tests-ce.yml +++ b/.github/workflows/tests-ce.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - tarantool-version: [ "1.x", "2.10.6", "2.x" ] + tarantool-version: [ "1.x", "2.10.6"] fail-fast: false steps: - uses: actions/checkout@v2 From 9b561fe1b11bf8b0935e3970185a7c22f80474cc Mon Sep 17 00:00:00 2001 From: Artyom Dubinin Date: Sun, 2 Apr 2023 20:43:37 +0300 Subject: [PATCH 4/4] Fix changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 06579ca57..c67b35179 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ - Add deep copy instead of shallow copy in default message pack mapper ([#166](https://github.com/tarantool/cartridge-java/issues/166)) - Add a factory builder for constructing mapper hierarchies - Add "can convert value" check to TupleResultConverter -- Support Datetime type ([#293](https://github.com/tarantool/cartridge-java/pull/293)) +- Support Datetime type ([#214](https://github.com/tarantool/cartridge-java/pull/214)) ## [0.10.1] - 2023-01-13