Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added "mode" option for crud select operation #416

Merged
merged 2 commits into from
Sep 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## [Unreleased]

### API changes
ArtDu marked this conversation as resolved.
Show resolved Hide resolved
- Add "mode" option for crud select operation ([#107](https://github.com/tarantool/cartridge-java/issues/107))

### Bugfixes
- Fix Instant converter to parse 8 bytes datetime ([#408](https://github.com/tarantool/cartridge-java/issues/408))

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package io.tarantool.driver.api.space.options;

import io.tarantool.driver.api.space.options.enums.crud.Mode;

import java.util.Optional;

/**
* Base interface for all operation options that may have a configurable mode.
*
* @author Belonogov Nikolay
*/
public interface OperationWithModeOptions<T extends OperationWithModeOptions<T>> extends Options, Self<T> {
String MODE = "mode";

/**
* Specifies the mode for operations (select, count, get) on a specific node type (mode == "write" - master, mode
* == "read" - replica). By default, mode is "read".
*
* @param mode mode for operations (select, get, count).
* @return this options instance.
*/
default T withMode(Mode mode) {
addOption(MODE, mode.value());
return self();
}

/**
* Return operation mode.
*
* @return mode.
*/
default Optional<Mode> getMode() {
return getOption(MODE, Mode.class);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
* @author Alexey Kuzin
*/
public interface SelectOptions<T extends SelectOptions<T>>
extends OperationWithBucketIdOptions<T>, OperationWithTimeoutOptions<T>, OperationWithFieldsOptions<T> {
extends OperationWithBucketIdOptions<T>, OperationWithTimeoutOptions<T>, OperationWithFieldsOptions<T>,
OperationWithModeOptions<T> {
/**
* Return the internal size of batch for transferring data between
* storage and router nodes.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package io.tarantool.driver.api.space.options.enums.crud;

/**
* Enum represents the CRUD predefined mode option values.
*
* @author Belonogov Nikolay.
* @see <a href="https://github.com/tarantool/crud">tarantool/crud</a>.
*/
public enum Mode {
WRITE("write"),
READ("read");

private final String value;

Mode(String value) {
this.value = value;
}

public String value() {
return this.value;
}

@Override
public String toString() {
return this.value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* Contains enums for CRUD option values.
*
* @author Belonogov Nikolay
*/
package io.tarantool.driver.api.space.options.enums.crud;
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ final class CRUDSelectOptions extends CRUDBucketIdOptions {
public static final String SELECT_AFTER = "after";
public static final String SELECT_BATCH_SIZE = "batch_size";
public static final String FIELDS = "fields";
public static final String MODE = "mode";

private <B extends AbstractBuilder<B>> CRUDSelectOptions(AbstractBuilder<B> builder) {
super(builder);
Expand All @@ -28,6 +29,7 @@ private <B extends AbstractBuilder<B>> CRUDSelectOptions(AbstractBuilder<B> buil
addOption(SELECT_AFTER, builder.after);
addOption(SELECT_BATCH_SIZE, builder.selectBatchSize);
addOption(FIELDS, builder.fields);
addOption(MODE, builder.mode);
}

/**
Expand All @@ -41,6 +43,7 @@ protected abstract static class AbstractBuilder<B extends AbstractBuilder<B>>
private Optional<Packable> after = Optional.empty();
private Optional<Integer> selectBatchSize = Optional.empty();
private Optional<List> fields = Optional.empty();
private Optional<String> mode = Optional.empty();

public B withSelectLimit(Optional<Long> selectLimit) {
this.selectLimit = selectLimit;
Expand All @@ -61,6 +64,11 @@ public B withFields(Optional<List> fields) {
this.fields = fields;
return self();
}

public B withMode(Optional<String> mode) {
this.mode = mode;
return self();
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ public SelectProxyOperation<T> build() {
.withSelectLimit(Optional.of(conditions.getLimit()))
.withSelectAfter(Optional.ofNullable(conditions.getStartTuple()))
.withBucketId(options.getBucketId())
.withFields(options.getFields());
.withFields(options.getFields())
.withMode(options.getMode());

List<?> arguments = Arrays.asList(
spaceName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.tarantool.driver.api.SingleValueCallResult;
import io.tarantool.driver.api.TarantoolResult;
import io.tarantool.driver.api.conditions.Conditions;
import io.tarantool.driver.api.space.options.enums.crud.Mode;
import io.tarantool.driver.api.space.options.proxy.ProxyDeleteOptions;
import io.tarantool.driver.api.space.options.proxy.ProxyInsertManyOptions;
import io.tarantool.driver.api.space.options.proxy.ProxyInsertOptions;
Expand All @@ -24,7 +25,6 @@
import io.tarantool.driver.mappers.TarantoolTupleResultMapperFactory;
import io.tarantool.driver.mappers.TarantoolTupleResultMapperFactoryImpl;
import io.tarantool.driver.mappers.factories.DefaultMessagePackMapperFactory;
import io.tarantool.driver.mappers.factories.ResultMapperFactoryFactoryImpl;
import io.tarantool.driver.protocol.TarantoolIndexQuery;
import org.junit.jupiter.api.Test;

Expand All @@ -42,13 +42,13 @@ public class ProxyOperationBuildersTest {
private static final ClusterTarantoolTupleClient client = new ClusterTarantoolTupleClient();
private final MessagePackMapper defaultMapper =
DefaultMessagePackMapperFactory.getInstance().defaultComplexTypesMapper();
private final TarantoolTupleFactory factory = new DefaultTarantoolTupleFactory(defaultMapper);
TarantoolTupleResultMapperFactory tarantoolTupleResultMapperFactory =
TarantoolTupleResultMapperFactoryImpl.getInstance();
private final
CallResultMapper<TarantoolResult<TarantoolTuple>, SingleValueCallResult<TarantoolResult<TarantoolTuple>>>
defaultResultMapper = tarantoolTupleResultMapperFactory
.withSingleValueArrayToTarantoolTupleResultMapper(defaultMapper, null);
private final TarantoolTupleFactory factory = new DefaultTarantoolTupleFactory(defaultMapper);

@Test
public void deleteOperationBuilderTest() {
Expand Down Expand Up @@ -221,13 +221,15 @@ public void selectOperationBuilderTest() {
.withOptions(ProxySelectOptions.create()
.withTimeout(client.getConfig().getRequestTimeout())
.withBatchSize(123456)
.withMode(Mode.WRITE)
)
.build();

Map<String, Object> options = new HashMap<>();
options.put(CRUDBaseOptions.TIMEOUT, client.getConfig().getRequestTimeout());
options.put(CRUDSelectOptions.SELECT_BATCH_SIZE, 123456);
options.put(CRUDSelectOptions.SELECT_LIMIT, 100L);
options.put(CRUDSelectOptions.MODE, Mode.WRITE.value());

assertEquals(client, op.getClient());
assertEquals("function1", op.getFunctionName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
import io.tarantool.driver.api.TarantoolResult;
import io.tarantool.driver.api.conditions.Conditions;
import io.tarantool.driver.api.space.TarantoolSpaceOperations;
import io.tarantool.driver.api.space.options.proxy.ProxySelectOptions;
import io.tarantool.driver.api.space.options.SelectOptions;
import io.tarantool.driver.api.space.options.enums.crud.Mode;
import io.tarantool.driver.api.space.options.proxy.ProxySelectOptions;
import io.tarantool.driver.api.tuple.DefaultTarantoolTupleFactory;
import io.tarantool.driver.api.tuple.TarantoolTuple;
import io.tarantool.driver.api.tuple.TarantoolTupleFactory;
Expand All @@ -24,25 +25,21 @@
import java.util.List;
import java.util.concurrent.ExecutionException;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.*;

/**
* @author Artyom Dubinin
*/
public class ProxySpaceSelectOptionsIT extends SharedCartridgeContainer {

private static TarantoolClient<TarantoolTuple, TarantoolResult<TarantoolTuple>> client;
private static final DefaultMessagePackMapperFactory mapperFactory = DefaultMessagePackMapperFactory.getInstance();
private static final TarantoolTupleFactory tupleFactory =
new DefaultTarantoolTupleFactory(mapperFactory.defaultComplexTypesMapper());

public static String USER_NAME;
public static String PASSWORD;

private static final String TEST_SPACE_NAME = "test__profile";
private static final String PK_FIELD_NAME = "profile_id";
public static String USER_NAME;
public static String PASSWORD;
private static TarantoolClient<TarantoolTuple, TarantoolResult<TarantoolTuple>> client;

@BeforeAll
public static void setUp() throws Exception {
Expand All @@ -53,26 +50,24 @@ public static void setUp() throws Exception {
}

private static void initClient() {
TarantoolClientConfig config = TarantoolClientConfig.builder()
.withCredentials(new SimpleTarantoolCredentials(USER_NAME, PASSWORD))
.withConnectTimeout(1000)
.withReadTimeout(1000)
.build();

ClusterTarantoolTupleClient clusterClient = new ClusterTarantoolTupleClient(
config, container.getRouterHost(), container.getRouterPort());
TarantoolClientConfig config =
TarantoolClientConfig.builder().withCredentials(new SimpleTarantoolCredentials(USER_NAME, PASSWORD))
.withConnectTimeout(1000).withReadTimeout(1000).build();

ClusterTarantoolTupleClient clusterClient =
new ClusterTarantoolTupleClient(config, container.getRouterHost(), container.getRouterPort());
client = new ProxyTarantoolTupleClient(clusterClient);
}

private static void truncateSpace(String spaceName) {
client.space(spaceName).truncate().join();
}

@BeforeEach
public void truncateSpace() {
truncateSpace(TEST_SPACE_NAME);
}

private static void truncateSpace(String spaceName) {
client.space(spaceName).truncate().join();
}

@Test
public void withBatchSizeTest() throws ExecutionException, InterruptedException {
TarantoolSpaceOperations<TarantoolTuple, TarantoolResult<TarantoolTuple>> profileSpace =
Expand All @@ -94,17 +89,14 @@ public void withBatchSizeTest() throws ExecutionException, InterruptedException
assertNull(((HashMap) crudSelectOpts.get(0)).get("batch_size"));

// with batchSize
selectResult = profileSpace.select(
conditions,
ProxySelectOptions.create().withBatchSize(5)
).get();
selectResult = profileSpace.select(conditions, ProxySelectOptions.create().withBatchSize(5)).get();
assertEquals(10, selectResult.size());
crudSelectOpts = client.eval("return crud_select_opts").get();
assertEquals(5, ((HashMap) crudSelectOpts.get(0)).get("batch_size"));
}

@Test
public void withTimeout() throws ExecutionException, InterruptedException {
public void withTimeoutTest() throws ExecutionException, InterruptedException {
TarantoolSpaceOperations<TarantoolTuple, TarantoolResult<TarantoolTuple>> profileSpace =
client.space(TEST_SPACE_NAME);

Expand All @@ -116,26 +108,20 @@ public void withTimeout() throws ExecutionException, InterruptedException {
List<?> crudSelectOpts = client.eval("return crud_select_opts").get();
assertNull(((HashMap) crudSelectOpts.get(0)).get("timeout"));

profileSpace.select(
Conditions.any(),
ProxySelectOptions.create()
).get();
profileSpace.select(Conditions.any(), ProxySelectOptions.create()).get();
crudSelectOpts = client.eval("return crud_select_opts").get();
assertNull(((HashMap) crudSelectOpts.get(0)).get("timeout"));

// with option timeout
profileSpace.select(
Conditions.any(),
ProxySelectOptions.create().withTimeout(customRequestTimeout)
).get();
profileSpace.select(Conditions.any(), ProxySelectOptions.create().withTimeout(customRequestTimeout)).get();
crudSelectOpts = client.eval("return crud_select_opts").get();
assertEquals(customRequestTimeout, ((HashMap) crudSelectOpts.get(0)).get("timeout"));
}

@Test
public void withFieldsTest() throws ExecutionException, InterruptedException {
TarantoolSpaceOperations<TarantoolTuple, TarantoolResult<TarantoolTuple>> profileSpace =
client.space(TEST_SPACE_NAME);
client.space(TEST_SPACE_NAME);

TarantoolTuple tarantoolTuple;

Expand Down Expand Up @@ -167,4 +153,23 @@ public void withFieldsTest() throws ExecutionException, InterruptedException {
assertEquals(1, tuple.getInteger("profile_id"));
assertEquals(50, tuple.getInteger("age"));
}

@Test
public void withModeTest() throws ExecutionException, InterruptedException {
TarantoolSpaceOperations<TarantoolTuple, TarantoolResult<TarantoolTuple>> operations =
client.space(TEST_SPACE_NAME);

operations.select(Conditions.any()).get();
List<?> crudSelectOpts = client.eval("return crud_select_opts").get();
assertNull(((HashMap<?, ?>) crudSelectOpts.get(0)).get("mode"));

int customTimeout = 2000;
operations.select(Conditions.any(), ProxySelectOptions.create().withTimeout(customTimeout)).get();
crudSelectOpts = client.eval("return crud_select_opts").get();
assertNull(((HashMap<?, ?>) crudSelectOpts.get(0)).get("mode"));

operations.select(Conditions.any(), ProxySelectOptions.create().withMode(Mode.WRITE)).get();
crudSelectOpts = client.eval("return crud_select_opts").get();
assertEquals(Mode.WRITE.value(), ((HashMap<?, ?>) crudSelectOpts.get(0)).get("mode"));
}
}
Loading