All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.tarantool.driver.ProxyTarantoolClient Maven / Gradle / Ivy

Go to download

Tarantool Cartridge driver for Tarantool versions 1.10+ based on Netty framework

There is a newer version: 0.14.0
Show newest version
package io.tarantool.driver;

import io.tarantool.driver.api.TarantoolClient;
import io.tarantool.driver.api.TarantoolResult;
import io.tarantool.driver.api.TarantoolTupleFactory;
import io.tarantool.driver.api.space.ProxyTarantoolSpace;
import io.tarantool.driver.api.space.TarantoolSpaceOperations;
import io.tarantool.driver.core.TarantoolConnectionListeners;
import io.tarantool.driver.exceptions.TarantoolClientException;
import io.tarantool.driver.exceptions.TarantoolSpaceNotFoundException;
import io.tarantool.driver.mappers.MessagePackMapper;
import io.tarantool.driver.mappers.MessagePackObjectMapper;
import io.tarantool.driver.mappers.MessagePackValueMapper;
import io.tarantool.driver.mappers.TarantoolCallResultMapper;
import io.tarantool.driver.mappers.ValueConverter;
import io.tarantool.driver.metadata.TarantoolMetadataOperations;
import io.tarantool.driver.metadata.TarantoolSpaceMetadata;
import io.tarantool.driver.proxy.ProxyOperationsMapping;
import io.tarantool.driver.metadata.ProxyTarantoolMetadata;
import org.msgpack.value.ArrayValue;
import org.springframework.util.Assert;

import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Client implementation that decorates a {@link TarantoolClient} instance, proxying all CRUD operations through the
 * instance's call method to the proxy functions defined on the Tarantool instance(s).
 *
 * Proxy functions to be called can be specified by overriding the methods of the implemented
 * {@link ProxyOperationsMapping} interface. These functions must be public API functions available on the Tarantool
 * instance fro the connected API user.
 *
 * It is recommended to use this client with the CRUD module (
 * https://github.com/tarantool/crud) installed on the target Tarantool instance.
 *
 * See 
 *     https://github.com/tarantool/examples/blob/master/profile-storage/README.md
 *
 * @author Alexey Kuzin
 * @author Sergey Volgin
 */
public class ProxyTarantoolClient implements TarantoolClient, ProxyOperationsMapping {

    private final TarantoolClient client;
    private final AtomicReference metadataHolder = new AtomicReference<>();

    public ProxyTarantoolClient(TarantoolClient decoratedClient) {
        this.client = decoratedClient;
        this.client.getListeners().clear();
        this.client.getListeners().add(connection -> {
            try {
                return metadata().refresh().thenApply(v -> connection);
            } catch (Throwable e) {
                throw new CompletionException(e);
            }
        });
    }

    @Override
    public TarantoolSpaceOperations space(int spaceId) throws TarantoolClientException {
        Assert.state(spaceId > 0, "Space ID must be greater than 0");

        TarantoolMetadataOperations metadata = this.metadata();
        Optional meta = metadata.getSpaceById(spaceId);
        if (!meta.isPresent()) {
            throw new TarantoolSpaceNotFoundException(spaceId);
        }

        return new ProxyTarantoolSpace(this, meta.get());
    }

    @Override
    public TarantoolClientConfig getConfig() {
        return client.getConfig();
    }

    @Override
    public TarantoolVersion getVersion() throws TarantoolClientException {
        return client.getVersion();
    }

    @Override
    public TarantoolSpaceOperations space(String spaceName) {
        Assert.hasText(spaceName, "Space name must not be null or empty");

        TarantoolMetadataOperations metadata = this.metadata();
        Optional meta = metadata.getSpaceByName(spaceName);
        if (!meta.isPresent()) {
            throw new TarantoolSpaceNotFoundException(spaceName);
        }

        return new ProxyTarantoolSpace(this, meta.get());
    }

    @Override
    public TarantoolMetadataOperations metadata() throws TarantoolClientException {
        if (metadataHolder.get() == null) {
            this.metadataHolder.compareAndSet(
                    null, new ProxyTarantoolMetadata(this.getGetSchemaFunctionName(), this));
        }
        return metadataHolder.get();
    }

    @Override
    public TarantoolConnectionListeners getListeners() {
        return this.client.getListeners();
    }

    @Override
    public TarantoolTupleFactory getTarantoolTupleFactory() {
        return this.client.getTarantoolTupleFactory();
    }

    @Override
    public CompletableFuture> call(String functionName) throws TarantoolClientException {
        return client.call(functionName);
    }

    @Override
    public CompletableFuture> call(String functionName, List arguments)
            throws TarantoolClientException {
        return client.call(functionName, arguments);
    }

    @Override
    public CompletableFuture> call(String functionName, List arguments, MessagePackMapper mapper)
            throws TarantoolClientException {
        return client.call(functionName, arguments, mapper);
    }

    @Override
    public  CompletableFuture> call(String functionName, Class entityClass)
            throws TarantoolClientException {
        return client.call(functionName, entityClass);
    }

    @Override
    public  CompletableFuture> call(String functionName,
                                                          ValueConverter tupleMapper)
            throws TarantoolClientException {
        return client.call(functionName, tupleMapper);
    }

    @Override
    public  CompletableFuture> call(String functionName,
                                                          List arguments,
                                                          Class entityClass) throws TarantoolClientException {
        return client.call(functionName, arguments, entityClass);
    }

    @Override
    public  CompletableFuture> call(String functionName,
                                                          List arguments,
                                                          ValueConverter tupleMapper)
            throws TarantoolClientException {
        return client.call(functionName, arguments, tupleMapper);
    }

    @Override
    public  CompletableFuture> call(String functionName,
                                                          List arguments,
                                                          MessagePackObjectMapper argumentsMapper,
                                                          Class entityClass) throws TarantoolClientException {
        return client.call(functionName, arguments, argumentsMapper, entityClass);
    }

    @Override
    public  CompletableFuture> call(String functionName,
                                                          List arguments,
                                                          MessagePackObjectMapper argumentsMapper,
                                                          ValueConverter tupleMapper)
            throws TarantoolClientException {
        return client.call(functionName, arguments, argumentsMapper, tupleMapper);
    }

    @Override
    public  CompletableFuture> call(String functionName,
                                                          List arguments,
                                                          MessagePackObjectMapper argumentsMapper,
                                                          TarantoolCallResultMapper resultMapper)
            throws TarantoolClientException {
        return client.call(functionName, arguments, argumentsMapper, resultMapper);
    }

    @Override
    public CompletableFuture> eval(String expression) throws TarantoolClientException {
        return client.eval(expression);
    }

    @Override
    public CompletableFuture> eval(String expression, List arguments)
            throws TarantoolClientException {
        return client.eval(expression, arguments);
    }

    @Override
    public CompletableFuture> eval(String expression, MessagePackValueMapper resultMapper)
            throws TarantoolClientException {
        return client.eval(expression, resultMapper);
    }

    @Override
    public CompletableFuture> eval(String expression,
                                                List arguments,
                                                MessagePackValueMapper resultMapper) throws TarantoolClientException {
        return client.eval(expression, arguments, resultMapper);
    }

    @Override
    public CompletableFuture> eval(String expression,
                                                List arguments,
                                                MessagePackObjectMapper argumentsMapper,
                                                MessagePackValueMapper resultMapper) throws TarantoolClientException {
        return client.eval(expression, arguments, argumentsMapper, resultMapper);
    }

    @Override
    public void close() throws Exception {
        this.client.close();
    }
}