
io.tarantool.driver.AbstractTarantoolClient Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cartridge-driver Show documentation
Show all versions of cartridge-driver Show documentation
Tarantool Cartridge driver for Tarantool versions 1.10+ based on Netty framework
package io.tarantool.driver;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.tarantool.driver.api.TarantoolClient;
import io.tarantool.driver.api.TarantoolResult;
import io.tarantool.driver.api.TarantoolTupleFactory;
import io.tarantool.driver.api.space.TarantoolSpace;
import io.tarantool.driver.api.space.TarantoolSpaceOperations;
import io.tarantool.driver.core.TarantoolConnectionFactory;
import io.tarantool.driver.core.TarantoolConnectionListeners;
import io.tarantool.driver.core.TarantoolConnectionManager;
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.TarantoolCallResultMapperFactory;
import io.tarantool.driver.mappers.ValueConverter;
import io.tarantool.driver.metadata.TarantoolMetadata;
import io.tarantool.driver.metadata.TarantoolMetadataOperations;
import io.tarantool.driver.metadata.TarantoolSpaceMetadata;
import io.tarantool.driver.protocol.TarantoolProtocolException;
import io.tarantool.driver.protocol.requests.TarantoolCallRequest;
import io.tarantool.driver.protocol.requests.TarantoolEvalRequest;
import org.msgpack.value.ArrayValue;
import org.springframework.util.Assert;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.atomic.AtomicReference;
/**
* Basic Tarantool client implementation. Subclasses must provide the connection manager.
*
* @author Alexey Kuzin
*/
public abstract class AbstractTarantoolClient implements TarantoolClient {
private final NioEventLoopGroup eventLoopGroup;
private final TarantoolClientConfig config;
private final Bootstrap bootstrap;
private final TarantoolConnectionFactory connectionFactory;
private final TarantoolConnectionListeners listeners;
private final AtomicReference connectionManagerHolder = new AtomicReference<>();
private final AtomicReference metadataHolder = new AtomicReference<>();
private final TarantoolCallResultMapperFactory mapperFactory;
private final DefaultTarantoolTupleFactory tupleFactory;
/**
* Create a client.
* @param config the client configuration
* @see TarantoolClientConfig
*/
protected AbstractTarantoolClient(TarantoolClientConfig config) {
this(config, new TarantoolConnectionListeners());
}
/**
* Create a client, specifying the connection established event listeners.
* @param listeners connection established event listeners
* @param config the client configuration
* @see TarantoolClientConfig
*/
protected AbstractTarantoolClient(TarantoolClientConfig config, TarantoolConnectionListeners listeners) {
Assert.notNull(config, "Tarantool client config must not be null");
Assert.notNull(listeners, "Tarantool connection listeners must not be null");
this.config = config;
this.mapperFactory = new TarantoolCallResultMapperFactory(config.getMessagePackMapper());
this.eventLoopGroup = new NioEventLoopGroup();
this.bootstrap = new Bootstrap()
.group(eventLoopGroup)
.channel(NioSocketChannel.class)
.option(ChannelOption.SO_REUSEADDR, true)
.option(ChannelOption.SO_KEEPALIVE, true)
.option(ChannelOption.TCP_NODELAY, true)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, config.getConnectTimeout());
this.connectionFactory = new TarantoolConnectionFactory(config, getBootstrap());
listeners.add(connection -> {
try {
return metadata().refresh().thenApply(v -> connection);
} catch (Throwable e) {
throw new CompletionException(e);
}
});
this.listeners = listeners;
this.tupleFactory = new DefaultTarantoolTupleFactory(config.getMessagePackMapper());
}
/**
* Provides a connection manager for Tarantool server connections
* @param config contains Tarantool client configuration options
* @param connectionFactory provides helper methods for connection instantiation
* @param listeners listeners which will be invoked once all connections are established
* @return connection manager
*/
protected abstract TarantoolConnectionManager connectionManager(TarantoolClientConfig config,
TarantoolConnectionFactory connectionFactory,
TarantoolConnectionListeners listeners);
private TarantoolConnectionManager connectionManager() {
if (this.connectionManagerHolder.get() == null) {
this.connectionManagerHolder.compareAndSet(null, connectionManager(config, connectionFactory, listeners));
}
return connectionManagerHolder.get();
}
@Override
public TarantoolVersion getVersion() throws TarantoolClientException {
return connectionManager().getConnection().getVersion();
}
@Override
public TarantoolSpaceOperations space(String spaceName) throws TarantoolClientException {
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 TarantoolSpace(config, connectionManager(), meta.get(), metadata);
}
@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 TarantoolSpace(config, connectionManager(), meta.get(), metadata());
}
@Override
public TarantoolMetadataOperations metadata() throws TarantoolClientException {
if (metadataHolder.get() == null) {
this.metadataHolder.compareAndSet(null, new TarantoolMetadata(config, connectionManager()));
}
return metadataHolder.get();
}
@Override
public CompletableFuture> call(String functionName) throws TarantoolClientException {
return call(functionName, Collections.emptyList());
}
@Override
public CompletableFuture> call(String functionName, List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy