You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@druid.apache.org by ab...@apache.org on 2023/02/26 15:53:40 UTC
[druid] branch master updated: Make leader redirection work when both plainText and TLS ports are set (#13847)
This is an automated email from the ASF dual-hosted git repository.
abhishek pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/master by this push:
new 48f4330100 Make leader redirection work when both plainText and TLS ports are set (#13847)
48f4330100 is described below
commit 48f4330100e73be5dbf85c3002eaf0d4e5224e63
Author: Abhishek Agarwal <14...@users.noreply.github.com>
AuthorDate: Sun Feb 26 21:23:29 2023 +0530
Make leader redirection work when both plainText and TLS ports are set (#13847)
When both plainText and TLS ports are set in druid, the redirection to a different leader node can fail. This is caused by how we compare a redirect path and the leader locations registered with a druid node. While the registered location has both plainText and TLS port set, the redirect path only has one port since it's a URI.
---
.../java/org/apache/druid/rpc/ServiceClientImpl.java | 19 +++++++++++++------
.../org/apache/druid/rpc/ServiceClientImplTest.java | 20 ++++++++++++++++++++
2 files changed, 33 insertions(+), 6 deletions(-)
diff --git a/server/src/main/java/org/apache/druid/rpc/ServiceClientImpl.java b/server/src/main/java/org/apache/druid/rpc/ServiceClientImpl.java
index eca2cfdc5a..98191b3e13 100644
--- a/server/src/main/java/org/apache/druid/rpc/ServiceClientImpl.java
+++ b/server/src/main/java/org/apache/druid/rpc/ServiceClientImpl.java
@@ -301,8 +301,7 @@ public class ServiceClientImpl implements ServiceClient
);
} else if (serviceLocations.getLocations()
.stream()
- .anyMatch(loc -> serviceLocationNoPath(loc)
- .equals(redirectLocationNoPath))) {
+ .anyMatch(loc -> serviceLocationMatches(loc, redirectLocationNoPath))) {
// Valid redirect, to a server that is one of the known locations.
final boolean isRedirectLoop = redirectLocations.contains(newUri);
final boolean isRedirectChainTooLong = redirectLocations.size() >= MAX_REDIRECTS;
@@ -415,7 +414,7 @@ public class ServiceClientImpl implements ServiceClient
if (preferred != null) {
// Preferred location is set. Use it if it's one of known locations.
for (final ServiceLocation location : locations.getLocations()) {
- if (serviceLocationNoPath(location).equals(preferred)) {
+ if (serviceLocationMatches(location, preferred)) {
return location;
}
}
@@ -511,11 +510,19 @@ public class ServiceClientImpl implements ServiceClient
}
/**
- * Returns a {@link ServiceLocation} without its path.
+ * Returns true if two service locations are same or false otherwise. If a port is negative, we ignore that
+ * port for comparison.
*/
- static ServiceLocation serviceLocationNoPath(final ServiceLocation location)
+ static boolean serviceLocationMatches(final ServiceLocation left, final ServiceLocation right)
{
- return new ServiceLocation(location.getHost(), location.getPlaintextPort(), location.getTlsPort(), "");
+ return left.getHost().equals(right.getHost())
+ && portMatches(left.getPlaintextPort(), right.getPlaintextPort())
+ && portMatches(left.getTlsPort(), right.getTlsPort());
+ }
+
+ static boolean portMatches(int left, int right)
+ {
+ return left < 0 || right < 0 || left == right;
}
@VisibleForTesting
diff --git a/server/src/test/java/org/apache/druid/rpc/ServiceClientImplTest.java b/server/src/test/java/org/apache/druid/rpc/ServiceClientImplTest.java
index dc8bba87d1..20487aeac8 100644
--- a/server/src/test/java/org/apache/druid/rpc/ServiceClientImplTest.java
+++ b/server/src/test/java/org/apache/druid/rpc/ServiceClientImplTest.java
@@ -70,6 +70,8 @@ public class ServiceClientImplTest
private static final ServiceLocation SERVER3 = new ServiceLocation("example.com", -1, 1111, "/q");
private static final ServiceLocation SERVER4 = new ServiceLocation("example.com", -1, 2222, "/q");
private static final ServiceLocation SERVER5 = new ServiceLocation("example.com", -1, 3333, "/q");
+ private static final ServiceLocation SERVER6 = new ServiceLocation("mixed.com", 201, 111, "/q");
+ private static final ServiceLocation SERVER7 = new ServiceLocation("mixed.com", 203, 222, "/q");
private ScheduledExecutorService exec;
@@ -272,6 +274,24 @@ public class ServiceClientImplTest
Assert.assertEquals(expectedResponseObject, response);
}
+ @Test
+ public void test_request_followRedirect_mixedPorts() throws Exception
+ {
+ final RequestBuilder requestBuilder = new RequestBuilder(HttpMethod.GET, "/foo");
+ final ImmutableMap<String, String> expectedResponseObject = ImmutableMap.of("foo", "bar");
+
+ // Redirect from SERVER6 -> SERVER7.
+ stubLocatorCall(locations(SERVER6, SERVER7));
+ expectHttpCall(requestBuilder, SERVER6)
+ .thenReturn(redirectResponse(requestBuilder.build(SERVER7).getUrl().toString()));
+ expectHttpCall(requestBuilder, SERVER7).thenReturn(valueResponse(expectedResponseObject));
+
+ serviceClient = makeServiceClient(StandardRetryPolicy.noRetries());
+ final Map<String, String> response = doRequest(serviceClient, requestBuilder);
+
+ Assert.assertEquals(expectedResponseObject, response);
+ }
+
@Test
public void test_request_tooLongRedirectChain()
{
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org