Browse Source

Fix GET /_snapshot/_all/_all if there are no repos (#43558)

When there are no repositories, a request to GET /_snapshot/_all/_all
returns a 504 timeout error.
This happens because try to create GroupedActionListener with the
size of zero, which leads to an exception.
This commit short-circuits if there are no repos and adds a test to
verify the fix.

Closes #43547
Andrey Ershov 6 years ago
parent
commit
03e8734b04

+ 5 - 0
server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/TransportGetSnapshotsAction.java

@@ -112,6 +112,11 @@ public class TransportGetSnapshotsAction extends TransportMasterNodeAction<GetSn
 
     private void getMultipleReposSnapshotInfo(List<RepositoryMetaData> repos, String[] snapshots, boolean ignoreUnavailable,
                                               boolean verbose, ActionListener<GetSnapshotsResponse> listener) {
+        // short-circuit if there are no repos, because we can not create GroupedActionListener of size 0
+        if (repos.isEmpty()) {
+            listener.onResponse(new GetSnapshotsResponse(Collections.emptyList()));
+            return;
+        }
         final GroupedActionListener<GetSnapshotsResponse.Response> groupedActionListener =
                 new GroupedActionListener<>(
                         ActionListener.map(listener, responses -> {

+ 12 - 0
server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java

@@ -1328,6 +1328,18 @@ public class SharedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTestCas
         assertThat(numberOfFiles(repo), equalTo(numberOfFiles[0] + 2));
     }
 
+    public void testGetSnapshotsNoRepos() {
+        ensureGreen();
+        GetSnapshotsResponse getSnapshotsResponse = client().admin().cluster()
+                .prepareGetSnapshots(new String[]{"_all"})
+                .setSnapshots(randomFrom("_all", "*"))
+                .get();
+
+        assertTrue(getSnapshotsResponse.getRepositories().isEmpty());
+        assertTrue(getSnapshotsResponse.getFailedResponses().isEmpty());
+        assertTrue(getSnapshotsResponse.getSuccessfulResponses().isEmpty());
+    }
+
     public void testGetSnapshotsMultipleRepos() {
         final Client client = client();