Skip to content

Commit

Permalink
Implement request signatures
Browse files Browse the repository at this point in the history
  • Loading branch information
akudiyar committed Aug 12, 2023
1 parent 8c6919f commit 7747033
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import io.tarantool.driver.mappers.factories.ResultMapperFactoryFactoryImpl;
import io.tarantool.driver.protocol.Packable;
import io.tarantool.driver.protocol.TarantoolProtocolException;
import io.tarantool.driver.protocol.TarantoolRequestSignature;
import io.tarantool.driver.protocol.requests.TarantoolCallRequest;
import io.tarantool.driver.protocol.requests.TarantoolEvalRequest;
import io.tarantool.driver.utils.Assert;
Expand Down Expand Up @@ -472,6 +473,15 @@ private <T> CompletableFuture<CallResult<T>> makeRequestForSingleResult(
return makeRequest(functionName, arguments, argumentsMapper, resultMapper);
}

private <T> CompletableFuture<CallResult<T>> makeRequestForSingleResult(
String functionName,
List<?> arguments,
TarantoolRequestSignature requestSignature,
MessagePackObjectMapper argumentsMapper,
CallResultMapper<T, SingleValueCallResult<T>> resultMapper) {
return makeRequest(functionName, arguments, requestSignature, argumentsMapper, resultMapper);
}

private <T, R extends List<T>> CompletableFuture<CallResult<R>> makeRequestForMultiResult(
String functionName,
List<?> arguments,
Expand All @@ -480,9 +490,28 @@ private <T, R extends List<T>> CompletableFuture<CallResult<R>> makeRequestForMu
return makeRequest(functionName, arguments, argumentsMapper, resultMapper);
}

private <T, R extends List<T>> CompletableFuture<CallResult<R>> makeRequestForMultiResult(
String functionName,
List<?> arguments,
TarantoolRequestSignature requestSignature,
MessagePackObjectMapper argumentsMapper,
CallResultMapper<R, MultiValueCallResult<T, R>> resultMapper) {
return makeRequest(functionName, arguments, argumentsMapper, resultMapper);
}

private <S> CompletableFuture<S> makeRequest(
String functionName,
List<?> arguments,
MessagePackObjectMapper argumentsMapper,
MessagePackValueMapper resultMapper)
throws TarantoolClientException {
return makeRequest(functionName, arguments, null, argumentsMapper, resultMapper);
}

private <S> CompletableFuture<S> makeRequest(
String functionName,
List<?> arguments,
TarantoolRequestSignature requestSignature,
MessagePackObjectMapper argumentsMapper,
MessagePackValueMapper resultMapper)
throws TarantoolClientException {
Expand All @@ -493,6 +522,7 @@ private <S> CompletableFuture<S> makeRequest(
if (arguments.size() > 0) {
builder.withArguments(arguments);
}
builder.withSignature(requestSignature);

TarantoolCallRequest request = builder.build(argumentsMapper);
return connectionManager().getConnection()
Expand Down
40 changes: 35 additions & 5 deletions src/main/java/io/tarantool/driver/protocol/TarantoolRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.msgpack.core.MessagePacker;

import java.io.IOException;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Supplier;

Expand All @@ -16,25 +17,28 @@
*
* @author Alexey Kuzin
*/
public class TarantoolRequest {
public abstract class TarantoolRequest {

private static final AtomicLong syncId = new AtomicLong(0);
private static final Supplier<Long> syncIdSupplier =
() -> syncId.updateAndGet(n -> (n >= Long.MAX_VALUE) ? 1 : n + 1);

private final TarantoolHeader header;
private final TarantoolRequestBody body;
private final Optional<TarantoolRequestSignature> signature;

/**
* Basic constructor. Sets an auto-incremented request ID into the Tarantool packet header.
*
* @param type request type code supported by Tarantool
* @param body request body, may be empty
* @param type request type code supported by Tarantool
* @param body request body, may be empty
* @param signature request signature, may be null
* @see TarantoolRequestType
*/
public TarantoolRequest(TarantoolRequestType type, TarantoolRequestBody body) {
public TarantoolRequest(TarantoolRequestType type, TarantoolRequestBody body, TarantoolRequestSignature signature) {
this.header = new TarantoolHeader(syncIdSupplier.get(), type.getCode());
this.body = body;
this.signature = Optional.of(signature);
}

/**
Expand All @@ -51,10 +55,19 @@ public TarantoolHeader getHeader() {
*
* @return instance of a {@link Packable}
*/
public Packable getBody() {
public TarantoolRequestBody getBody() {
return body;
}

/**
* Get signature
*
* @return request signature that uniquely represents the operation and argument types
*/
public Optional<TarantoolRequestSignature> getSignature() {
return signature;
}

/**
* Encode incapsulated data using {@link MessagePacker}
*
Expand All @@ -71,4 +84,21 @@ public void toMessagePack(MessagePacker packer, MessagePackObjectMapper mapper)
throw new TarantoolDecoderException(header, e);
}
}

/**
* Base class for request builder implementations
*/
public static abstract class Builder<B extends Builder> {
protected TarantoolRequestSignature signature;

/**
* Set request signature
*
* @param signature request signature
*/
public B withSignature(TarantoolRequestSignature signature) {
this.signature = signature;
return this;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package io.tarantool.driver.protocol;

import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

/**
* Represents a request signature, uniquely defining the operation and the argument types.
* May include some argument values as well.
*
* @author Alexey Kuzin
*/
public class TarantoolRequestSignature {

private List<Object> components = new LinkedList<>();
private int hashCode = 1;

/**
* Constructor.
*
* @param initialComponents initial signature components, must be hashable
*/
public TarantoolRequestSignature(Object... initialComponents) {
for (Object component: initialComponents) {
components.add(component);
hashCode = 31 * hashCode + Objects.hashCode(component);
}
}

/**
* Add a signature component to the end of the components list
*
* @param component signature component, must be hashable
* @return this signature object instance
*/
public TarantoolRequestSignature addComponent(Object component) {
components.add(component);
hashCode = 31 * hashCode + Objects.hashCode(component);
return this;
}

@Override
public int hashCode() {
return hashCode;
}

@Override
public boolean equals(Object other) {
return other instanceof TarantoolRequestSignature &&
Objects.equals(this.components, ((TarantoolRequestSignature) other).components);
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder("[");
for (Object component: components) {
sb.append(String.valueOf(component)).append(",");
}
sb.append("]");
return sb.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
import io.tarantool.driver.protocol.TarantoolRequest;
import io.tarantool.driver.protocol.TarantoolRequestBody;
import io.tarantool.driver.protocol.TarantoolRequestFieldType;
import io.tarantool.driver.protocol.TarantoolRequestSignature;
import io.tarantool.driver.protocol.TarantoolRequestType;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* Call request.
Expand All @@ -20,14 +22,14 @@
*/
public final class TarantoolCallRequest extends TarantoolRequest {

private TarantoolCallRequest(TarantoolRequestBody body) {
super(TarantoolRequestType.IPROTO_CALL, body);
private TarantoolCallRequest(TarantoolRequestBody body, TarantoolRequestSignature signature) {
super(TarantoolRequestType.IPROTO_CALL, body, signature);
}

/**
* Tarantool call request builder
*/
public static class Builder {
public static class Builder extends TarantoolRequest.Builder<Builder> {

Map<Integer, Object> bodyMap;

Expand Down Expand Up @@ -69,7 +71,7 @@ public TarantoolCallRequest build(MessagePackObjectMapper mapper) throws Taranto
throw new TarantoolProtocolException("Function name must be specified in the call request");
}

return new TarantoolCallRequest(new TarantoolRequestBody(bodyMap, mapper));
return new TarantoolCallRequest(new TarantoolRequestBody(bodyMap, mapper), signature);
}
}
}

0 comments on commit 7747033

Please sign in to comment.