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 a3a9c5f409 Fixing overlord issued too many redirects (#12908)
a3a9c5f409 is described below

commit a3a9c5f409f7a0985973e062ecd5756f653bb486
Author: Karan Kumar <[email protected]>
AuthorDate: Wed Aug 17 18:27:39 2022 +0530

    Fixing overlord issued too many redirects (#12908)
    
    * Fixing race in overlord redirects where the node was redirecting to itself
    
    * Fixing test cases
---
 .../apache/druid/indexing/overlord/TaskMaster.java    | 13 +++++++++++++
 .../indexing/overlord/http/OverlordRedirectInfo.java  |  8 ++++----
 .../overlord/http/OverlordRedirectInfoTest.java       | 19 +++++--------------
 .../druid/indexing/overlord/http/OverlordTest.java    |  2 +-
 .../java/org/apache/druid/rpc/ServiceClientImpl.java  | 14 ++++++++++++--
 .../org/apache/druid/rpc/ServiceClientImplTest.java   |  9 +++++----
 6 files changed, 40 insertions(+), 25 deletions(-)

diff --git 
a/indexing-service/src/main/java/org/apache/druid/indexing/overlord/TaskMaster.java
 
b/indexing-service/src/main/java/org/apache/druid/indexing/overlord/TaskMaster.java
index 5825a2fb03..b52a3c5c03 100644
--- 
a/indexing-service/src/main/java/org/apache/druid/indexing/overlord/TaskMaster.java
+++ 
b/indexing-service/src/main/java/org/apache/druid/indexing/overlord/TaskMaster.java
@@ -232,6 +232,19 @@ public class TaskMaster implements TaskCountStatsProvider, 
TaskSlotCountStatsPro
     return overlordLeaderSelector.getCurrentLeader();
   }
 
+  public Optional<String> getRedirectLocation()
+  {
+    String leader = overlordLeaderSelector.getCurrentLeader();
+    // do not redirect when
+    // leader is not elected
+    // leader is the current node
+    if (leader == null || leader.isEmpty() || 
overlordLeaderSelector.isLeader()) {
+      return Optional.absent();
+    } else {
+      return Optional.of(leader);
+    }
+  }
+
   public Optional<TaskRunner> getTaskRunner()
   {
     if (isLeader()) {
diff --git 
a/indexing-service/src/main/java/org/apache/druid/indexing/overlord/http/OverlordRedirectInfo.java
 
b/indexing-service/src/main/java/org/apache/druid/indexing/overlord/http/OverlordRedirectInfo.java
index 0faa6c8aad..4e332f599d 100644
--- 
a/indexing-service/src/main/java/org/apache/druid/indexing/overlord/http/OverlordRedirectInfo.java
+++ 
b/indexing-service/src/main/java/org/apache/druid/indexing/overlord/http/OverlordRedirectInfo.java
@@ -19,6 +19,7 @@
 
 package org.apache.druid.indexing.overlord.http;
 
+import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.Inject;
 import org.apache.druid.indexing.overlord.TaskMaster;
@@ -55,13 +56,12 @@ public class OverlordRedirectInfo implements RedirectInfo
   public URL getRedirectURL(String queryString, String requestURI)
   {
     try {
-      final String leader = taskMaster.getCurrentLeader();
-      if (leader == null || leader.isEmpty()) {
+      final Optional<String> redirectLocation = 
taskMaster.getRedirectLocation();
+      if (!redirectLocation.isPresent()) {
         return null;
       }
 
-      String location = StringUtils.format("%s%s", leader, requestURI);
-
+      String location = StringUtils.format("%s%s", redirectLocation.get(), 
requestURI);
       if (queryString != null) {
         location = StringUtils.format("%s?%s", location, queryString);
       }
diff --git 
a/indexing-service/src/test/java/org/apache/druid/indexing/overlord/http/OverlordRedirectInfoTest.java
 
b/indexing-service/src/test/java/org/apache/druid/indexing/overlord/http/OverlordRedirectInfoTest.java
index 33ea5e75c7..46e03206f4 100644
--- 
a/indexing-service/src/test/java/org/apache/druid/indexing/overlord/http/OverlordRedirectInfoTest.java
+++ 
b/indexing-service/src/test/java/org/apache/druid/indexing/overlord/http/OverlordRedirectInfoTest.java
@@ -19,6 +19,7 @@
 
 package org.apache.druid.indexing.overlord.http;
 
+import com.google.common.base.Optional;
 import org.apache.druid.indexing.overlord.TaskMaster;
 import org.easymock.EasyMock;
 import org.junit.Assert;
@@ -66,19 +67,9 @@ public class OverlordRedirectInfoTest
   }
 
   @Test
-  public void testGetRedirectURLNull()
+  public void testGetRedirectURLWithEmptyLocation()
   {
-    EasyMock.expect(taskMaster.getCurrentLeader()).andReturn(null).anyTimes();
-    EasyMock.replay(taskMaster);
-    URL url = redirectInfo.getRedirectURL("query", "/request");
-    Assert.assertNull(url);
-    EasyMock.verify(taskMaster);
-  }
-
-  @Test
-  public void testGetRedirectURLEmpty()
-  {
-    EasyMock.expect(taskMaster.getCurrentLeader()).andReturn("").anyTimes();
+    
EasyMock.expect(taskMaster.getRedirectLocation()).andReturn(Optional.absent()).anyTimes();
     EasyMock.replay(taskMaster);
     URL url = redirectInfo.getRedirectURL("query", "/request");
     Assert.assertNull(url);
@@ -91,7 +82,7 @@ public class OverlordRedirectInfoTest
     String host = "http://localhost";;
     String query = "foo=bar&x=y";
     String request = "/request";
-    EasyMock.expect(taskMaster.getCurrentLeader()).andReturn(host).anyTimes();
+    
EasyMock.expect(taskMaster.getRedirectLocation()).andReturn(Optional.of(host)).anyTimes();
     EasyMock.replay(taskMaster);
     URL url = redirectInfo.getRedirectURL(query, request);
     Assert.assertEquals("http://localhost/request?foo=bar&x=y";, 
url.toString());
@@ -107,7 +98,7 @@ public class OverlordRedirectInfoTest
         "UTF-8"
     ) + "/status";
 
-    EasyMock.expect(taskMaster.getCurrentLeader()).andReturn(host).anyTimes();
+    
EasyMock.expect(taskMaster.getRedirectLocation()).andReturn(Optional.of(host)).anyTimes();
     EasyMock.replay(taskMaster);
     URL url = redirectInfo.getRedirectURL(null, request);
     Assert.assertEquals(
diff --git 
a/indexing-service/src/test/java/org/apache/druid/indexing/overlord/http/OverlordTest.java
 
b/indexing-service/src/test/java/org/apache/druid/indexing/overlord/http/OverlordTest.java
index 40ed6e0212..02a71f8560 100644
--- 
a/indexing-service/src/test/java/org/apache/druid/indexing/overlord/http/OverlordTest.java
+++ 
b/indexing-service/src/test/java/org/apache/druid/indexing/overlord/http/OverlordTest.java
@@ -80,7 +80,6 @@ import org.junit.Test;
 import javax.annotation.Nullable;
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.core.Response;
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -217,6 +216,7 @@ public class OverlordTest
       Thread.sleep(10);
     }
     Assert.assertEquals(taskMaster.getCurrentLeader(), 
druidNode.getHostAndPort());
+    Assert.assertEquals(Optional.absent(), taskMaster.getRedirectLocation());
 
     final TaskStorageQueryAdapter taskStorageQueryAdapter = new 
TaskStorageQueryAdapter(taskStorage, taskLockbox);
     final WorkerTaskRunnerQueryAdapter workerTaskRunnerQueryAdapter = new 
WorkerTaskRunnerQueryAdapter(taskMaster, null);
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 9a2ce234c5..e7fbf72b1d 100644
--- a/server/src/main/java/org/apache/druid/rpc/ServiceClientImpl.java
+++ b/server/src/main/java/org/apache/druid/rpc/ServiceClientImpl.java
@@ -200,7 +200,12 @@ public class ServiceClientImpl implements ServiceClient
                         final String newUri = 
result.error().getResponse().headers().get("Location");
 
                         if (redirectCount >= MAX_REDIRECTS) {
-                          retVal.setException(new RpcException("Service [%s] 
issued too many redirects", serviceName));
+                          retVal.setException(new RpcException(
+                              "Service [%s] redirected too many times [%d] to 
invalid url %s",
+                              serviceName,
+                              redirectCount,
+                              newUri
+                          ));
                         } else {
                           // Update preferredLocationNoPath if we got a 
redirect.
                           final ServiceLocation redirectLocationNoPath = 
serviceLocationNoPathFromUri(newUri);
@@ -212,7 +217,12 @@ public class ServiceClientImpl implements ServiceClient
                             );
                           } else {
                             retVal.setException(
-                                new RpcException("Service [%s] redirected to 
invalid URL [%s]", serviceName, newUri)
+                                new RpcException(
+                                    "Service [%s] redirected [%d] times to 
invalid URL [%s]",
+                                    serviceName,
+                                    redirectCount,
+                                    newUri
+                                )
                             );
                           }
                         }
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 01540c5d7e..f998bf82d7 100644
--- a/server/src/test/java/org/apache/druid/rpc/ServiceClientImplTest.java
+++ b/server/src/test/java/org/apache/druid/rpc/ServiceClientImplTest.java
@@ -289,7 +289,7 @@ public class ServiceClientImplTest
     MatcherAssert.assertThat(e.getCause(), 
CoreMatchers.instanceOf(RpcException.class));
     MatcherAssert.assertThat(
         e.getCause(),
-        ThrowableMessageMatcher.hasMessage(CoreMatchers.containsString("too 
many redirects"))
+        
ThrowableMessageMatcher.hasMessage(CoreMatchers.containsString("redirected too 
many times"))
     );
   }
 
@@ -313,7 +313,8 @@ public class ServiceClientImplTest
     MatcherAssert.assertThat(e.getCause(), 
CoreMatchers.instanceOf(RpcException.class));
     MatcherAssert.assertThat(
         e.getCause(),
-        
ThrowableMessageMatcher.hasMessage(CoreMatchers.containsString("redirected to 
invalid URL [invalid-url]"))
+        ThrowableMessageMatcher.hasMessage(
+            CoreMatchers.containsString("redirected [0] times to invalid URL 
[invalid-url]"))
     );
   }
 
@@ -337,7 +338,7 @@ public class ServiceClientImplTest
     MatcherAssert.assertThat(e.getCause(), 
CoreMatchers.instanceOf(RpcException.class));
     MatcherAssert.assertThat(
         e.getCause(),
-        
ThrowableMessageMatcher.hasMessage(CoreMatchers.containsString("redirected to 
invalid URL [null]"))
+        
ThrowableMessageMatcher.hasMessage(CoreMatchers.containsString("redirected [0] 
times to invalid URL [null]"))
     );
   }
 
@@ -361,7 +362,7 @@ public class ServiceClientImplTest
     MatcherAssert.assertThat(e.getCause(), 
CoreMatchers.instanceOf(RpcException.class));
     MatcherAssert.assertThat(
         e.getCause(),
-        ThrowableMessageMatcher.hasMessage(CoreMatchers.containsString("too 
many redirects"))
+        
ThrowableMessageMatcher.hasMessage(CoreMatchers.containsString("redirected too 
many times"))
     );
   }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to