Skip to content

Commit 6ff283a

Browse files
authored
[8.x] Add deprecation warning to TransportHandshaker (#123188) (#123627)
This PR adds a deprecation warning log to the TransportHandshaker when connecting with nodes < v8.19.
1 parent dc3275c commit 6ff283a

File tree

3 files changed

+88
-17
lines changed

3 files changed

+88
-17
lines changed

docs/changelog/123627.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
pr: 123627
2+
summary: Add deprecation warning to `TransportHandshaker`
3+
area: Infra/Core
4+
type: deprecation
5+
issues: []
6+
deprecation:
7+
title: Deprecate ability to connect to nodes of versions 8.18 and earlier
8+
area: REST API
9+
details: >
10+
Versions 9.1.0 and later of {es} will not support communication with nodes of versions earlier than 8.19.0,
11+
so the ability to connect to nodes of earlier versions is deprecated in this version. This applies both to
12+
communication within a cluster and communication across clusters (e.g. for <<modules-cross-cluster-search,{ccs}>> or
13+
<<xpack-ccr,{ccr}>>).
14+
15+
{es} will report in its <<deprecation-logging, deprecation logging>> each time it opens a connection to a node that
16+
will not be supported from version 9.1.0 onwards. You must upgrade all your clusters to version 8.19.0 or later
17+
before upgrading any of your clusters to 9.1.0 or later.
18+
impact: >
19+
Upgrade all of your clusters to at least 8.19.0 before upgrading any of them to 9.1.0 or later.

server/src/main/java/org/elasticsearch/transport/TransportHandshaker.java

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@
1818
import org.elasticsearch.common.io.stream.BytesStreamOutput;
1919
import org.elasticsearch.common.io.stream.StreamInput;
2020
import org.elasticsearch.common.io.stream.StreamOutput;
21+
import org.elasticsearch.common.logging.DeprecationCategory;
22+
import org.elasticsearch.common.logging.DeprecationLogger;
2123
import org.elasticsearch.common.metrics.CounterMetric;
24+
import org.elasticsearch.common.util.concurrent.ThreadContext;
2225
import org.elasticsearch.core.Strings;
2326
import org.elasticsearch.core.TimeValue;
2427
import org.elasticsearch.logging.LogManager;
@@ -161,6 +164,7 @@ final class TransportHandshaker {
161164
*/
162165

163166
private static final Logger logger = LogManager.getLogger(TransportHandshaker.class);
167+
private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(logger.getName());
164168

165169
static final TransportVersion V7_HANDSHAKE_VERSION = TransportVersion.fromId(6_08_00_99);
166170
static final TransportVersion V8_HANDSHAKE_VERSION = TransportVersion.fromId(7_17_00_99);
@@ -172,6 +176,7 @@ final class TransportHandshaker {
172176
);
173177

174178
static final String HANDSHAKE_ACTION_NAME = "internal:tcp/handshake";
179+
static final TransportVersion V8_19_FIRST_VERSION = TransportVersions.INITIAL_ELASTICSEARCH_8_19;
175180
private final ConcurrentMap<Long, HandshakeResponseHandler> pendingHandshakes = new ConcurrentHashMap<>();
176181
private final CounterMetric numHandshakes = new CounterMetric();
177182

@@ -249,7 +254,13 @@ void handleHandshake(TransportChannel channel, long requestId, StreamInput strea
249254
}
250255
channel.sendResponse(
251256
new HandshakeResponse(
252-
ensureCompatibleVersion(version, handshakeRequest.transportVersion, handshakeRequest.releaseVersion, channel),
257+
ensureCompatibleVersion(
258+
version,
259+
handshakeRequest.transportVersion,
260+
handshakeRequest.releaseVersion,
261+
channel,
262+
threadPool.getThreadContext()
263+
),
253264
Build.current().version()
254265
)
255266
);
@@ -258,10 +269,21 @@ void handleHandshake(TransportChannel channel, long requestId, StreamInput strea
258269
private static TransportVersion ensureCompatibleVersion(
259270
TransportVersion localTransportVersion,
260271
TransportVersion remoteTransportVersion,
261-
String releaseVersion,
262-
Object channel
272+
String remoteReleaseVersion,
273+
Object channel,
274+
ThreadContext threadContext
263275
) {
264276
if (TransportVersion.isCompatible(remoteTransportVersion)) {
277+
// Prevent log message headers from being added to the handshake response.
278+
try (var ignored = threadContext.stashContext()) {
279+
if (remoteTransportVersion.before(V8_19_FIRST_VERSION)) {
280+
deprecationLogger.warn(
281+
DeprecationCategory.OTHER,
282+
"handshake_version",
283+
getDeprecationMessage(localTransportVersion, remoteTransportVersion, remoteReleaseVersion, channel)
284+
);
285+
}
286+
}
265287
if (remoteTransportVersion.onOrAfter(localTransportVersion)) {
266288
// Remote is semantically newer than us (i.e. has a greater transport protocol version), so we propose using our current
267289
// transport protocol version. If we're initiating the connection then that's the version we'll use; if the other end is
@@ -282,7 +304,7 @@ private static TransportVersion ensureCompatibleVersion(
282304
from a chronologically-older release with a numerically-newer version compared to this node's version [{}/{}]. \
283305
Upgrading to a chronologically-older release may not work reliably and is not recommended. \
284306
Falling back to transport protocol version [{}].""",
285-
releaseVersion,
307+
remoteReleaseVersion,
286308
remoteTransportVersion,
287309
channel,
288310
Build.current().version(),
@@ -298,7 +320,7 @@ private static TransportVersion ensureCompatibleVersion(
298320
"""
299321
Rejecting unreadable transport handshake from remote node with version [%s/%s] received on [%s] since this node has \
300322
version [%s/%s] which has an incompatible wire format.""",
301-
releaseVersion,
323+
remoteReleaseVersion,
302324
remoteTransportVersion,
303325
channel,
304326
Build.current().version(),
@@ -309,6 +331,24 @@ private static TransportVersion ensureCompatibleVersion(
309331

310332
}
311333

334+
// Non-private for testing
335+
static String getDeprecationMessage(
336+
TransportVersion localTransportVersion,
337+
TransportVersion remoteTransportVersion,
338+
String remoteReleaseVersion,
339+
Object channel
340+
) {
341+
return Strings.format(
342+
"Performed a handshake with a remote node with version [%s/%s] received on [%s] which "
343+
+ "will be incompatible after this node on version [%s/%s] is upgraded to >= 9.1.",
344+
remoteReleaseVersion,
345+
remoteTransportVersion,
346+
channel,
347+
Build.current().version(),
348+
localTransportVersion
349+
);
350+
}
351+
312352
TransportResponseHandler<HandshakeResponse> removeHandlerForHandshake(long requestId) {
313353
return pendingHandshakes.remove(requestId);
314354
}
@@ -352,7 +392,8 @@ public void handleResponse(HandshakeResponse response) {
352392
version,
353393
response.getTransportVersion(),
354394
response.getReleaseVersion(),
355-
channel
395+
channel,
396+
threadPool.getThreadContext()
356397
);
357398
assert TransportVersion.current().before(version) // simulating a newer-version transport service for test purposes
358399
|| resultVersion.isKnown() : "negotiated unknown version " + resultVersion;

server/src/test/java/org/elasticsearch/transport/TransportHandshakerTests.java

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import java.util.concurrent.ExecutionException;
3333
import java.util.concurrent.TimeUnit;
3434

35+
import static org.elasticsearch.transport.TransportHandshaker.V8_19_FIRST_VERSION;
36+
import static org.elasticsearch.transport.TransportHandshaker.getDeprecationMessage;
3537
import static org.hamcrest.Matchers.allOf;
3638
import static org.hamcrest.Matchers.containsString;
3739
import static org.mockito.Mockito.doThrow;
@@ -101,10 +103,8 @@ public void testHandshakeRequestAndResponse() throws IOException {
101103

102104
@TestLogging(reason = "testing WARN logging", value = "org.elasticsearch.transport.TransportHandshaker:WARN")
103105
public void testIncompatibleHandshakeRequest() throws Exception {
104-
TransportHandshaker.HandshakeRequest handshakeRequest = new TransportHandshaker.HandshakeRequest(
105-
getRandomIncompatibleTransportVersion(),
106-
randomIdentifier()
107-
);
106+
var remoteVersion = getRandomIncompatibleTransportVersion();
107+
TransportHandshaker.HandshakeRequest handshakeRequest = new TransportHandshaker.HandshakeRequest(remoteVersion, randomIdentifier());
108108
BytesStreamOutput bytesStreamOutput = new BytesStreamOutput();
109109
bytesStreamOutput.setTransportVersion(HANDSHAKE_REQUEST_VERSION);
110110
handshakeRequest.writeTo(bytesStreamOutput);
@@ -149,7 +149,7 @@ public void testIncompatibleHandshakeRequest() throws Exception {
149149
handshakeRequest.transportVersion.bestKnownVersion(),
150150
asInstanceOf(TransportHandshaker.HandshakeResponse.class, responseFuture.result()).getTransportVersion()
151151
);
152-
152+
assertDeprecationMessageIsLogged(remoteVersion, remoteVersion.toReleaseVersion(), channel);
153153
} else {
154154
final TestTransportChannel channel = new TestTransportChannel(ActionListener.running(() -> fail("should not complete")));
155155

@@ -186,10 +186,13 @@ public void testHandshakeResponseFromOlderNode() throws Exception {
186186
assertFalse(versionFuture.isDone());
187187

188188
final var remoteVersion = TransportVersionUtils.randomCompatibleVersion(random());
189-
handler.handleResponse(new TransportHandshaker.HandshakeResponse(remoteVersion, randomIdentifier()));
189+
var releaseVersion = randomIdentifier();
190+
handler.handleResponse(new TransportHandshaker.HandshakeResponse(remoteVersion, releaseVersion));
190191

191192
assertTrue(versionFuture.isDone());
192193
assertEquals(remoteVersion, versionFuture.result());
194+
195+
assertDeprecationMessageIsLogged(remoteVersion, releaseVersion, channel);
193196
}
194197

195198
@TestLogging(reason = "testing WARN logging", value = "org.elasticsearch.transport.TransportHandshaker:WARN")
@@ -201,10 +204,11 @@ public void testHandshakeResponseFromOlderNodeWithPatchedProtocol() throws Excep
201204

202205
assertFalse(versionFuture.isDone());
203206

204-
final var randomIncompatibleTransportVersion = getRandomIncompatibleTransportVersion();
205-
final var handshakeResponse = new TransportHandshaker.HandshakeResponse(randomIncompatibleTransportVersion, randomIdentifier());
207+
var remoteVersion = getRandomIncompatibleTransportVersion();
208+
var releaseVersion = randomIdentifier();
209+
final var handshakeResponse = new TransportHandshaker.HandshakeResponse(remoteVersion, releaseVersion);
206210

207-
if (randomIncompatibleTransportVersion.onOrAfter(TransportVersions.MINIMUM_COMPATIBLE)) {
211+
if (remoteVersion.onOrAfter(TransportVersions.MINIMUM_COMPATIBLE)) {
208212
// we fall back to the best known version
209213
MockLog.assertThatLogger(
210214
() -> handler.handleResponse(handshakeResponse),
@@ -223,13 +227,13 @@ public void testHandshakeResponseFromOlderNodeWithPatchedProtocol() throws Excep
223227
handshakeResponse.getTransportVersion(),
224228
Build.current().version(),
225229
TransportVersion.current(),
226-
randomIncompatibleTransportVersion.bestKnownVersion()
230+
remoteVersion.bestKnownVersion()
227231
)
228232
)
229233
);
230234

231235
assertTrue(versionFuture.isDone());
232-
assertEquals(randomIncompatibleTransportVersion.bestKnownVersion(), versionFuture.result());
236+
assertEquals(remoteVersion.bestKnownVersion(), versionFuture.result());
233237
} else {
234238
MockLog.assertThatLogger(
235239
() -> handler.handleResponse(handshakeResponse),
@@ -253,6 +257,13 @@ public void testHandshakeResponseFromOlderNodeWithPatchedProtocol() throws Excep
253257
)
254258
);
255259
}
260+
assertDeprecationMessageIsLogged(remoteVersion, releaseVersion, channel);
261+
}
262+
263+
private void assertDeprecationMessageIsLogged(TransportVersion remoteVersion, String remoteReleaseVersion, Object channel) {
264+
if (remoteVersion.onOrAfter(TransportVersions.MINIMUM_COMPATIBLE) && remoteVersion.before(V8_19_FIRST_VERSION)) {
265+
assertWarnings(getDeprecationMessage(TransportVersion.current(), remoteVersion, remoteReleaseVersion, channel));
266+
}
256267
}
257268

258269
private static TransportVersion getRandomIncompatibleTransportVersion() {

0 commit comments

Comments
 (0)