Add version to handshake requests (#36171)
Currently our handshake requests do not include a version. This is unfortunate as we cannot rely on the stream version since it is not the sending node's version. Instead it is the minimum compatibility version. The handshake request is currently empty and we do nothing with it. This should allow us to add data to the request without breaking backwards compatibility. This commit adds the version to the handshake request. Additionally, it allows "future data" to be added to the request. This allows nodes to craft a version compatible response. And will properly handle additional data in future handshake requests. The proper handling of "future data" is useful as this is the only request where we do not know the other node's version. Finally, it renames the TcpTransportHandshaker to TransportHandshaker.
This commit is contained in:
parent
55743aac47
commit
797f985067
|
@ -132,7 +132,13 @@ class ByteBufStreamInput extends StreamInput {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte readByte() throws IOException {
|
public byte readByte() throws IOException {
|
||||||
return buffer.readByte();
|
try {
|
||||||
|
return buffer.readByte();
|
||||||
|
} catch (IndexOutOfBoundsException ex) {
|
||||||
|
EOFException eofException = new EOFException();
|
||||||
|
eofException.initCause(ex);
|
||||||
|
throw eofException;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -238,7 +238,13 @@ class ByteBufUtils {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte readByte() throws IOException {
|
public byte readByte() throws IOException {
|
||||||
return buffer.readByte();
|
try {
|
||||||
|
return buffer.readByte();
|
||||||
|
} catch (IndexOutOfBoundsException ex) {
|
||||||
|
EOFException eofException = new EOFException();
|
||||||
|
eofException.initCause(ex);
|
||||||
|
throw eofException;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -204,7 +204,7 @@ public abstract class TcpTransport extends AbstractLifecycleComponent implements
|
||||||
private volatile Map<String, RequestHandlerRegistry<? extends TransportRequest>> requestHandlers = Collections.emptyMap();
|
private volatile Map<String, RequestHandlerRegistry<? extends TransportRequest>> requestHandlers = Collections.emptyMap();
|
||||||
private final ResponseHandlers responseHandlers = new ResponseHandlers();
|
private final ResponseHandlers responseHandlers = new ResponseHandlers();
|
||||||
private final TransportLogger transportLogger;
|
private final TransportLogger transportLogger;
|
||||||
private final TcpTransportHandshaker handshaker;
|
private final TransportHandshaker handshaker;
|
||||||
private final TransportKeepAlive keepAlive;
|
private final TransportKeepAlive keepAlive;
|
||||||
private final String nodeName;
|
private final String nodeName;
|
||||||
|
|
||||||
|
@ -224,12 +224,12 @@ public abstract class TcpTransport extends AbstractLifecycleComponent implements
|
||||||
this.networkService = networkService;
|
this.networkService = networkService;
|
||||||
this.transportName = transportName;
|
this.transportName = transportName;
|
||||||
this.transportLogger = new TransportLogger();
|
this.transportLogger = new TransportLogger();
|
||||||
this.handshaker = new TcpTransportHandshaker(version, threadPool,
|
this.handshaker = new TransportHandshaker(version, threadPool,
|
||||||
(node, channel, requestId, v) -> sendRequestToChannel(node, channel, requestId,
|
(node, channel, requestId, v) -> sendRequestToChannel(node, channel, requestId,
|
||||||
TcpTransportHandshaker.HANDSHAKE_ACTION_NAME, TransportRequest.Empty.INSTANCE, TransportRequestOptions.EMPTY, v,
|
TransportHandshaker.HANDSHAKE_ACTION_NAME, new TransportHandshaker.HandshakeRequest(version),
|
||||||
TransportStatus.setHandshake((byte) 0)),
|
TransportRequestOptions.EMPTY, v, TransportStatus.setHandshake((byte) 0)),
|
||||||
(v, features, channel, response, requestId) -> sendResponse(v, features, channel, response, requestId,
|
(v, features, channel, response, requestId) -> sendResponse(v, features, channel, response, requestId,
|
||||||
TcpTransportHandshaker.HANDSHAKE_ACTION_NAME, TransportResponseOptions.EMPTY, TransportStatus.setHandshake((byte) 0)));
|
TransportHandshaker.HANDSHAKE_ACTION_NAME, TransportResponseOptions.EMPTY, TransportStatus.setHandshake((byte) 0)));
|
||||||
this.keepAlive = new TransportKeepAlive(threadPool, this::internalSendMessage);
|
this.keepAlive = new TransportKeepAlive(threadPool, this::internalSendMessage);
|
||||||
this.nodeName = Node.NODE_NAME_SETTING.get(settings);
|
this.nodeName = Node.NODE_NAME_SETTING.get(settings);
|
||||||
|
|
||||||
|
@ -1287,7 +1287,7 @@ public abstract class TcpTransport extends AbstractLifecycleComponent implements
|
||||||
TransportChannel transportChannel = null;
|
TransportChannel transportChannel = null;
|
||||||
try {
|
try {
|
||||||
if (TransportStatus.isHandshake(status)) {
|
if (TransportStatus.isHandshake(status)) {
|
||||||
handshaker.handleHandshake(version, features, channel, requestId);
|
handshaker.handleHandshake(version, features, channel, requestId, stream);
|
||||||
} else {
|
} else {
|
||||||
final RequestHandlerRegistry reg = getRequestHandler(action);
|
final RequestHandlerRegistry reg = getRequestHandler(action);
|
||||||
if (reg == null) {
|
if (reg == null) {
|
||||||
|
|
|
@ -21,12 +21,15 @@ package org.elasticsearch.transport;
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
import org.elasticsearch.action.ActionListener;
|
import org.elasticsearch.action.ActionListener;
|
||||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||||
|
import org.elasticsearch.common.bytes.BytesReference;
|
||||||
|
import org.elasticsearch.common.io.stream.BytesStreamOutput;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.metrics.CounterMetric;
|
import org.elasticsearch.common.metrics.CounterMetric;
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
|
|
||||||
|
import java.io.EOFException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
@ -37,7 +40,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
* Sends and receives transport-level connection handshakes. This class will send the initial handshake,
|
* Sends and receives transport-level connection handshakes. This class will send the initial handshake,
|
||||||
* manage state/timeouts while the handshake is in transit, and handle the eventual response.
|
* manage state/timeouts while the handshake is in transit, and handle the eventual response.
|
||||||
*/
|
*/
|
||||||
final class TcpTransportHandshaker {
|
final class TransportHandshaker {
|
||||||
|
|
||||||
static final String HANDSHAKE_ACTION_NAME = "internal:tcp/handshake";
|
static final String HANDSHAKE_ACTION_NAME = "internal:tcp/handshake";
|
||||||
private final ConcurrentMap<Long, HandshakeResponseHandler> pendingHandshakes = new ConcurrentHashMap<>();
|
private final ConcurrentMap<Long, HandshakeResponseHandler> pendingHandshakes = new ConcurrentHashMap<>();
|
||||||
|
@ -48,8 +51,8 @@ final class TcpTransportHandshaker {
|
||||||
private final HandshakeRequestSender handshakeRequestSender;
|
private final HandshakeRequestSender handshakeRequestSender;
|
||||||
private final HandshakeResponseSender handshakeResponseSender;
|
private final HandshakeResponseSender handshakeResponseSender;
|
||||||
|
|
||||||
TcpTransportHandshaker(Version version, ThreadPool threadPool, HandshakeRequestSender handshakeRequestSender,
|
TransportHandshaker(Version version, ThreadPool threadPool, HandshakeRequestSender handshakeRequestSender,
|
||||||
HandshakeResponseSender handshakeResponseSender) {
|
HandshakeResponseSender handshakeResponseSender) {
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.threadPool = threadPool;
|
this.threadPool = threadPool;
|
||||||
this.handshakeRequestSender = handshakeRequestSender;
|
this.handshakeRequestSender = handshakeRequestSender;
|
||||||
|
@ -83,11 +86,19 @@ final class TcpTransportHandshaker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleHandshake(Version version, Set<String> features, TcpChannel channel, long requestId) throws IOException {
|
void handleHandshake(Version version, Set<String> features, TcpChannel channel, long requestId, StreamInput stream) throws IOException {
|
||||||
handshakeResponseSender.sendResponse(version, features, channel, new VersionHandshakeResponse(this.version), requestId);
|
// Must read the handshake request to exhaust the stream
|
||||||
|
HandshakeRequest handshakeRequest = new HandshakeRequest(stream);
|
||||||
|
final int nextByte = stream.read();
|
||||||
|
if (nextByte != -1) {
|
||||||
|
throw new IllegalStateException("Handshake request not fully read for requestId [" + requestId + "], action ["
|
||||||
|
+ TransportHandshaker.HANDSHAKE_ACTION_NAME + "], available [" + stream.available() + "]; resetting");
|
||||||
|
}
|
||||||
|
HandshakeResponse response = new HandshakeResponse(this.version);
|
||||||
|
handshakeResponseSender.sendResponse(version, features, channel, response, requestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
TransportResponseHandler<VersionHandshakeResponse> removeHandlerForHandshake(long requestId) {
|
TransportResponseHandler<HandshakeResponse> removeHandlerForHandshake(long requestId) {
|
||||||
return pendingHandshakes.remove(requestId);
|
return pendingHandshakes.remove(requestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +110,7 @@ final class TcpTransportHandshaker {
|
||||||
return numHandshakes.count();
|
return numHandshakes.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class HandshakeResponseHandler implements TransportResponseHandler<VersionHandshakeResponse> {
|
private class HandshakeResponseHandler implements TransportResponseHandler<HandshakeResponse> {
|
||||||
|
|
||||||
private final long requestId;
|
private final long requestId;
|
||||||
private final Version currentVersion;
|
private final Version currentVersion;
|
||||||
|
@ -113,14 +124,14 @@ final class TcpTransportHandshaker {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VersionHandshakeResponse read(StreamInput in) throws IOException {
|
public HandshakeResponse read(StreamInput in) throws IOException {
|
||||||
return new VersionHandshakeResponse(in);
|
return new HandshakeResponse(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleResponse(VersionHandshakeResponse response) {
|
public void handleResponse(HandshakeResponse response) {
|
||||||
if (isDone.compareAndSet(false, true)) {
|
if (isDone.compareAndSet(false, true)) {
|
||||||
Version version = response.version;
|
Version version = response.responseVersion;
|
||||||
if (currentVersion.isCompatible(version) == false) {
|
if (currentVersion.isCompatible(version) == false) {
|
||||||
listener.onFailure(new IllegalStateException("Received message from unsupported version: [" + version
|
listener.onFailure(new IllegalStateException("Received message from unsupported version: [" + version
|
||||||
+ "] minimal compatible version is: [" + currentVersion.minimumCompatibilityVersion() + "]"));
|
+ "] minimal compatible version is: [" + currentVersion.minimumCompatibilityVersion() + "]"));
|
||||||
|
@ -149,24 +160,75 @@ final class TcpTransportHandshaker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static final class VersionHandshakeResponse extends TransportResponse {
|
static final class HandshakeRequest extends TransportRequest {
|
||||||
|
|
||||||
private final Version version;
|
private final Version version;
|
||||||
|
|
||||||
VersionHandshakeResponse(Version version) {
|
HandshakeRequest(Version version) {
|
||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
private VersionHandshakeResponse(StreamInput in) throws IOException {
|
HandshakeRequest(StreamInput streamInput) throws IOException {
|
||||||
|
super(streamInput);
|
||||||
|
BytesReference remainingMessage;
|
||||||
|
try {
|
||||||
|
remainingMessage = streamInput.readBytesReference();
|
||||||
|
} catch (EOFException e) {
|
||||||
|
remainingMessage = null;
|
||||||
|
}
|
||||||
|
if (remainingMessage == null) {
|
||||||
|
version = null;
|
||||||
|
} else {
|
||||||
|
try (StreamInput messageStreamInput = remainingMessage.streamInput()) {
|
||||||
|
this.version = Version.readVersion(messageStreamInput);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readFrom(StreamInput in) {
|
||||||
|
throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTo(StreamOutput streamOutput) throws IOException {
|
||||||
|
super.writeTo(streamOutput);
|
||||||
|
assert version != null;
|
||||||
|
try (BytesStreamOutput messageStreamOutput = new BytesStreamOutput(4)) {
|
||||||
|
Version.writeVersion(version, messageStreamOutput);
|
||||||
|
BytesReference reference = messageStreamOutput.bytes();
|
||||||
|
streamOutput.writeBytesReference(reference);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static final class HandshakeResponse extends TransportResponse {
|
||||||
|
|
||||||
|
private final Version responseVersion;
|
||||||
|
|
||||||
|
HandshakeResponse(Version responseVersion) {
|
||||||
|
this.responseVersion = responseVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
private HandshakeResponse(StreamInput in) throws IOException {
|
||||||
super.readFrom(in);
|
super.readFrom(in);
|
||||||
version = Version.readVersion(in);
|
responseVersion = Version.readVersion(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readFrom(StreamInput in) {
|
||||||
|
throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeTo(StreamOutput out) throws IOException {
|
public void writeTo(StreamOutput out) throws IOException {
|
||||||
super.writeTo(out);
|
super.writeTo(out);
|
||||||
assert version != null;
|
assert responseVersion != null;
|
||||||
Version.writeVersion(version, out);
|
Version.writeVersion(responseVersion, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
Version getResponseVersion() {
|
||||||
|
return responseVersion;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,4 @@ public final class TransportStatus {
|
||||||
value |= STATUS_HANDSHAKE;
|
value |= STATUS_HANDSHAKE;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,10 @@ package org.elasticsearch.transport;
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
import org.elasticsearch.action.support.PlainActionFuture;
|
import org.elasticsearch.action.support.PlainActionFuture;
|
||||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||||
|
import org.elasticsearch.common.io.stream.BytesStreamOutput;
|
||||||
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
|
import org.elasticsearch.tasks.TaskId;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.threadpool.TestThreadPool;
|
import org.elasticsearch.threadpool.TestThreadPool;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
|
@ -38,24 +41,24 @@ import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
public class TransportHandshakerTests extends ESTestCase {
|
public class TransportHandshakerTests extends ESTestCase {
|
||||||
|
|
||||||
private TcpTransportHandshaker handshaker;
|
private TransportHandshaker handshaker;
|
||||||
private DiscoveryNode node;
|
private DiscoveryNode node;
|
||||||
private TcpChannel channel;
|
private TcpChannel channel;
|
||||||
private TestThreadPool threadPool;
|
private TestThreadPool threadPool;
|
||||||
private TcpTransportHandshaker.HandshakeRequestSender requestSender;
|
private TransportHandshaker.HandshakeRequestSender requestSender;
|
||||||
private TcpTransportHandshaker.HandshakeResponseSender responseSender;
|
private TransportHandshaker.HandshakeResponseSender responseSender;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
String nodeId = "node-id";
|
String nodeId = "node-id";
|
||||||
channel = mock(TcpChannel.class);
|
channel = mock(TcpChannel.class);
|
||||||
requestSender = mock(TcpTransportHandshaker.HandshakeRequestSender.class);
|
requestSender = mock(TransportHandshaker.HandshakeRequestSender.class);
|
||||||
responseSender = mock(TcpTransportHandshaker.HandshakeResponseSender.class);
|
responseSender = mock(TransportHandshaker.HandshakeResponseSender.class);
|
||||||
node = new DiscoveryNode(nodeId, nodeId, nodeId, "host", "host_address", buildNewFakeTransportAddress(), Collections.emptyMap(),
|
node = new DiscoveryNode(nodeId, nodeId, nodeId, "host", "host_address", buildNewFakeTransportAddress(), Collections.emptyMap(),
|
||||||
Collections.emptySet(), Version.CURRENT);
|
Collections.emptySet(), Version.CURRENT);
|
||||||
threadPool = new TestThreadPool("thread-poll");
|
threadPool = new TestThreadPool("thread-poll");
|
||||||
handshaker = new TcpTransportHandshaker(Version.CURRENT, threadPool, requestSender, responseSender);
|
handshaker = new TransportHandshaker(Version.CURRENT, threadPool, requestSender, responseSender);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -74,20 +77,63 @@ public class TransportHandshakerTests extends ESTestCase {
|
||||||
assertFalse(versionFuture.isDone());
|
assertFalse(versionFuture.isDone());
|
||||||
|
|
||||||
TcpChannel mockChannel = mock(TcpChannel.class);
|
TcpChannel mockChannel = mock(TcpChannel.class);
|
||||||
handshaker.handleHandshake(Version.CURRENT, Collections.emptySet(), mockChannel, reqId);
|
TransportHandshaker.HandshakeRequest handshakeRequest = new TransportHandshaker.HandshakeRequest(Version.CURRENT);
|
||||||
|
BytesStreamOutput bytesStreamOutput = new BytesStreamOutput();
|
||||||
|
handshakeRequest.writeTo(bytesStreamOutput);
|
||||||
|
StreamInput input = bytesStreamOutput.bytes().streamInput();
|
||||||
|
handshaker.handleHandshake(Version.CURRENT, Collections.emptySet(), mockChannel, reqId, input);
|
||||||
|
|
||||||
|
|
||||||
ArgumentCaptor<TransportResponse> responseCaptor = ArgumentCaptor.forClass(TransportResponse.class);
|
ArgumentCaptor<TransportResponse> responseCaptor = ArgumentCaptor.forClass(TransportResponse.class);
|
||||||
verify(responseSender).sendResponse(eq(Version.CURRENT), eq(Collections.emptySet()), eq(mockChannel), responseCaptor.capture(),
|
verify(responseSender).sendResponse(eq(Version.CURRENT), eq(Collections.emptySet()), eq(mockChannel), responseCaptor.capture(),
|
||||||
eq(reqId));
|
eq(reqId));
|
||||||
|
|
||||||
TransportResponseHandler<TcpTransportHandshaker.VersionHandshakeResponse> handler = handshaker.removeHandlerForHandshake(reqId);
|
TransportResponseHandler<TransportHandshaker.HandshakeResponse> handler = handshaker.removeHandlerForHandshake(reqId);
|
||||||
handler.handleResponse((TcpTransportHandshaker.VersionHandshakeResponse) responseCaptor.getValue());
|
handler.handleResponse((TransportHandshaker.HandshakeResponse) responseCaptor.getValue());
|
||||||
|
|
||||||
assertTrue(versionFuture.isDone());
|
assertTrue(versionFuture.isDone());
|
||||||
assertEquals(Version.CURRENT, versionFuture.actionGet());
|
assertEquals(Version.CURRENT, versionFuture.actionGet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testHandshakeRequestFutureVersionsCompatibility() throws IOException {
|
||||||
|
long reqId = randomLongBetween(1, 10);
|
||||||
|
handshaker.sendHandshake(reqId, node, channel, new TimeValue(30, TimeUnit.SECONDS), PlainActionFuture.newFuture());
|
||||||
|
|
||||||
|
verify(requestSender).sendRequest(node, channel, reqId, Version.CURRENT.minimumCompatibilityVersion());
|
||||||
|
|
||||||
|
TcpChannel mockChannel = mock(TcpChannel.class);
|
||||||
|
TransportHandshaker.HandshakeRequest handshakeRequest = new TransportHandshaker.HandshakeRequest(Version.CURRENT);
|
||||||
|
BytesStreamOutput currentHandshakeBytes = new BytesStreamOutput();
|
||||||
|
handshakeRequest.writeTo(currentHandshakeBytes);
|
||||||
|
|
||||||
|
BytesStreamOutput lengthCheckingHandshake = new BytesStreamOutput();
|
||||||
|
BytesStreamOutput futureHandshake = new BytesStreamOutput();
|
||||||
|
TaskId.EMPTY_TASK_ID.writeTo(lengthCheckingHandshake);
|
||||||
|
TaskId.EMPTY_TASK_ID.writeTo(futureHandshake);
|
||||||
|
try (BytesStreamOutput internalMessage = new BytesStreamOutput()) {
|
||||||
|
Version.writeVersion(Version.CURRENT, internalMessage);
|
||||||
|
lengthCheckingHandshake.writeBytesReference(internalMessage.bytes());
|
||||||
|
internalMessage.write(new byte[1024]);
|
||||||
|
futureHandshake.writeBytesReference(internalMessage.bytes());
|
||||||
|
}
|
||||||
|
StreamInput futureHandshakeStream = futureHandshake.bytes().streamInput();
|
||||||
|
// We check that the handshake we serialize for this test equals the actual request.
|
||||||
|
// Otherwise, we need to update the test.
|
||||||
|
assertEquals(currentHandshakeBytes.bytes().length(), lengthCheckingHandshake.bytes().length());
|
||||||
|
assertEquals(1031, futureHandshakeStream.available());
|
||||||
|
handshaker.handleHandshake(Version.CURRENT, Collections.emptySet(), mockChannel, reqId, futureHandshakeStream);
|
||||||
|
assertEquals(0, futureHandshakeStream.available());
|
||||||
|
|
||||||
|
|
||||||
|
ArgumentCaptor<TransportResponse> responseCaptor = ArgumentCaptor.forClass(TransportResponse.class);
|
||||||
|
verify(responseSender).sendResponse(eq(Version.CURRENT), eq(Collections.emptySet()), eq(mockChannel), responseCaptor.capture(),
|
||||||
|
eq(reqId));
|
||||||
|
|
||||||
|
TransportHandshaker.HandshakeResponse response = (TransportHandshaker.HandshakeResponse) responseCaptor.getValue();
|
||||||
|
|
||||||
|
assertEquals(Version.CURRENT, response.getResponseVersion());
|
||||||
|
}
|
||||||
|
|
||||||
public void testHandshakeError() throws IOException {
|
public void testHandshakeError() throws IOException {
|
||||||
PlainActionFuture<Version> versionFuture = PlainActionFuture.newFuture();
|
PlainActionFuture<Version> versionFuture = PlainActionFuture.newFuture();
|
||||||
long reqId = randomLongBetween(1, 10);
|
long reqId = randomLongBetween(1, 10);
|
||||||
|
@ -97,7 +143,7 @@ public class TransportHandshakerTests extends ESTestCase {
|
||||||
|
|
||||||
assertFalse(versionFuture.isDone());
|
assertFalse(versionFuture.isDone());
|
||||||
|
|
||||||
TransportResponseHandler<TcpTransportHandshaker.VersionHandshakeResponse> handler = handshaker.removeHandlerForHandshake(reqId);
|
TransportResponseHandler<TransportHandshaker.HandshakeResponse> handler = handshaker.removeHandlerForHandshake(reqId);
|
||||||
handler.handleException(new TransportException("failed"));
|
handler.handleException(new TransportException("failed"));
|
||||||
|
|
||||||
assertTrue(versionFuture.isDone());
|
assertTrue(versionFuture.isDone());
|
||||||
|
@ -113,7 +159,6 @@ public class TransportHandshakerTests extends ESTestCase {
|
||||||
|
|
||||||
handshaker.sendHandshake(reqId, node, channel, new TimeValue(30, TimeUnit.SECONDS), versionFuture);
|
handshaker.sendHandshake(reqId, node, channel, new TimeValue(30, TimeUnit.SECONDS), versionFuture);
|
||||||
|
|
||||||
|
|
||||||
assertTrue(versionFuture.isDone());
|
assertTrue(versionFuture.isDone());
|
||||||
ConnectTransportException cte = expectThrows(ConnectTransportException.class, versionFuture::actionGet);
|
ConnectTransportException cte = expectThrows(ConnectTransportException.class, versionFuture::actionGet);
|
||||||
assertThat(cte.getMessage(), containsString("failure to send internal:tcp/handshake"));
|
assertThat(cte.getMessage(), containsString("failure to send internal:tcp/handshake"));
|
||||||
|
|
|
@ -2382,7 +2382,7 @@ public abstract class AbstractSimpleTransportTestCase extends ESTestCase {
|
||||||
assertEquals(1, transportStats.getRxCount());
|
assertEquals(1, transportStats.getRxCount());
|
||||||
assertEquals(1, transportStats.getTxCount());
|
assertEquals(1, transportStats.getTxCount());
|
||||||
assertEquals(25, transportStats.getRxSize().getBytes());
|
assertEquals(25, transportStats.getRxSize().getBytes());
|
||||||
assertEquals(45, transportStats.getTxSize().getBytes());
|
assertEquals(50, transportStats.getTxSize().getBytes());
|
||||||
});
|
});
|
||||||
serviceC.sendRequest(connection, "internal:action", new TestRequest("hello world"), TransportRequestOptions.EMPTY,
|
serviceC.sendRequest(connection, "internal:action", new TestRequest("hello world"), TransportRequestOptions.EMPTY,
|
||||||
transportResponseHandler);
|
transportResponseHandler);
|
||||||
|
@ -2392,7 +2392,7 @@ public abstract class AbstractSimpleTransportTestCase extends ESTestCase {
|
||||||
assertEquals(1, transportStats.getRxCount());
|
assertEquals(1, transportStats.getRxCount());
|
||||||
assertEquals(2, transportStats.getTxCount());
|
assertEquals(2, transportStats.getTxCount());
|
||||||
assertEquals(25, transportStats.getRxSize().getBytes());
|
assertEquals(25, transportStats.getRxSize().getBytes());
|
||||||
assertEquals(101, transportStats.getTxSize().getBytes());
|
assertEquals(106, transportStats.getTxSize().getBytes());
|
||||||
});
|
});
|
||||||
sendResponseLatch.countDown();
|
sendResponseLatch.countDown();
|
||||||
responseLatch.await();
|
responseLatch.await();
|
||||||
|
@ -2400,7 +2400,7 @@ public abstract class AbstractSimpleTransportTestCase extends ESTestCase {
|
||||||
assertEquals(2, stats.getRxCount());
|
assertEquals(2, stats.getRxCount());
|
||||||
assertEquals(2, stats.getTxCount());
|
assertEquals(2, stats.getTxCount());
|
||||||
assertEquals(46, stats.getRxSize().getBytes());
|
assertEquals(46, stats.getRxSize().getBytes());
|
||||||
assertEquals(101, stats.getTxSize().getBytes());
|
assertEquals(106, stats.getTxSize().getBytes());
|
||||||
} finally {
|
} finally {
|
||||||
serviceC.close();
|
serviceC.close();
|
||||||
}
|
}
|
||||||
|
@ -2497,7 +2497,7 @@ public abstract class AbstractSimpleTransportTestCase extends ESTestCase {
|
||||||
assertEquals(1, transportStats.getRxCount());
|
assertEquals(1, transportStats.getRxCount());
|
||||||
assertEquals(1, transportStats.getTxCount());
|
assertEquals(1, transportStats.getTxCount());
|
||||||
assertEquals(25, transportStats.getRxSize().getBytes());
|
assertEquals(25, transportStats.getRxSize().getBytes());
|
||||||
assertEquals(45, transportStats.getTxSize().getBytes());
|
assertEquals(50, transportStats.getTxSize().getBytes());
|
||||||
});
|
});
|
||||||
serviceC.sendRequest(connection, "internal:action", new TestRequest("hello world"), TransportRequestOptions.EMPTY,
|
serviceC.sendRequest(connection, "internal:action", new TestRequest("hello world"), TransportRequestOptions.EMPTY,
|
||||||
transportResponseHandler);
|
transportResponseHandler);
|
||||||
|
@ -2507,7 +2507,7 @@ public abstract class AbstractSimpleTransportTestCase extends ESTestCase {
|
||||||
assertEquals(1, transportStats.getRxCount());
|
assertEquals(1, transportStats.getRxCount());
|
||||||
assertEquals(2, transportStats.getTxCount());
|
assertEquals(2, transportStats.getTxCount());
|
||||||
assertEquals(25, transportStats.getRxSize().getBytes());
|
assertEquals(25, transportStats.getRxSize().getBytes());
|
||||||
assertEquals(101, transportStats.getTxSize().getBytes());
|
assertEquals(106, transportStats.getTxSize().getBytes());
|
||||||
});
|
});
|
||||||
sendResponseLatch.countDown();
|
sendResponseLatch.countDown();
|
||||||
responseLatch.await();
|
responseLatch.await();
|
||||||
|
@ -2522,7 +2522,7 @@ public abstract class AbstractSimpleTransportTestCase extends ESTestCase {
|
||||||
// 49 bytes are the non-exception message bytes that have been received. It should include the initial
|
// 49 bytes are the non-exception message bytes that have been received. It should include the initial
|
||||||
// handshake message and the header, version, etc bytes in the exception message.
|
// handshake message and the header, version, etc bytes in the exception message.
|
||||||
assertEquals(failedMessage, 49 + streamOutput.bytes().length(), stats.getRxSize().getBytes());
|
assertEquals(failedMessage, 49 + streamOutput.bytes().length(), stats.getRxSize().getBytes());
|
||||||
assertEquals(101, stats.getTxSize().getBytes());
|
assertEquals(106, stats.getTxSize().getBytes());
|
||||||
} finally {
|
} finally {
|
||||||
serviceC.close();
|
serviceC.close();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue