diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotRequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotRequestConverters.java index 0dedd59c3e6a2..ac653a0dd97b0 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotRequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotRequestConverters.java @@ -108,7 +108,7 @@ static Request createSnapshot(CreateSnapshotRequest createSnapshotRequest) throw static Request getSnapshots(GetSnapshotsRequest getSnapshotsRequest) { RequestConverters.EndpointBuilder endpointBuilder = new RequestConverters.EndpointBuilder().addPathPartAsIs("_snapshot") - .addPathPart(getSnapshotsRequest.repository()); + .addCommaSeparatedPathParts(getSnapshotsRequest.repositories()); String endpoint; if (getSnapshotsRequest.snapshots().length == 0) { endpoint = endpointBuilder.addPathPart("_all").build(); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotIT.java index afc7a88151ebe..8e4001442b0cc 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotIT.java @@ -41,17 +41,16 @@ import org.elasticsearch.repositories.fs.FsRepository; import org.elasticsearch.rest.RestStatus; import org.elasticsearch.snapshots.RestoreInfo; -import org.elasticsearch.snapshots.SnapshotInfo; +import org.mockito.internal.util.collections.Sets; import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Map; -import java.util.stream.Collectors; -import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; public class SnapshotIT extends ESRestHighLevelClientTestCase { @@ -61,14 +60,14 @@ private AcknowledgedResponse createTestRepository(String repository, String type request.settings(settings, XContentType.JSON); request.type(type); return execute(request, highLevelClient().snapshot()::createRepository, - highLevelClient().snapshot()::createRepositoryAsync); + highLevelClient().snapshot()::createRepositoryAsync); } private CreateSnapshotResponse createTestSnapshot(CreateSnapshotRequest createSnapshotRequest) throws IOException { // assumes the repository already exists return execute(createSnapshotRequest, highLevelClient().snapshot()::create, - highLevelClient().snapshot()::createAsync); + highLevelClient().snapshot()::createAsync); } public void testCreateRepository() throws IOException { @@ -84,7 +83,7 @@ public void testSnapshotGetRepositoriesUsingParams() throws IOException { GetRepositoriesRequest request = new GetRepositoriesRequest(); request.repositories(new String[]{testRepository}); GetRepositoriesResponse response = execute(request, highLevelClient().snapshot()::getRepository, - highLevelClient().snapshot()::getRepositoryAsync); + highLevelClient().snapshot()::getRepositoryAsync); assertThat(1, equalTo(response.repositories().size())); } @@ -93,7 +92,7 @@ public void testSnapshotGetDefaultRepositories() throws IOException { assertTrue(createTestRepository("test", FsRepository.TYPE, "{\"location\": \".\"}").isAcknowledged()); GetRepositoriesResponse response = execute(new GetRepositoriesRequest(), highLevelClient().snapshot()::getRepository, - highLevelClient().snapshot()::getRepositoryAsync); + highLevelClient().snapshot()::getRepositoryAsync); assertThat(2, equalTo(response.repositories().size())); } @@ -101,11 +100,11 @@ public void testSnapshotGetRepositoriesNonExistent() { String repository = "doesnotexist"; GetRepositoriesRequest request = new GetRepositoriesRequest(new String[]{repository}); ElasticsearchException exception = expectThrows(ElasticsearchException.class, () -> execute(request, - highLevelClient().snapshot()::getRepository, highLevelClient().snapshot()::getRepositoryAsync)); + highLevelClient().snapshot()::getRepository, highLevelClient().snapshot()::getRepositoryAsync)); assertThat(exception.status(), equalTo(RestStatus.NOT_FOUND)); assertThat(exception.getMessage(), equalTo( - "Elasticsearch exception [type=repository_missing_exception, reason=[" + repository + "] missing]")); + "Elasticsearch exception [type=repository_missing_exception, reason=[" + repository + "] missing]")); } public void testSnapshotDeleteRepository() throws IOException { @@ -114,12 +113,12 @@ public void testSnapshotDeleteRepository() throws IOException { GetRepositoriesRequest request = new GetRepositoriesRequest(); GetRepositoriesResponse response = execute(request, highLevelClient().snapshot()::getRepository, - highLevelClient().snapshot()::getRepositoryAsync); + highLevelClient().snapshot()::getRepositoryAsync); assertThat(1, equalTo(response.repositories().size())); DeleteRepositoryRequest deleteRequest = new DeleteRepositoryRequest(repository); AcknowledgedResponse deleteResponse = execute(deleteRequest, highLevelClient().snapshot()::deleteRepository, - highLevelClient().snapshot()::deleteRepositoryAsync); + highLevelClient().snapshot()::deleteRepositoryAsync); assertTrue(deleteResponse.isAcknowledged()); } @@ -130,7 +129,7 @@ public void testVerifyRepository() throws IOException { VerifyRepositoryRequest request = new VerifyRepositoryRequest("test"); VerifyRepositoryResponse response = execute(request, highLevelClient().snapshot()::verifyRepository, - highLevelClient().snapshot()::verifyRepositoryAsync); + highLevelClient().snapshot()::verifyRepositoryAsync); assertThat(response.getNodes().size(), equalTo(1)); } @@ -153,25 +152,31 @@ public void testCreateSnapshot() throws IOException { if (waitForCompletion == false) { // If we don't wait for the snapshot to complete we have to cancel it to not leak the snapshot task AcknowledgedResponse deleteResponse = execute( - new DeleteSnapshotRequest(repository, snapshot), - highLevelClient().snapshot()::delete, highLevelClient().snapshot()::deleteAsync + new DeleteSnapshotRequest(repository, snapshot), + highLevelClient().snapshot()::delete, highLevelClient().snapshot()::deleteAsync ); assertTrue(deleteResponse.isAcknowledged()); } } public void testGetSnapshots() throws IOException { - String repository = "test_repository"; + String repository1 = "test_repository1"; + String repository2 = "test_repository2"; String snapshot1 = "test_snapshot1"; String snapshot2 = "test_snapshot2"; - AcknowledgedResponse putRepositoryResponse = createTestRepository(repository, FsRepository.TYPE, "{\"location\": \".\"}"); + AcknowledgedResponse putRepositoryResponse = + createTestRepository(repository1, FsRepository.TYPE, "{\"location\": \"loc1\"}"); assertTrue(putRepositoryResponse.isAcknowledged()); - CreateSnapshotRequest createSnapshotRequest1 = new CreateSnapshotRequest(repository, snapshot1); + AcknowledgedResponse putRepositoryResponse2 = + createTestRepository(repository2, FsRepository.TYPE, "{\"location\": \"loc2\"}"); + assertTrue(putRepositoryResponse2.isAcknowledged()); + + CreateSnapshotRequest createSnapshotRequest1 = new CreateSnapshotRequest(repository1, snapshot1); createSnapshotRequest1.waitForCompletion(true); CreateSnapshotResponse putSnapshotResponse1 = createTestSnapshot(createSnapshotRequest1); - CreateSnapshotRequest createSnapshotRequest2 = new CreateSnapshotRequest(repository, snapshot2); + CreateSnapshotRequest createSnapshotRequest2 = new CreateSnapshotRequest(repository2, snapshot2); createSnapshotRequest2.waitForCompletion(true); Map originalMetadata = randomUserMetadata(); createSnapshotRequest2.userMetadata(originalMetadata); @@ -180,28 +185,26 @@ public void testGetSnapshots() throws IOException { assertEquals(RestStatus.OK, putSnapshotResponse1.status()); assertEquals(RestStatus.OK, putSnapshotResponse2.status()); - GetSnapshotsRequest request; - if (randomBoolean()) { - request = new GetSnapshotsRequest(repository); - } else if (randomBoolean()) { - request = new GetSnapshotsRequest(repository, new String[] {"_all"}); + GetSnapshotsRequest request = new GetSnapshotsRequest( + randomFrom(new String[]{"_all"}, new String[]{"*"}, new String[]{repository1, repository2}), + randomFrom(new String[]{"_all"}, new String[]{"*"}, new String[]{snapshot1, snapshot2}) + ); + request.ignoreUnavailable(true); - } else { - request = new GetSnapshotsRequest(repository, new String[] {snapshot1, snapshot2}); - } GetSnapshotsResponse response = execute(request, highLevelClient().snapshot()::get, highLevelClient().snapshot()::getAsync); - assertEquals(2, response.getSnapshots().size()); - assertThat(response.getSnapshots().stream().map((s) -> s.snapshotId().getName()).collect(Collectors.toList()), - contains("test_snapshot1", "test_snapshot2")); - response.getSnapshots().stream() - .filter(s -> s.snapshotId().getName().equals("test_snapshot2")) - .findFirst() - .map(SnapshotInfo::userMetadata) - .ifPresentOrElse(metadata -> assertEquals(originalMetadata, metadata), - () -> assertNull("retrieved metadata is null, expected non-null metadata", originalMetadata)); + assertThat(response.isFailed(), is(false)); + assertThat(response.getRepositories(), equalTo(Sets.newSet(repository1, repository2))); + + assertThat(response.getSnapshots(repository1), hasSize(1)); + assertThat(response.getSnapshots(repository1).get(0).snapshotId().getName(), equalTo(snapshot1)); + + assertThat(response.getSnapshots(repository2), hasSize(1)); + assertThat(response.getSnapshots(repository2).get(0).snapshotId().getName(), equalTo(snapshot2)); + assertThat(response.getSnapshots(repository2).get(0).userMetadata(), equalTo(originalMetadata)); } + public void testSnapshotsStatus() throws IOException { String testRepository = "test"; String testSnapshot = "snapshot"; @@ -223,7 +226,7 @@ public void testSnapshotsStatus() throws IOException { request.repository(testRepository); request.snapshots(new String[]{testSnapshot}); SnapshotsStatusResponse response = execute(request, highLevelClient().snapshot()::status, - highLevelClient().snapshot()::statusAsync); + highLevelClient().snapshot()::statusAsync); assertThat(response.getSnapshots().size(), equalTo(1)); assertThat(response.getSnapshots().get(0).getSnapshot().getRepository(), equalTo(testRepository)); assertThat(response.getSnapshots().get(0).getSnapshot().getSnapshotId().getName(), equalTo(testSnapshot)); @@ -260,7 +263,7 @@ public void testRestoreSnapshot() throws IOException { request.renameReplacement(restoredIndex); RestoreSnapshotResponse response = execute(request, highLevelClient().snapshot()::restore, - highLevelClient().snapshot()::restoreAsync); + highLevelClient().snapshot()::restoreAsync); RestoreInfo restoreInfo = response.getRestoreInfo(); assertThat(restoreInfo.name(), equalTo(testSnapshot)); @@ -301,17 +304,17 @@ private static Map randomUserMetadata() { for (int i = 0; i < fields; i++) { if (randomBoolean()) { metadata.put(randomValueOtherThanMany(metadata::containsKey, () -> randomAlphaOfLengthBetween(2,10)), - randomAlphaOfLengthBetween(5, 5)); + randomAlphaOfLengthBetween(5, 5)); } else { Map nested = new HashMap<>(); long nestedFields = randomLongBetween(0, 4); for (int j = 0; j < nestedFields; j++) { nested.put(randomValueOtherThanMany(nested::containsKey, () -> randomAlphaOfLengthBetween(2,10)), - randomAlphaOfLengthBetween(5, 5)); + randomAlphaOfLengthBetween(5, 5)); } metadata.put(randomValueOtherThanMany(metadata::containsKey, () -> randomAlphaOfLengthBetween(2,10)), nested); } } return metadata; } -} +} \ No newline at end of file diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotRequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotRequestConvertersTests.java index 66720b70ee3a6..bea8835e093b8 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotRequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/SnapshotRequestConvertersTests.java @@ -41,7 +41,6 @@ import java.io.IOException; import java.nio.file.Path; -import java.util.Arrays; import java.util.HashMap; import java.util.Locale; import java.util.Map; @@ -148,15 +147,16 @@ public void testCreateSnapshot() throws IOException { public void testGetSnapshots() { Map expectedParams = new HashMap<>(); - String repository = RequestConvertersTests.randomIndicesNames(1, 1)[0]; + String repository1 = randomAlphaOfLength(10); + String repository2 = randomAlphaOfLength(10); String snapshot1 = "snapshot1-" + randomAlphaOfLengthBetween(2, 5).toLowerCase(Locale.ROOT); String snapshot2 = "snapshot2-" + randomAlphaOfLengthBetween(2, 5).toLowerCase(Locale.ROOT); - String endpoint = String.format(Locale.ROOT, "/_snapshot/%s/%s,%s", repository, snapshot1, snapshot2); + String endpoint = String.format(Locale.ROOT, "/_snapshot/%s,%s/%s,%s", repository1, repository2, snapshot1, snapshot2); GetSnapshotsRequest getSnapshotsRequest = new GetSnapshotsRequest(); - getSnapshotsRequest.repository(repository); - getSnapshotsRequest.snapshots(Arrays.asList(snapshot1, snapshot2).toArray(new String[0])); + getSnapshotsRequest.repositories(repository1, repository2); + getSnapshotsRequest.snapshots(new String[]{snapshot1, snapshot2}); RequestConvertersTests.setRandomMasterTimeout(getSnapshotsRequest, expectedParams); if (randomBoolean()) { diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java index d80c24be6618a..5a6016175bae2 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SnapshotClientDocumentationIT.java @@ -590,7 +590,7 @@ public void testSnapshotGetSnapshots() throws IOException { // end::get-snapshots-request // tag::get-snapshots-request-repositoryName - request.repository(repositoryName); // <1> + request.repositories(repositoryName); // <1> // end::get-snapshots-request-repositoryName // tag::get-snapshots-request-snapshots @@ -616,7 +616,7 @@ public void testSnapshotGetSnapshots() throws IOException { // end::get-snapshots-execute // tag::get-snapshots-response - List snapshotsInfos = response.getSnapshots(); + List snapshotsInfos = response.getSnapshots(repositoryName); SnapshotInfo snapshotInfo = snapshotsInfos.get(0); RestStatus restStatus = snapshotInfo.status(); // <1> SnapshotId snapshotId = snapshotInfo.snapshotId(); // <2> diff --git a/docs/reference/cat/snapshots.asciidoc b/docs/reference/cat/snapshots.asciidoc index e8c5320043026..37d57292e0488 100644 --- a/docs/reference/cat/snapshots.asciidoc +++ b/docs/reference/cat/snapshots.asciidoc @@ -1,7 +1,8 @@ [[cat-snapshots]] == cat snapshots -The `snapshots` command shows all snapshots that belong to a specific repository. +The `snapshots` command shows all snapshots that belong to a specific repository +or multiple repositories. To find a list of available repositories to query, the command `/_cat/repositories` can be used. Querying the snapshots of a repository named `repo1` then looks as follows. @@ -18,9 +19,9 @@ Which looks like: [source,txt] -------------------------------------------------- -id status start_epoch start_time end_epoch end_time duration indices successful_shards failed_shards total_shards -snap1 FAILED 1445616705 18:11:45 1445616978 18:16:18 4.6m 1 4 1 5 -snap2 SUCCESS 1445634298 23:04:58 1445634672 23:11:12 6.2m 2 10 0 10 +id repository status start_epoch start_time end_epoch end_time duration indices successful_shards failed_shards total_shards +snap1 repo1 FAILED 1445616705 18:11:45 1445616978 18:16:18 4.6m 1 4 1 5 +snap2 repo1 SUCCESS 1445634298 23:04:58 1445634672 23:11:12 6.2m 2 10 0 10 -------------------------------------------------- // TESTRESPONSE[s/FAILED/SUCCESS/ s/14456\d+/\\d+/ s/\d+(\.\d+)?(m|s|ms)/\\d+(\\.\\d+)?(m|s|ms)/] // TESTRESPONSE[s/\d+:\d+:\d+/\\d+:\\d+:\\d+/] @@ -32,3 +33,17 @@ Each snapshot contains information about when it was started and stopped. Start and stop timestamps are available in two formats. The `HH:MM:SS` output is simply for quick human consumption. The epoch time retains more information, including date, and is machine sortable if the snapshot process spans days. + +It is also possible to get the list of snapshots from multiple repositories. +Here are some examples: + +[source,js] +-------------------------------------------------- +GET /_cat/snapshots/_all +GET /_cat/snapshots/repo1,repo2 +GET /_cat/snapshots/repo* +-------------------------------------------------- +// CONSOLE +// TEST[skip:no repo2] + +Please note that if one of the repositories fails during the request you will get an exception instead of the table. \ No newline at end of file diff --git a/docs/reference/migration/migrate_8_0/snapshots.asciidoc b/docs/reference/migration/migrate_8_0/snapshots.asciidoc index 791e5b28da057..c08ac76f88c90 100644 --- a/docs/reference/migration/migrate_8_0/snapshots.asciidoc +++ b/docs/reference/migration/migrate_8_0/snapshots.asciidoc @@ -9,6 +9,11 @@ // end::notable-breaking-changes[] +[float] +=== Get snapshots response format is changed +It's possible to get snapshots from multiple repositories in one go. The response format has changed +and now contains separate response for each repository. See <> for more information. + [float] ==== Deprecated node level compress setting removed diff --git a/docs/reference/modules/snapshots.asciidoc b/docs/reference/modules/snapshots.asciidoc index c8874c5fa1d32..a2fcd39496092 100644 --- a/docs/reference/modules/snapshots.asciidoc +++ b/docs/reference/modules/snapshots.asciidoc @@ -472,6 +472,16 @@ that setting `verbose` to `false` will omit all other information about the snap such as status information, the number of snapshotted shards, etc. The default value of the `verbose` parameter is `true`. +It is also possible to retrieve snapshots from multiple repositories in one go, for example: +[source,sh] +----------------------------------- +GET /_snapshot/_all +GET /_snapshot/my_backup,my_fs_backup +GET /_snapshot/my*/snap* +----------------------------------- +// CONSOLE +// TEST[skip:no my_fs_backup] + A currently running snapshot can be retrieved using the following command: [source,sh] diff --git a/modules/repository-url/src/test/java/org/elasticsearch/repositories/url/URLSnapshotRestoreTests.java b/modules/repository-url/src/test/java/org/elasticsearch/repositories/url/URLSnapshotRestoreTests.java index ab9268b081456..160333d5346ed 100644 --- a/modules/repository-url/src/test/java/org/elasticsearch/repositories/url/URLSnapshotRestoreTests.java +++ b/modules/repository-url/src/test/java/org/elasticsearch/repositories/url/URLSnapshotRestoreTests.java @@ -88,7 +88,7 @@ public void testUrlRepository() throws Exception { .prepareGetSnapshots("test-repo") .setSnapshots("test-snap") .get() - .getSnapshots() + .getSnapshots("test-repo") .get(0) .state(); assertThat(state, equalTo(SnapshotState.SUCCESS)); @@ -116,8 +116,8 @@ public void testUrlRepository() throws Exception { logger.info("--> list available shapshots"); GetSnapshotsResponse getSnapshotsResponse = client.admin().cluster().prepareGetSnapshots("url-repo").get(); - assertThat(getSnapshotsResponse.getSnapshots(), notNullValue()); - assertThat(getSnapshotsResponse.getSnapshots().size(), equalTo(1)); + assertThat(getSnapshotsResponse.getSnapshots("url-repo"), notNullValue()); + assertThat(getSnapshotsResponse.getSnapshots("url-repo").size(), equalTo(1)); logger.info("--> delete snapshot"); AcknowledgedResponse deleteSnapshotResponse = client.admin().cluster().prepareDeleteSnapshot("test-repo", "test-snap").get(); @@ -125,7 +125,7 @@ public void testUrlRepository() throws Exception { logger.info("--> list available shapshot again, no snapshots should be returned"); getSnapshotsResponse = client.admin().cluster().prepareGetSnapshots("url-repo").get(); - assertThat(getSnapshotsResponse.getSnapshots(), notNullValue()); - assertThat(getSnapshotsResponse.getSnapshots().size(), equalTo(0)); + assertThat(getSnapshotsResponse.getSnapshots("url-repo"), notNullValue()); + assertThat(getSnapshotsResponse.getSnapshots("url-repo").size(), equalTo(0)); } } diff --git a/modules/repository-url/src/test/resources/rest-api-spec/test/repository_url/10_basic.yml b/modules/repository-url/src/test/resources/rest-api-spec/test/repository_url/10_basic.yml index b932f0d53caad..e76669dc75e01 100644 --- a/modules/repository-url/src/test/resources/rest-api-spec/test/repository_url/10_basic.yml +++ b/modules/repository-url/src/test/resources/rest-api-spec/test/repository_url/10_basic.yml @@ -112,6 +112,9 @@ teardown: --- "Restore with repository-url using http://": + - skip: + version: " - 7.9.99" + reason: "8.0 changes get snapshots response format" # Ensure that the URL repository is registered - do: @@ -126,9 +129,9 @@ teardown: repository: repository-url snapshot: snapshot-one,snapshot-two - - is_true: snapshots - - match: { snapshots.0.state : SUCCESS } - - match: { snapshots.1.state : SUCCESS } + - is_true: responses.0.snapshots + - match: { responses.0.snapshots.0.state : SUCCESS } + - match: { responses.0.snapshots.1.state : SUCCESS } # Delete the index - do: @@ -174,6 +177,9 @@ teardown: --- "Restore with repository-url using file://": + - skip: + version: " - 7.9.99" + reason: "8.0 changes get snapshots response format" # Ensure that the URL repository is registered - do: @@ -188,9 +194,9 @@ teardown: repository: repository-file snapshot: snapshot-one,snapshot-two - - is_true: snapshots - - match: { snapshots.0.state : SUCCESS } - - match: { snapshots.1.state : SUCCESS } + - is_true: responses.0.snapshots + - match: { responses.0.snapshots.0.state : SUCCESS } + - match: { responses.0.snapshots.1.state : SUCCESS } # Delete the index - do: @@ -236,13 +242,18 @@ teardown: --- "Get a non existing snapshot": + - skip: + version: " - 7.9.99" + reason: "8.0 changes get snapshots response format" - do: - catch: /snapshot_missing_exception/ snapshot.get: repository: repository-url snapshot: missing + - is_true: responses.0.error + - match: { responses.0.error.type: snapshot_missing_exception } + --- "Delete a non existing snapshot": diff --git a/plugins/repository-azure/qa/microsoft-azure-storage/src/test/resources/rest-api-spec/test/repository_azure/10_repository.yml b/plugins/repository-azure/qa/microsoft-azure-storage/src/test/resources/rest-api-spec/test/repository_azure/10_repository.yml index 92866190959e6..fade1f9f1e67d 100644 --- a/plugins/repository-azure/qa/microsoft-azure-storage/src/test/resources/rest-api-spec/test/repository_azure/10_repository.yml +++ b/plugins/repository-azure/qa/microsoft-azure-storage/src/test/resources/rest-api-spec/test/repository_azure/10_repository.yml @@ -15,6 +15,9 @@ setup: --- "Snapshot/Restore with repository-azure": + - skip: + version: " - 7.9.99" + reason: "8.0 changes get snapshots response format" # Get repository - do: @@ -121,9 +124,9 @@ setup: repository: repository snapshot: snapshot-one,snapshot-two - - is_true: snapshots - - match: { snapshots.0.state : SUCCESS } - - match: { snapshots.1.state : SUCCESS } + - is_true: responses.0.snapshots + - match: { responses.0.snapshots.0.state: SUCCESS } + - match: { responses.0.snapshots.1.state: SUCCESS } # Delete the index - do: @@ -203,13 +206,18 @@ setup: --- "Get a non existing snapshot": + - skip: + version: " - 7.9.99" + reason: "8.0 changes get snapshots response format" - do: - catch: /snapshot_missing_exception/ snapshot.get: repository: repository snapshot: missing + - is_true: responses.0.error + - match: { responses.0.error.type: snapshot_missing_exception } + --- "Delete a non existing snapshot": diff --git a/plugins/repository-gcs/qa/google-cloud-storage/src/test/resources/rest-api-spec/test/repository_gcs/10_repository.yml b/plugins/repository-gcs/qa/google-cloud-storage/src/test/resources/rest-api-spec/test/repository_gcs/10_repository.yml index ac649229001db..553b6a3e14e50 100644 --- a/plugins/repository-gcs/qa/google-cloud-storage/src/test/resources/rest-api-spec/test/repository_gcs/10_repository.yml +++ b/plugins/repository-gcs/qa/google-cloud-storage/src/test/resources/rest-api-spec/test/repository_gcs/10_repository.yml @@ -28,6 +28,9 @@ setup: --- "Snapshot/Restore with repository-gcs": + - skip: + version: " - 7.9.99" + reason: "8.0 changes get snapshots response format" # Get repository - do: @@ -134,9 +137,9 @@ setup: repository: repository snapshot: snapshot-one,snapshot-two - - is_true: snapshots - - match: { snapshots.0.state : SUCCESS } - - match: { snapshots.1.state : SUCCESS } + - is_true: responses.0.snapshots + - match: { responses.0.snapshots.0.state : SUCCESS } + - match: { responses.0.snapshots.1.state : SUCCESS } # Delete the index - do: @@ -213,13 +216,18 @@ setup: --- "Get a non existing snapshot": + - skip: + version: " - 7.9.99" + reason: "8.0 changes get snapshots response format" - do: - catch: /snapshot_missing_exception/ snapshot.get: repository: repository snapshot: missing + - is_true: responses.0.error + - match: { responses.0.error.type: snapshot_missing_exception } + --- "Delete a non existing snapshot": diff --git a/plugins/repository-hdfs/src/test/java/org/elasticsearch/repositories/hdfs/HdfsTests.java b/plugins/repository-hdfs/src/test/java/org/elasticsearch/repositories/hdfs/HdfsTests.java index 88454188da588..8c211a6cabb43 100644 --- a/plugins/repository-hdfs/src/test/java/org/elasticsearch/repositories/hdfs/HdfsTests.java +++ b/plugins/repository-hdfs/src/test/java/org/elasticsearch/repositories/hdfs/HdfsTests.java @@ -91,7 +91,7 @@ public void testSimpleWorkflow() { .prepareGetSnapshots("test-repo") .setSnapshots("test-snap") .get() - .getSnapshots() + .getSnapshots("test-repo") .get(0) .state(), equalTo(SnapshotState.SUCCESS)); diff --git a/plugins/repository-hdfs/src/test/resources/rest-api-spec/test/hdfs_repository/30_snapshot_get.yml b/plugins/repository-hdfs/src/test/resources/rest-api-spec/test/hdfs_repository/30_snapshot_get.yml index f38f4783b195b..6ed93e07160b2 100644 --- a/plugins/repository-hdfs/src/test/resources/rest-api-spec/test/hdfs_repository/30_snapshot_get.yml +++ b/plugins/repository-hdfs/src/test/resources/rest-api-spec/test/hdfs_repository/30_snapshot_get.yml @@ -46,8 +46,8 @@ repository: test_snapshot_get_repository snapshot: test_snapshot_get - - length: { snapshots: 1 } - - match: { snapshots.0.snapshot : test_snapshot_get } + - length: { responses.0.snapshots: 1 } + - match: { responses.0.snapshots.0.snapshot : test_snapshot_get } # List snapshot info - do: @@ -55,8 +55,8 @@ repository: test_snapshot_get_repository snapshot: "*" - - length: { snapshots: 1 } - - match: { snapshots.0.snapshot : test_snapshot_get } + - length: { responses.0.snapshots: 1 } + - match: { responses.0.snapshots.0.snapshot : test_snapshot_get } # Remove our snapshot - do: diff --git a/plugins/repository-hdfs/src/test/resources/rest-api-spec/test/hdfs_repository/30_snapshot_readonly.yml b/plugins/repository-hdfs/src/test/resources/rest-api-spec/test/hdfs_repository/30_snapshot_readonly.yml index c2a37964e70a7..dda910ae36c26 100644 --- a/plugins/repository-hdfs/src/test/resources/rest-api-spec/test/hdfs_repository/30_snapshot_readonly.yml +++ b/plugins/repository-hdfs/src/test/resources/rest-api-spec/test/hdfs_repository/30_snapshot_readonly.yml @@ -21,7 +21,7 @@ repository: test_snapshot_repository_ro snapshot: "_all" - - length: { snapshots: 1 } + - length: { responses.0.snapshots: 1 } # Remove our repository - do: diff --git a/plugins/repository-s3/src/test/resources/rest-api-spec/test/repository_s3/20_repository_permanent_credentials.yml b/plugins/repository-s3/src/test/resources/rest-api-spec/test/repository_s3/20_repository_permanent_credentials.yml index e6c94f8c408d9..d319bf8984a97 100644 --- a/plugins/repository-s3/src/test/resources/rest-api-spec/test/repository_s3/20_repository_permanent_credentials.yml +++ b/plugins/repository-s3/src/test/resources/rest-api-spec/test/repository_s3/20_repository_permanent_credentials.yml @@ -31,7 +31,6 @@ setup: --- "Try to create repository with broken endpoint override and named client": - # Register repository with broken endpoint setting - do: catch: /repository_verification_exception/ @@ -108,6 +107,9 @@ setup: --- "Snapshot and Restore with repository-s3 using permanent credentials": + - skip: + version: " - 7.9.99" + reason: "8.0 changes get snapshots response format" # Get repository - do: @@ -215,9 +217,9 @@ setup: repository: repository_permanent snapshot: snapshot-one,snapshot-two - - is_true: snapshots - - match: { snapshots.0.state : SUCCESS } - - match: { snapshots.1.state : SUCCESS } + - is_true: responses.0.snapshots + - match: { responses.0.snapshots.0.state : SUCCESS } + - match: { responses.0.snapshots.1.state : SUCCESS } # Delete the index - do: @@ -322,13 +324,18 @@ setup: --- "Get a non existing snapshot": + - skip: + version: " - 7.9.99" + reason: "8.0 changes get snapshots response format" - do: - catch: /snapshot_missing_exception/ snapshot.get: repository: repository_permanent snapshot: missing + - is_true: responses.0.error + - match: { responses.0.error.type: snapshot_missing_exception } + --- "Delete a non existing snapshot": diff --git a/plugins/repository-s3/src/test/resources/rest-api-spec/test/repository_s3/30_repository_temporary_credentials.yml b/plugins/repository-s3/src/test/resources/rest-api-spec/test/repository_s3/30_repository_temporary_credentials.yml index d5bdcd9c4f203..3ad6c3959634b 100644 --- a/plugins/repository-s3/src/test/resources/rest-api-spec/test/repository_s3/30_repository_temporary_credentials.yml +++ b/plugins/repository-s3/src/test/resources/rest-api-spec/test/repository_s3/30_repository_temporary_credentials.yml @@ -18,6 +18,9 @@ setup: --- "Snapshot and Restore with repository-s3 using temporary credentials": + - skip: + version: " - 7.9.99" + reason: "8.0 changes get snapshots response format" # Get repository - do: @@ -122,9 +125,9 @@ setup: repository: repository_temporary snapshot: snapshot-one,snapshot-two - - is_true: snapshots - - match: { snapshots.0.state : SUCCESS } - - match: { snapshots.1.state : SUCCESS } + - is_true: responses.0.snapshots + - match: { responses.0.snapshots.0.state : SUCCESS } + - match: { responses.0.snapshots.1.state : SUCCESS } # Delete the index - do: @@ -229,13 +232,18 @@ setup: --- "Get a non existing snapshot": + - skip: + version: " - 7.9.99" + reason: "8.0 changes get snapshots response format" - do: - catch: /snapshot_missing_exception/ snapshot.get: repository: repository_temporary snapshot: missing + - is_true: responses.0.error + - match: { responses.0.error.type: snapshot_missing_exception } + --- "Delete a non existing snapshot": diff --git a/plugins/repository-s3/src/test/resources/rest-api-spec/test/repository_s3/40_repository_ec2_credentials.yml b/plugins/repository-s3/src/test/resources/rest-api-spec/test/repository_s3/40_repository_ec2_credentials.yml index 829ae6197659c..fa1d3fc10fb13 100644 --- a/plugins/repository-s3/src/test/resources/rest-api-spec/test/repository_s3/40_repository_ec2_credentials.yml +++ b/plugins/repository-s3/src/test/resources/rest-api-spec/test/repository_s3/40_repository_ec2_credentials.yml @@ -18,6 +18,9 @@ setup: --- "Snapshot and Restore with repository-s3 using ec2 credentials": + - skip: + version: " - 7.9.99" + reason: "8.0 changes get snapshots response format" # Get repository - do: @@ -122,9 +125,9 @@ setup: repository: repository_ec2 snapshot: snapshot-one,snapshot-two - - is_true: snapshots - - match: { snapshots.0.state : SUCCESS } - - match: { snapshots.1.state : SUCCESS } + - is_true: responses.0.snapshots + - match: { responses.0.snapshots.0.state : SUCCESS } + - match: { responses.0.snapshots.1.state : SUCCESS } # Delete the index - do: @@ -229,13 +232,18 @@ setup: --- "Get a non existing snapshot": + - skip: + version: " - 7.9.99" + reason: "8.0 changes get snapshots response format" - do: - catch: /snapshot_missing_exception/ snapshot.get: repository: repository_ec2 snapshot: missing + - is_true: responses.0.error + - match: { responses.0.error.type: snapshot_missing_exception } + --- "Delete a non existing snapshot": diff --git a/plugins/repository-s3/src/test/resources/rest-api-spec/test/repository_s3/50_repository_ecs_credentials.yml b/plugins/repository-s3/src/test/resources/rest-api-spec/test/repository_s3/50_repository_ecs_credentials.yml index c59d3a32badc7..99736fb25ff24 100644 --- a/plugins/repository-s3/src/test/resources/rest-api-spec/test/repository_s3/50_repository_ecs_credentials.yml +++ b/plugins/repository-s3/src/test/resources/rest-api-spec/test/repository_s3/50_repository_ecs_credentials.yml @@ -18,6 +18,9 @@ setup: --- "Snapshot and Restore with repository-s3 using ecs credentials": + - skip: + version: " - 7.9.99" + reason: "8.0 changes get snapshots response format" # Get repository - do: @@ -122,9 +125,9 @@ setup: repository: repository_ecs snapshot: snapshot-one,snapshot-two - - is_true: snapshots - - match: { snapshots.0.state : SUCCESS } - - match: { snapshots.1.state : SUCCESS } + - is_true: responses.0.snapshots + - match: { responses.0.snapshots.0.state : SUCCESS } + - match: { responses.0.snapshots.1.state : SUCCESS } # Delete the index - do: @@ -229,13 +232,18 @@ setup: --- "Get a non existing snapshot": + - skip: + version: " - 7.9.99" + reason: "8.0 changes get snapshots response format" - do: - catch: /snapshot_missing_exception/ snapshot.get: repository: repository_ecs snapshot: missing + - is_true: responses.0.error + - match: { responses.0.error.type: snapshot_missing_exception } + --- "Delete a non existing snapshot": diff --git a/qa/full-cluster-restart/src/test/java/org/elasticsearch/upgrades/FullClusterRestartIT.java b/qa/full-cluster-restart/src/test/java/org/elasticsearch/upgrades/FullClusterRestartIT.java index eb7078b2b189c..350ef19ccc6c5 100644 --- a/qa/full-cluster-restart/src/test/java/org/elasticsearch/upgrades/FullClusterRestartIT.java +++ b/qa/full-cluster-restart/src/test/java/org/elasticsearch/upgrades/FullClusterRestartIT.java @@ -1048,19 +1048,26 @@ private void assertClosedIndex(final String index, final boolean checkRoutingTab } } + @SuppressWarnings("unchecked") private void checkSnapshot(final String snapshotName, final int count, final Version tookOnVersion) throws IOException { // Check the snapshot metadata, especially the version Request listSnapshotRequest = new Request("GET", "/_snapshot/repo/" + snapshotName); - Map listSnapshotResponse = entityAsMap(client().performRequest(listSnapshotRequest)); - assertEquals(singletonList(snapshotName), XContentMapValues.extractValue("snapshots.snapshot", listSnapshotResponse)); - assertEquals(singletonList("SUCCESS"), XContentMapValues.extractValue("snapshots.state", listSnapshotResponse)); - assertEquals(singletonList(tookOnVersion.toString()), XContentMapValues.extractValue("snapshots.version", listSnapshotResponse)); + Map responseMap = entityAsMap(client().performRequest(listSnapshotRequest)); + Map snapResponse; + if (responseMap.get("responses") != null) { + snapResponse = (Map) ((List) responseMap.get("responses")).get(0); + } else { + snapResponse = responseMap; + } + + assertEquals(singletonList(snapshotName), XContentMapValues.extractValue("snapshots.snapshot", snapResponse)); + assertEquals(singletonList("SUCCESS"), XContentMapValues.extractValue("snapshots.state", snapResponse)); + assertEquals(singletonList(tookOnVersion.toString()), XContentMapValues.extractValue("snapshots.version", snapResponse)); // Remove the routing setting and template so we can test restoring them. Request clearRoutingFromSettings = new Request("PUT", "/_cluster/settings"); clearRoutingFromSettings.setJsonEntity("{\"persistent\":{\"cluster.routing.allocation.exclude.test_attr\": null}}"); client().performRequest(clearRoutingFromSettings); - client().performRequest(new Request("DELETE", "/_template/test_template")); // Restore diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/cat.snapshots/10_basic.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/cat.snapshots/10_basic.yml index 6e03ceb98c716..4f425f4817638 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/cat.snapshots/10_basic.yml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/cat.snapshots/10_basic.yml @@ -1,5 +1,9 @@ --- "Help": + - skip: + version: " - 7.9.99" + reason: Repository field added in 8.0 + - do: cat.snapshots: help: true @@ -7,6 +11,7 @@ - match: $body: | /^ id .+ \n + repository .+ \n status .+ \n start_epoch .+ \n start_time .+ \n @@ -21,6 +26,9 @@ $/ --- "Test cat snapshots output": + - skip: + version: " - 7.9.99" + reason: Repository field added in 8.0 - do: snapshot.create_repository: @@ -74,6 +82,6 @@ - match: $body: | - /^ snap1\s+ SUCCESS\s+ \d+\s+ \d\d\:\d\d\:\d\d\s+ \d+\s+ \d\d\:\d\d\:\d\d\s+ \S+\s+ 2\s+ 2\s+ 0\s+ 2\s*\n - snap2\s+ SUCCESS\s+ \d+\s+ \d\d\:\d\d\:\d\d\s+ \d+\s+ \d\d\:\d\d\:\d\d\s+ \S+\s+ 2\s+ 2\s+ 0\s+ 2\s*\n + /^ snap1\s+ test_cat_snapshots_1\s+ SUCCESS\s+ \d+\s+ \d\d\:\d\d\:\d\d\s+ \d+\s+ \d\d\:\d\d\:\d\d\s+ \S+\s+ 2\s+ 2\s+ 0\s+ 2\s*\n + snap2\s+ test_cat_snapshots_1\s+ SUCCESS\s+ \d+\s+ \d\d\:\d\d\:\d\d\s+ \d+\s+ \d\d\:\d\d\:\d\d\s+ \S+\s+ 2\s+ 2\s+ 0\s+ 2\s*\n $/ diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/snapshot.get/10_basic.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/snapshot.get/10_basic.yml index ad1279666ce62..219c5a70f331e 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/snapshot.get/10_basic.yml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/snapshot.get/10_basic.yml @@ -11,6 +11,9 @@ setup: --- "Get snapshot info": + - skip: + version: " - 7.9.99" + reason: "8.0 changes get snapshots response format" - do: indices.create: @@ -31,8 +34,8 @@ setup: repository: test_repo_get_1 snapshot: test_snapshot - - is_true: snapshots - - is_true: snapshots.0.failures + - is_true: responses.0.snapshots + - is_true: responses.0.snapshots.0.failures - do: snapshot.delete: @@ -41,15 +44,23 @@ setup: --- "Get missing snapshot info throws an exception": + - skip: + version: " - 7.9.99" + reason: "8.0 changes get snapshots response format" - do: - catch: /snapshot_missing_exception.+ is missing/ snapshot.get: repository: test_repo_get_1 snapshot: test_nonexistent_snapshot + - is_true: responses.0.error + - match: { responses.0.error.type: snapshot_missing_exception } + --- "Get missing snapshot info succeeds when ignore_unavailable is true": + - skip: + version: " - 7.9.99" + reason: "8.0 changes get snapshots response format" - do: snapshot.get: @@ -57,10 +68,14 @@ setup: snapshot: test_nonexistent_snapshot ignore_unavailable: true - - is_true: snapshots + - is_true: responses.0.snapshots --- "Get snapshot info when verbose is false": + - skip: + version: " - 7.9.99" + reason: "8.0 changes get snapshots response format" + - do: indices.create: index: test_index @@ -81,13 +96,13 @@ setup: snapshot: test_snapshot verbose: false - - is_true: snapshots - - match: { snapshots.0.snapshot: test_snapshot } - - match: { snapshots.0.state: SUCCESS } - - is_false: snapshots.0.failures - - is_false: snapshots.0.shards - - is_false: snapshots.0.version - - is_false: snapshots.0._meta + - is_true: responses.0.snapshots + - match: { responses.0.snapshots.0.snapshot: test_snapshot } + - match: { responses.0.snapshots.0.state: SUCCESS } + - is_false: responses.0.snapshots.0.failures + - is_false: responses.0.snapshots.0.shards + - is_false: responses.0.snapshots.0.version + - is_false: responses.0.snapshots.0._meta - do: snapshot.delete: @@ -96,6 +111,9 @@ setup: --- "Get snapshot info contains include_global_state": + - skip: + version: " - 7.9.99" + reason: "8.0 changes get snapshots response format" - do: indices.create: @@ -118,10 +136,10 @@ setup: repository: test_repo_get_1 snapshot: test_snapshot_with_include_global_state - - is_true: snapshots - - match: { snapshots.0.snapshot: test_snapshot_with_include_global_state } - - match: { snapshots.0.state: SUCCESS } - - match: { snapshots.0.include_global_state: true } + - is_true: responses.0.snapshots + - match: { responses.0.snapshots.0.snapshot: test_snapshot_with_include_global_state } + - match: { responses.0.snapshots.0.state: SUCCESS } + - match: { responses.0.snapshots.0.include_global_state: true } - do: snapshot.delete: @@ -141,10 +159,10 @@ setup: repository: test_repo_get_1 snapshot: test_snapshot_without_include_global_state - - is_true: snapshots - - match: { snapshots.0.snapshot: test_snapshot_without_include_global_state } - - match: { snapshots.0.state: SUCCESS } - - match: { snapshots.0.include_global_state: false } + - is_true: responses.0.snapshots + - match: { responses.0.snapshots.0.snapshot: test_snapshot_without_include_global_state } + - match: { responses.0.snapshots.0.state: SUCCESS } + - match: { responses.0.snapshots.0.include_global_state: false } - do: snapshot.delete: @@ -154,8 +172,8 @@ setup: --- "Get snapshot info with metadata": - skip: - version: " - 7.2.99" - reason: "metadata field was added in 7.3" + version: " - 7.9.99" + reason: "8.0 changes get snapshots response format" - do: indices.create: @@ -178,11 +196,11 @@ setup: repository: test_repo_get_1 snapshot: test_snapshot_with_metadata - - is_true: snapshots - - match: { snapshots.0.snapshot: test_snapshot_with_metadata } - - match: { snapshots.0.state: SUCCESS } - - match: { snapshots.0.metadata.taken_by: test } - - match: { snapshots.0.metadata.foo.bar: baz } + - is_true: responses.0.snapshots + - match: { responses.0.snapshots.0.snapshot: test_snapshot_with_metadata } + - match: { responses.0.snapshots.0.state: SUCCESS } + - match: { responses.0.snapshots.0.metadata.taken_by: test } + - match: { responses.0.snapshots.0.metadata.foo.bar: baz } - do: snapshot.delete: diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/get/GetRepositoriesAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/get/GetRepositoriesAction.java index d89e466461d9b..eac4d971b60a1 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/get/GetRepositoriesAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/get/GetRepositoriesAction.java @@ -20,6 +20,7 @@ package org.elasticsearch.action.admin.cluster.repositories.get; import org.elasticsearch.action.Action; +import org.elasticsearch.common.io.stream.Writeable; /** * Get repositories action @@ -35,7 +36,12 @@ private GetRepositoriesAction() { @Override public GetRepositoriesResponse newResponse() { - return new GetRepositoriesResponse(); + throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable"); + } + + @Override + public Writeable.Reader getResponseReader() { + return GetRepositoriesResponse::new; } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/get/GetRepositoriesResponse.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/get/GetRepositoriesResponse.java index 24228aa565871..4fb9cbaebe941 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/get/GetRepositoriesResponse.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/get/GetRepositoriesResponse.java @@ -29,7 +29,6 @@ import org.elasticsearch.common.xcontent.XContentParser; import java.io.IOException; -import java.util.Collections; import java.util.List; import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken; @@ -39,16 +38,16 @@ */ public class GetRepositoriesResponse extends ActionResponse implements ToXContentObject { - private RepositoriesMetaData repositories; - - GetRepositoriesResponse() { - repositories = new RepositoriesMetaData(Collections.emptyList()); - } + private final RepositoriesMetaData repositories; GetRepositoriesResponse(RepositoriesMetaData repositories) { this.repositories = repositories; } + public GetRepositoriesResponse(StreamInput in) throws IOException { + repositories = new RepositoriesMetaData(in); + } + /** * List of repositories to return * @@ -61,7 +60,7 @@ public List repositories() { @Override public void readFrom(StreamInput in) throws IOException { - repositories = new RepositoriesMetaData(in); + throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable"); } @Override diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/get/TransportGetRepositoriesAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/get/TransportGetRepositoriesAction.java index 4b3ee1cd9251a..c626a17a13ead 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/get/TransportGetRepositoriesAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/get/TransportGetRepositoriesAction.java @@ -31,11 +31,13 @@ import org.elasticsearch.cluster.metadata.RepositoryMetaData; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.repositories.RepositoryMissingException; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; +import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashSet; @@ -62,7 +64,12 @@ protected String executor() { @Override protected GetRepositoriesResponse newResponse() { - return new GetRepositoriesResponse(); + throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable"); + } + + @Override + protected GetRepositoriesResponse read(StreamInput in) throws IOException { + return new GetRepositoriesResponse(in); } @Override diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsAction.java index b5015ff5c23b0..b77130f1875be 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsAction.java @@ -20,6 +20,7 @@ package org.elasticsearch.action.admin.cluster.snapshots.get; import org.elasticsearch.action.Action; +import org.elasticsearch.common.io.stream.Writeable; /** * Get snapshots action @@ -35,7 +36,12 @@ private GetSnapshotsAction() { @Override public GetSnapshotsResponse newResponse() { - return new GetSnapshotsResponse(); + throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable"); + } + + @Override + public Writeable.Reader getResponseReader() { + return GetSnapshotsResponse::new; } } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsRequest.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsRequest.java index 41ae57031d320..4bfd656700684 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsRequest.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsRequest.java @@ -19,6 +19,7 @@ package org.elasticsearch.action.admin.cluster.snapshots.get; +import org.elasticsearch.Version; import org.elasticsearch.action.ActionRequestValidationException; import org.elasticsearch.action.support.master.MasterNodeRequest; import org.elasticsearch.common.Strings; @@ -37,8 +38,9 @@ public class GetSnapshotsRequest extends MasterNodeRequest public static final String ALL_SNAPSHOTS = "_all"; public static final String CURRENT_SNAPSHOT = "_current"; public static final boolean DEFAULT_VERBOSE_MODE = true; + public static final Version MULTIPLE_REPOSITORIES_SUPPORT_ADDED = Version.V_8_0_0; - private String repository; + private String[] repositories; private String[] snapshots = Strings.EMPTY_ARRAY; @@ -50,28 +52,32 @@ public GetSnapshotsRequest() { } /** - * Constructs a new get snapshots request with given repository name and list of snapshots + * Constructs a new get snapshots request with given repository names and list of snapshots * - * @param repository repository name + * @param repositories repository names * @param snapshots list of snapshots */ - public GetSnapshotsRequest(String repository, String[] snapshots) { - this.repository = repository; + public GetSnapshotsRequest(String[] repositories, String[] snapshots) { + this.repositories = repositories; this.snapshots = snapshots; } /** - * Constructs a new get snapshots request with given repository name + * Constructs a new get snapshots request with given repository names * - * @param repository repository name + * @param repositories repository names */ - public GetSnapshotsRequest(String repository) { - this.repository = repository; + public GetSnapshotsRequest(String... repositories) { + this.repositories = repositories; } public GetSnapshotsRequest(StreamInput in) throws IOException { super(in); - repository = in.readString(); + if (in.getVersion().onOrAfter(MULTIPLE_REPOSITORIES_SUPPORT_ADDED)) { + repositories = in.readStringArray(); + } else { + repositories = new String[]{in.readString()}; + } snapshots = in.readStringArray(); ignoreUnavailable = in.readBoolean(); verbose = in.readBoolean(); @@ -80,7 +86,15 @@ public GetSnapshotsRequest(StreamInput in) throws IOException { @Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); - out.writeString(repository); + if (out.getVersion().onOrAfter(MULTIPLE_REPOSITORIES_SUPPORT_ADDED)) { + out.writeStringArray(repositories); + } else { + if (repositories.length != 1) { + throw new IllegalArgumentException("Requesting snapshots from multiple repositories is not supported in versions prior " + + "to " + MULTIPLE_REPOSITORIES_SUPPORT_ADDED.toString()); + } + out.writeString(repositories[0]); + } out.writeStringArray(snapshots); out.writeBoolean(ignoreUnavailable); out.writeBoolean(verbose); @@ -89,30 +103,30 @@ public void writeTo(StreamOutput out) throws IOException { @Override public ActionRequestValidationException validate() { ActionRequestValidationException validationException = null; - if (repository == null) { - validationException = addValidationError("repository is missing", validationException); + if (repositories == null || repositories.length == 0) { + validationException = addValidationError("repositories are missing", validationException); } return validationException; } /** - * Sets repository name + * Sets repository names * - * @param repository repository name + * @param repositories repository names * @return this request */ - public GetSnapshotsRequest repository(String repository) { - this.repository = repository; + public GetSnapshotsRequest repositories(String... repositories) { + this.repositories = repositories; return this; } /** - * Returns repository name + * Returns repository names * - * @return repository name + * @return repository names */ - public String repository() { - return this.repository; + public String[] repositories() { + return this.repositories; } /** @@ -176,4 +190,4 @@ public boolean verbose() { public void readFrom(StreamInput in) throws IOException { throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable"); } -} +} \ No newline at end of file diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsRequestBuilder.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsRequestBuilder.java index 052f8da0c7508..e4219c858551a 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsRequestBuilder.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsRequestBuilder.java @@ -30,27 +30,20 @@ public class GetSnapshotsRequestBuilder extends MasterNodeOperationRequestBuilde GetSnapshotsResponse, GetSnapshotsRequestBuilder> { /** - * Constructs the new get snapshot request + * Constructs the new get snapshot request with specified repositories */ - public GetSnapshotsRequestBuilder(ElasticsearchClient client, GetSnapshotsAction action) { - super(client, action, new GetSnapshotsRequest()); + public GetSnapshotsRequestBuilder(ElasticsearchClient client, GetSnapshotsAction action, String... repositories) { + super(client, action, new GetSnapshotsRequest(repositories)); } /** - * Constructs the new get snapshot request with specified repository - */ - public GetSnapshotsRequestBuilder(ElasticsearchClient client, GetSnapshotsAction action, String repository) { - super(client, action, new GetSnapshotsRequest(repository)); - } - - /** - * Sets the repository name + * Sets the repository names * - * @param repository repository name + * @param repositories repository names * @return this builder */ - public GetSnapshotsRequestBuilder setRepository(String repository) { - request.repository(repository); + public GetSnapshotsRequestBuilder setRepositories(String... repositories) { + request.repositories(repositories); return this; } diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsResponse.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsResponse.java index 62ddc5b7d9df3..1ecbd222c6d84 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsResponse.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsResponse.java @@ -19,13 +19,14 @@ package org.elasticsearch.action.admin.cluster.snapshots.get; +import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.ActionResponse; import org.elasticsearch.common.ParseField; import org.elasticsearch.common.Strings; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.util.set.Sets; import org.elasticsearch.common.xcontent.ConstructingObjectParser; -import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContentObject; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; @@ -33,94 +34,241 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; -import java.util.Objects; +import java.util.Map; +import java.util.Set; /** * Get snapshots response */ public class GetSnapshotsResponse extends ActionResponse implements ToXContentObject { - @SuppressWarnings("unchecked") - private static final ConstructingObjectParser GET_SNAPSHOT_PARSER = - new ConstructingObjectParser<>(GetSnapshotsResponse.class.getName(), true, - (args) -> new GetSnapshotsResponse((List) args[0])); + private static final ConstructingObjectParser PARSER = + new ConstructingObjectParser<>(GetSnapshotsResponse.class.getName(), true, + (args) -> new GetSnapshotsResponse((List) args[0])); static { - GET_SNAPSHOT_PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), - (p, c) -> SnapshotInfo.SNAPSHOT_INFO_PARSER.apply(p, c).build(), new ParseField("snapshots")); + PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), + (p, c) -> Response.fromXContent(p), new ParseField("responses")); } - private List snapshots = Collections.emptyList(); + public GetSnapshotsResponse(StreamInput in) throws IOException { + if (in.getVersion().onOrAfter(GetSnapshotsRequest.MULTIPLE_REPOSITORIES_SUPPORT_ADDED)) { + int successfulSize = in.readVInt(); + Map> successfulResponses = new HashMap<>(successfulSize); + for (int i = 0; i < successfulSize; i++) { + String repository = in.readString(); + int size = in.readVInt(); + List snapshotInfos = new ArrayList<>(size); + for (int j = 0; j < size; j++) { + snapshotInfos.add(new SnapshotInfo(in)); + } + successfulResponses.put(repository, snapshotInfos); + } - GetSnapshotsResponse() { + int failedSize = in.readVInt(); + Map failedResponses = new HashMap<>(failedSize); + for (int i = 0; i < failedSize; i++) { + String repository = in.readString(); + ElasticsearchException error = in.readException(); + failedResponses.put(repository, error); + } + this.successfulResponses = Collections.unmodifiableMap(successfulResponses); + this.failedResponses = Collections.unmodifiableMap(failedResponses); + } else { + int size = in.readVInt(); + List snapshots = new ArrayList<>(size); + for (int i = 0; i < size; i++) { + snapshots.add(new SnapshotInfo(in)); + } + this.successfulResponses = Collections.singletonMap("unknown", snapshots); + this.failedResponses = Collections.emptyMap(); + } + } + + + public static class Response { + private String repository; + private List snapshots; + private ElasticsearchException error; + + private static final ConstructingObjectParser RESPONSE_PARSER = + new ConstructingObjectParser<>(Response.class.getName(), true, + (args) -> new Response((String) args[0], + (List) args[1], (ElasticsearchException) args[2])); + + static { + RESPONSE_PARSER.declareString(ConstructingObjectParser.constructorArg(), new ParseField("repository")); + RESPONSE_PARSER.declareObjectArray(ConstructingObjectParser.optionalConstructorArg(), + (p, c) -> SnapshotInfo.SNAPSHOT_INFO_PARSER.apply(p, c).build(), new ParseField("snapshots")); + RESPONSE_PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), + (p, c) -> ElasticsearchException.fromXContent(p), new ParseField("error")); + } + + private Response(String repository, List snapshots, ElasticsearchException error) { + this.repository = repository; + this.snapshots = snapshots; + this.error = error; + } + + public static Response snapshots(String repository, List snapshots) { + return new Response(repository, snapshots, null); + } + + public static Response error(String repository, ElasticsearchException error) { + return new Response(repository, null, error); + } + + private static Response fromXContent(XContentParser parser) throws IOException { + return RESPONSE_PARSER.parse(parser, null); + } } - GetSnapshotsResponse(List snapshots) { - this.snapshots = Collections.unmodifiableList(snapshots); + private final Map> successfulResponses; + private final Map failedResponses; + + public GetSnapshotsResponse(Collection responses) { + Map> successfulResponses = new HashMap<>(); + Map failedResponses = new HashMap<>(); + for (Response response : responses) { + if (response.snapshots != null) { + assert response.error == null; + successfulResponses.put(response.repository, response.snapshots); + } else { + assert response.snapshots == null; + failedResponses.put(response.repository, response.error); + } + } + this.successfulResponses = Collections.unmodifiableMap(successfulResponses); + this.failedResponses = Collections.unmodifiableMap(failedResponses); } /** - * Returns the list of snapshots - * - * @return the list of snapshots + * Returns list of snapshots for the specified repository. + * @param repo - repository name. + * @return list of snapshots. + * @throws IllegalArgumentException if there is no such repository in the response. + * @throws ElasticsearchException if an exception occurred when retrieving snapshots from the repository. */ - public List getSnapshots() { - return snapshots; + public List getSnapshots(String repo) { + List snapshots = successfulResponses.get(repo); + if (snapshots != null) { + return snapshots; + } + ElasticsearchException error = failedResponses.get(repo); + if (error == null) { + throw new IllegalArgumentException("No such repository"); + } + throw error; } - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - int size = in.readVInt(); - List builder = new ArrayList<>(size); - for (int i = 0; i < size; i++) { - builder.add(new SnapshotInfo(in)); - } - snapshots = Collections.unmodifiableList(builder); + /** + * Returns list of repositories for both successful and unsuccessful responses. + */ + public Set getRepositories() { + return Sets.union(successfulResponses.keySet(), failedResponses.keySet()); } - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeVInt(snapshots.size()); - for (SnapshotInfo snapshotInfo : snapshots) { - snapshotInfo.writeTo(out); - } + /** + * Returns a map of repository name to the list of {@link SnapshotInfo} for each successful response. + */ + public Map> getSuccessfulResponses() { + return successfulResponses; + } + + /** + * Returns a map of repository name to {@link ElasticsearchException} for each unsuccessful response. + */ + public Map getFailedResponses() { + return failedResponses; + } + + /** + * Returns true if there is a least one failed response. + */ + public boolean isFailed() { + return failedResponses.isEmpty() == false; } @Override - public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException { + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(); - builder.startArray("snapshots"); - for (SnapshotInfo snapshotInfo : snapshots) { - snapshotInfo.toXContent(builder, params); + builder.startArray("responses"); + + for (Map.Entry> snapshots : successfulResponses.entrySet()) { + builder.startObject(); + builder.field("repository", snapshots.getKey()); + builder.startArray("snapshots"); + for (SnapshotInfo snapshot : snapshots.getValue()) { + snapshot.toXContent(builder, params); + } + builder.endArray(); + builder.endObject(); } + + for (Map.Entry error : failedResponses.entrySet()) { + builder.startObject(); + builder.field("repository", error.getKey()); + ElasticsearchException.generateFailureXContent(builder, params, error.getValue(), true); + builder.endObject(); + } + builder.endArray(); builder.endObject(); return builder; } - public static GetSnapshotsResponse fromXContent(XContentParser parser) throws IOException { - return GET_SNAPSHOT_PARSER.parse(parser, null); + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + if (out.getVersion().onOrAfter(GetSnapshotsRequest.MULTIPLE_REPOSITORIES_SUPPORT_ADDED)) { + out.writeVInt(successfulResponses.size()); + for (Map.Entry> snapshots : successfulResponses.entrySet()) { + out.writeString(snapshots.getKey()); + out.writeVInt(snapshots.getValue().size()); + for (SnapshotInfo snapshotInfo : snapshots.getValue()) { + snapshotInfo.writeTo(out); + } + } + out.writeVInt(failedResponses.size()); + for (Map.Entry error : failedResponses.entrySet()) { + out.writeString(error.getKey()); + out.writeException(error.getValue()); + } + } else { + if (successfulResponses.size() + failedResponses.size() != 1) { + throw new IllegalArgumentException("Requesting snapshots from multiple repositories is not supported in versions prior " + + "to " + GetSnapshotsRequest.MULTIPLE_REPOSITORIES_SUPPORT_ADDED.toString()); + } + + if (successfulResponses.size() == 1) { + List snapshotInfos = successfulResponses.values().iterator().next(); + out.writeVInt(snapshotInfos.size()); + for (SnapshotInfo snapshotInfo : snapshotInfos) { + snapshotInfo.writeTo(out); + } + } + + if (failedResponses.isEmpty() == false) { + throw failedResponses.values().iterator().next(); + } + } } @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - GetSnapshotsResponse that = (GetSnapshotsResponse) o; - return Objects.equals(snapshots, that.snapshots); + public void readFrom(StreamInput in) throws IOException { + throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable"); } - @Override - public int hashCode() { - return Objects.hash(snapshots); + public static GetSnapshotsResponse fromXContent(XContentParser parser) throws IOException { + return PARSER.parse(parser, null); } @Override public String toString() { return Strings.toString(this); } -} +} \ No newline at end of file diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/TransportGetSnapshotsAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/TransportGetSnapshotsAction.java index 23ffbd0dd1e3c..246b9c8fe132c 100644 --- a/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/TransportGetSnapshotsAction.java +++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/TransportGetSnapshotsAction.java @@ -20,15 +20,24 @@ package org.elasticsearch.action.admin.cluster.snapshots.get; import org.apache.lucene.util.CollectionUtil; +import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.ActionListenerResponseHandler; +import org.elasticsearch.action.ActionRunnable; +import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesAction; +import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesRequest; +import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesResponse; import org.elasticsearch.action.support.ActionFilters; +import org.elasticsearch.action.support.GroupedActionListener; import org.elasticsearch.action.support.master.TransportMasterNodeAction; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.block.ClusterBlockException; import org.elasticsearch.cluster.block.ClusterBlockLevel; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; +import org.elasticsearch.cluster.metadata.RepositoryMetaData; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.repositories.IndexId; import org.elasticsearch.repositories.RepositoryData; @@ -39,6 +48,7 @@ import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; +import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -70,7 +80,12 @@ protected String executor() { @Override protected GetSnapshotsResponse newResponse() { - return new GetSnapshotsResponse(); + throw new UnsupportedOperationException("usage of Streamable is to be replaced by Writeable"); + } + + @Override + protected GetSnapshotsResponse read(StreamInput in) throws IOException { + return new GetSnapshotsResponse(in); } @Override @@ -81,73 +96,109 @@ protected ClusterBlockException checkBlock(GetSnapshotsRequest request, ClusterS @Override protected void masterOperation(final GetSnapshotsRequest request, final ClusterState state, final ActionListener listener) { - try { - final String repository = request.repository(); - final Map allSnapshotIds = new HashMap<>(); - final List currentSnapshots = new ArrayList<>(); - for (SnapshotInfo snapshotInfo : snapshotsService.currentSnapshots(repository)) { - SnapshotId snapshotId = snapshotInfo.snapshotId(); - allSnapshotIds.put(snapshotId.getName(), snapshotId); - currentSnapshots.add(snapshotInfo); - } + final String[] repositories = request.repositories(); + transportService.sendRequest(transportService.getLocalNode(), GetRepositoriesAction.NAME, + new GetRepositoriesRequest(repositories), + new ActionListenerResponseHandler<>( + ActionListener.wrap( + response -> + // switch to GENERIC thread pool because it might be long running operation + threadPool.executor(ThreadPool.Names.GENERIC).execute( + () -> getMultipleReposSnapshotInfo(response.repositories(), request.snapshots(), + request.ignoreUnavailable(), request.verbose(), listener)), + listener::onFailure), + GetRepositoriesResponse::new)); + } - final RepositoryData repositoryData; - if (isCurrentSnapshotsOnly(request.snapshots()) == false) { - repositoryData = snapshotsService.getRepositoryData(repository); - for (SnapshotId snapshotId : repositoryData.getAllSnapshotIds()) { - allSnapshotIds.put(snapshotId.getName(), snapshotId); + private void getMultipleReposSnapshotInfo(List repos, String[] snapshots, boolean ignoreUnavailable, + boolean verbose, ActionListener listener) { + final GroupedActionListener groupedActionListener = + new GroupedActionListener<>( + ActionListener.map(listener, responses -> { + assert repos.size() == responses.size(); + return new GetSnapshotsResponse(responses); + }), repos.size()); + + // run concurrently for all repos on GENERIC thread pool + for (final RepositoryMetaData repo : repos) { + threadPool.executor(ThreadPool.Names.GENERIC).execute(new ActionRunnable<>(groupedActionListener) { + @Override + protected void doRun() { + try { + groupedActionListener.onResponse(GetSnapshotsResponse.Response.snapshots( + repo.name(), getSingleRepoSnapshotInfo(repo.name(), snapshots, ignoreUnavailable, verbose))); + } catch (ElasticsearchException e) { + groupedActionListener.onResponse(GetSnapshotsResponse.Response.error(repo.name(), e)); + } } - } else { - repositoryData = null; + }); + } + } + + private List getSingleRepoSnapshotInfo(String repo, String[] snapshots, boolean ignoreUnavailable, boolean verbose) { + final Map allSnapshotIds = new HashMap<>(); + final List currentSnapshots = new ArrayList<>(); + for (SnapshotInfo snapshotInfo : snapshotsService.currentSnapshots(repo)) { + SnapshotId snapshotId = snapshotInfo.snapshotId(); + allSnapshotIds.put(snapshotId.getName(), snapshotId); + currentSnapshots.add(snapshotInfo); + } + + final RepositoryData repositoryData; + if (isCurrentSnapshotsOnly(snapshots) == false) { + repositoryData = snapshotsService.getRepositoryData(repo); + for (SnapshotId snapshotId : repositoryData.getAllSnapshotIds()) { + allSnapshotIds.put(snapshotId.getName(), snapshotId); } + } else { + repositoryData = null; + } - final Set toResolve = new HashSet<>(); - if (isAllSnapshots(request.snapshots())) { - toResolve.addAll(allSnapshotIds.values()); - } else { - for (String snapshotOrPattern : request.snapshots()) { - if (GetSnapshotsRequest.CURRENT_SNAPSHOT.equalsIgnoreCase(snapshotOrPattern)) { - toResolve.addAll(currentSnapshots.stream().map(SnapshotInfo::snapshotId).collect(Collectors.toList())); - } else if (Regex.isSimpleMatchPattern(snapshotOrPattern) == false) { - if (allSnapshotIds.containsKey(snapshotOrPattern)) { - toResolve.add(allSnapshotIds.get(snapshotOrPattern)); - } else if (request.ignoreUnavailable() == false) { - throw new SnapshotMissingException(repository, snapshotOrPattern); - } - } else { - for (Map.Entry entry : allSnapshotIds.entrySet()) { - if (Regex.simpleMatch(snapshotOrPattern, entry.getKey())) { - toResolve.add(entry.getValue()); - } + final Set toResolve = new HashSet<>(); + if (isAllSnapshots(snapshots)) { + toResolve.addAll(allSnapshotIds.values()); + } else { + for (String snapshotOrPattern : snapshots) { + if (GetSnapshotsRequest.CURRENT_SNAPSHOT.equalsIgnoreCase(snapshotOrPattern)) { + toResolve.addAll(currentSnapshots.stream().map(SnapshotInfo::snapshotId).collect(Collectors.toList())); + } else if (Regex.isSimpleMatchPattern(snapshotOrPattern) == false) { + if (allSnapshotIds.containsKey(snapshotOrPattern)) { + toResolve.add(allSnapshotIds.get(snapshotOrPattern)); + } else if (ignoreUnavailable == false) { + throw new SnapshotMissingException(repo, snapshotOrPattern); + } + } else { + for (Map.Entry entry : allSnapshotIds.entrySet()) { + if (Regex.simpleMatch(snapshotOrPattern, entry.getKey())) { + toResolve.add(entry.getValue()); } } } + } - if (toResolve.isEmpty() && request.ignoreUnavailable() == false && isCurrentSnapshotsOnly(request.snapshots()) == false) { - throw new SnapshotMissingException(repository, request.snapshots()[0]); - } + if (toResolve.isEmpty() && ignoreUnavailable == false && isCurrentSnapshotsOnly(snapshots) == false) { + throw new SnapshotMissingException(repo, snapshots[0]); } + } - final List snapshotInfos; - if (request.verbose()) { - final Set incompatibleSnapshots = repositoryData != null ? + final List snapshotInfos; + if (verbose) { + final Set incompatibleSnapshots = repositoryData != null ? new HashSet<>(repositoryData.getIncompatibleSnapshotIds()) : Collections.emptySet(); - snapshotInfos = snapshotsService.snapshots(repository, new ArrayList<>(toResolve), - incompatibleSnapshots, request.ignoreUnavailable()); + snapshotInfos = snapshotsService.snapshots(repo, new ArrayList<>(toResolve), + incompatibleSnapshots, ignoreUnavailable); + } else { + if (repositoryData != null) { + // want non-current snapshots as well, which are found in the repository data + snapshotInfos = buildSimpleSnapshotInfos(toResolve, repositoryData, currentSnapshots); } else { - if (repositoryData != null) { - // want non-current snapshots as well, which are found in the repository data - snapshotInfos = buildSimpleSnapshotInfos(toResolve, repositoryData, currentSnapshots); - } else { - // only want current snapshots - snapshotInfos = currentSnapshots.stream().map(SnapshotInfo::basic).collect(Collectors.toList()); - CollectionUtil.timSort(snapshotInfos); - } + // only want current snapshots + snapshotInfos = currentSnapshots.stream().map(SnapshotInfo::basic).collect(Collectors.toList()); + CollectionUtil.timSort(snapshotInfos); } - listener.onResponse(new GetSnapshotsResponse(snapshotInfos)); - } catch (Exception e) { - listener.onFailure(e); } + + return snapshotInfos; } private boolean isAllSnapshots(String[] snapshots) { @@ -158,7 +209,7 @@ private boolean isCurrentSnapshotsOnly(String[] snapshots) { return (snapshots.length == 1 && GetSnapshotsRequest.CURRENT_SNAPSHOT.equalsIgnoreCase(snapshots[0])); } - private List buildSimpleSnapshotInfos(final Set toResolve, + private static List buildSimpleSnapshotInfos(final Set toResolve, final RepositoryData repositoryData, final List currentSnapshots) { List snapshotInfos = new ArrayList<>(); @@ -172,7 +223,7 @@ private List buildSimpleSnapshotInfos(final Set toReso for (SnapshotId snapshotId : repositoryData.getSnapshots(indexId)) { if (toResolve.contains(snapshotId)) { snapshotsToIndices.computeIfAbsent(snapshotId, (k) -> new ArrayList<>()) - .add(indexId.getName()); + .add(indexId.getName()); } } } diff --git a/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java b/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java index 42aaed10d6172..cd874b62a40b4 100644 --- a/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java +++ b/server/src/main/java/org/elasticsearch/client/ClusterAdminClient.java @@ -484,19 +484,19 @@ public interface ClusterAdminClient extends ElasticsearchClient { CreateSnapshotRequestBuilder prepareCreateSnapshot(String repository, String name); /** - * Get snapshot. + * Get snapshots. */ ActionFuture getSnapshots(GetSnapshotsRequest request); /** - * Get snapshot. + * Get snapshots. */ void getSnapshots(GetSnapshotsRequest request, ActionListener listener); /** - * Get snapshot. + * Get snapshots. */ - GetSnapshotsRequestBuilder prepareGetSnapshots(String repository); + GetSnapshotsRequestBuilder prepareGetSnapshots(String... repository); /** * Delete snapshot. diff --git a/server/src/main/java/org/elasticsearch/client/Requests.java b/server/src/main/java/org/elasticsearch/client/Requests.java index 19ad2fb397edc..3e4ac2eafed59 100644 --- a/server/src/main/java/org/elasticsearch/client/Requests.java +++ b/server/src/main/java/org/elasticsearch/client/Requests.java @@ -494,13 +494,13 @@ public static CreateSnapshotRequest createSnapshotRequest(String repository, Str } /** - * Gets snapshots from repository + * Gets snapshots from repositories * - * @param repository repository name + * @param repositories repository names * @return get snapshot request */ - public static GetSnapshotsRequest getSnapshotsRequest(String repository) { - return new GetSnapshotsRequest(repository); + public static GetSnapshotsRequest getSnapshotsRequest(String... repositories) { + return new GetSnapshotsRequest(repositories); } /** diff --git a/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java b/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java index c936e931b5889..02f267a82fba9 100644 --- a/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java +++ b/server/src/main/java/org/elasticsearch/client/support/AbstractClient.java @@ -949,8 +949,8 @@ public void getSnapshots(GetSnapshotsRequest request, ActionListener - client.admin().cluster().getSnapshots(getSnapshotsRequest, new RestResponseListener(channel) { + client.admin().cluster().getSnapshots(getSnapshotsRequest, new RestResponseListener<>(channel) { @Override public RestResponse buildResponse(GetSnapshotsResponse getSnapshotsResponse) throws Exception { return RestTable.buildResponse(buildTable(request, getSnapshotsResponse), channel); @@ -84,6 +88,7 @@ protected Table getTableWithHeader(RestRequest request) { return new Table() .startHeaders() .addCell("id", "alias:id,snapshot;desc:unique snapshot") + .addCell("repository", "alias:re,repo;desc:repository name") .addCell("status", "alias:s,status;text-align:right;desc:snapshot name") .addCell("start_epoch", "alias:ste,startEpoch;desc:start time in seconds since 1970-01-01 00:00:00") .addCell("start_time", "alias:sti,startTime;desc:start time in HH:MM:SS") @@ -102,29 +107,50 @@ protected Table getTableWithHeader(RestRequest request) { private Table buildTable(RestRequest req, GetSnapshotsResponse getSnapshotsResponse) { Table table = getTableWithHeader(req); - for (SnapshotInfo snapshotStatus : getSnapshotsResponse.getSnapshots()) { - table.startRow(); - - table.addCell(snapshotStatus.snapshotId().getName()); - table.addCell(snapshotStatus.state()); - table.addCell(TimeUnit.SECONDS.convert(snapshotStatus.startTime(), TimeUnit.MILLISECONDS)); - table.addCell(FORMATTER.format(Instant.ofEpochMilli(snapshotStatus.startTime()))); - table.addCell(TimeUnit.SECONDS.convert(snapshotStatus.endTime(), TimeUnit.MILLISECONDS)); - table.addCell(FORMATTER.format(Instant.ofEpochMilli(snapshotStatus.endTime()))); - final long durationMillis; - if (snapshotStatus.state() == SnapshotState.IN_PROGRESS) { - durationMillis = System.currentTimeMillis() - snapshotStatus.startTime(); - } else { - durationMillis = snapshotStatus.endTime() - snapshotStatus.startTime(); + + if (getSnapshotsResponse.isFailed()) { + ElasticsearchException causes = null; + + for (ElasticsearchException e : getSnapshotsResponse.getFailedResponses().values()) { + if (causes == null) { + causes = e; + } else { + causes.addSuppressed(e); + } + } + throw new ElasticsearchException( + "Repositories [" + + Strings.collectionToCommaDelimitedString(getSnapshotsResponse.getFailedResponses().keySet()) + + "] failed to retrieve snapshots", causes); + } + + for (Map.Entry> response : getSnapshotsResponse.getSuccessfulResponses().entrySet()) { + String repository = response.getKey(); + for (SnapshotInfo snapshotStatus : response.getValue()) { + table.startRow(); + + table.addCell(snapshotStatus.snapshotId().getName()); + table.addCell(repository); + table.addCell(snapshotStatus.state()); + table.addCell(TimeUnit.SECONDS.convert(snapshotStatus.startTime(), TimeUnit.MILLISECONDS)); + table.addCell(FORMATTER.format(Instant.ofEpochMilli(snapshotStatus.startTime()))); + table.addCell(TimeUnit.SECONDS.convert(snapshotStatus.endTime(), TimeUnit.MILLISECONDS)); + table.addCell(FORMATTER.format(Instant.ofEpochMilli(snapshotStatus.endTime()))); + final long durationMillis; + if (snapshotStatus.state() == SnapshotState.IN_PROGRESS) { + durationMillis = System.currentTimeMillis() - snapshotStatus.startTime(); + } else { + durationMillis = snapshotStatus.endTime() - snapshotStatus.startTime(); + } + table.addCell(TimeValue.timeValueMillis(durationMillis)); + table.addCell(snapshotStatus.indices().size()); + table.addCell(snapshotStatus.successfulShards()); + table.addCell(snapshotStatus.failedShards()); + table.addCell(snapshotStatus.totalShards()); + table.addCell(snapshotStatus.reason()); + + table.endRow(); } - table.addCell(TimeValue.timeValueMillis(durationMillis)); - table.addCell(snapshotStatus.indices().size()); - table.addCell(snapshotStatus.successfulShards()); - table.addCell(snapshotStatus.failedShards()); - table.addCell(snapshotStatus.totalShards()); - table.addCell(snapshotStatus.reason()); - - table.endRow(); } return table; diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java index 7dac3a38dddd7..2ab9f7d89824b 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java @@ -157,8 +157,8 @@ public void testGetSnapshotWithBlocks() { try { setClusterReadOnly(true); GetSnapshotsResponse response = client().admin().cluster().prepareGetSnapshots(REPOSITORY_NAME).execute().actionGet(); - assertThat(response.getSnapshots(), hasSize(1)); - assertThat(response.getSnapshots().get(0).snapshotId().getName(), equalTo(SNAPSHOT_NAME)); + assertThat(response.getSnapshots(REPOSITORY_NAME), hasSize(1)); + assertThat(response.getSnapshots(REPOSITORY_NAME).get(0).snapshotId().getName(), equalTo(SNAPSHOT_NAME)); } finally { setClusterReadOnly(false); } diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsResponseTests.java index 2113fc7504305..081db2e5383c9 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsResponseTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/get/GetSnapshotsResponseTests.java @@ -19,59 +19,121 @@ package org.elasticsearch.action.admin.cluster.snapshots.get; +import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.Version; +import org.elasticsearch.common.Strings; import org.elasticsearch.common.UUIDs; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.shard.ShardId; import org.elasticsearch.snapshots.SnapshotId; import org.elasticsearch.snapshots.SnapshotInfo; import org.elasticsearch.snapshots.SnapshotInfoTests; import org.elasticsearch.snapshots.SnapshotShardFailure; -import org.elasticsearch.test.AbstractStreamableXContentTestCase; +import org.elasticsearch.test.ESTestCase; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.function.Predicate; import java.util.regex.Pattern; -public class GetSnapshotsResponseTests extends AbstractStreamableXContentTestCase { +import static org.elasticsearch.test.AbstractXContentTestCase.xContentTester; +import static org.hamcrest.CoreMatchers.containsString; - @Override - protected GetSnapshotsResponse doParseInstance(XContentParser parser) throws IOException { +public class GetSnapshotsResponseTests extends ESTestCase { + // We can not subclass AbstractStreamableXContentTestCase because it + // can only be used for instances with equals and hashCode + // GetSnapshotResponse does not override equals and hashCode. + // It does not override equals and hashCode, because it + // contains ElasticsearchException, which does not override equals and hashCode. + + private GetSnapshotsResponse doParseInstance(XContentParser parser) throws IOException { return GetSnapshotsResponse.fromXContent(parser); } - @Override - protected GetSnapshotsResponse createBlankInstance() { - return new GetSnapshotsResponse(); + private GetSnapshotsResponse copyInstance(GetSnapshotsResponse instance, Version version) throws IOException { + return copyInstance(instance, new NamedWriteableRegistry(Collections.emptyList()), (out, value) -> value.writeTo(out), + in -> new GetSnapshotsResponse(in), version); + + } + + private void assertEqualInstances(GetSnapshotsResponse expectedInstance, GetSnapshotsResponse newInstance) { + assertEquals(expectedInstance.getSuccessfulResponses(), newInstance.getSuccessfulResponses()); + assertEquals(expectedInstance.getFailedResponses().keySet(), newInstance.getFailedResponses().keySet()); + for (Map.Entry expectedEntry : expectedInstance.getFailedResponses().entrySet()) { + ElasticsearchException expectedException = expectedEntry.getValue(); + ElasticsearchException newException = newInstance.getFailedResponses().get(expectedEntry.getKey()); + assertThat(newException.getMessage(), containsString(expectedException.getMessage())); + } } - @Override - protected GetSnapshotsResponse createTestInstance() { + private List createSnapshotInfos() { ArrayList snapshots = new ArrayList<>(); for (int i = 0; i < randomIntBetween(5, 10); ++i) { SnapshotId snapshotId = new SnapshotId("snapshot " + i, UUIDs.base64UUID()); String reason = randomBoolean() ? null : "reason"; ShardId shardId = new ShardId("index", UUIDs.base64UUID(), 2); List shardFailures = Collections.singletonList(new SnapshotShardFailure("node-id", shardId, "reason")); - snapshots.add(new SnapshotInfo(snapshotId, Arrays.asList("indice1", "indice2"), System.currentTimeMillis(), reason, - System.currentTimeMillis(), randomIntBetween(2, 3), shardFailures, randomBoolean(), - SnapshotInfoTests.randomUserMetadata())); + snapshots.add(new SnapshotInfo(snapshotId, Arrays.asList("index1", "index2"), System.currentTimeMillis(), reason, + System.currentTimeMillis(), randomIntBetween(2, 3), shardFailures, randomBoolean(), + SnapshotInfoTests.randomUserMetadata())); + + } + return snapshots; + } + + private GetSnapshotsResponse createTestInstance() { + Set repositories = new HashSet<>(); + List responses = new ArrayList<>(); + + for (int i = 0; i < randomIntBetween(0, 5); i++) { + String repository = randomValueOtherThanMany(r -> repositories.contains(r), () -> randomAlphaOfLength(10)); + repositories.add(repository); + responses.add(GetSnapshotsResponse.Response.snapshots(repository, createSnapshotInfos())); + } + + for (int i = 0; i < randomIntBetween(0, 5); i++) { + String repository = randomValueOtherThanMany(r -> repositories.contains(r), () -> randomAlphaOfLength(10)); + repositories.add(repository); + responses.add(GetSnapshotsResponse.Response.error(repository, new ElasticsearchException(randomAlphaOfLength(10)))); } - return new GetSnapshotsResponse(snapshots); + + return new GetSnapshotsResponse(responses); + } + + public void testSerialization() throws IOException { + GetSnapshotsResponse testInstance = createTestInstance(); + GetSnapshotsResponse deserializedInstance = copyInstance(testInstance, Version.CURRENT); + assertEqualInstances(testInstance, deserializedInstance); } - @Override - protected Predicate getRandomFieldsExcludeFilter() { - // Don't inject random fields into the custom snapshot metadata, because the metadata map is equality-checked after doing a - // round-trip through xContent serialization/deserialization. Even though the rest of the object ignores unknown fields, - // `metadata` doesn't ignore unknown fields (it just includes them in the parsed object, because the keys are arbitrary), so any - // new fields added to the the metadata before it gets deserialized that weren't in the serialized version will cause the equality - // check to fail. + public void testFromXContent() throws IOException { + final Predicate predicate = Pattern.compile("responses\\.\\d+\\.snapshots\\.\\d+\\.metadata.*").asMatchPredicate(); + xContentTester(this::createParser, this::createTestInstance, ToXContent.EMPTY_PARAMS, this::doParseInstance) + .numberOfTestRuns(1) + .supportsUnknownFields(true) + .shuffleFieldsExceptions(Strings.EMPTY_ARRAY) + // Don't inject random fields into the custom snapshot metadata, because the metadata map is equality-checked after doing a + // round-trip through xContent serialization/deserialization. Even though the rest of the object ignores unknown fields, + // `metadata` doesn't ignore unknown fields (it just includes them in the parsed object, because the keys are arbitrary), + // so any new fields added to the the metadata before it gets deserialized that weren't in the serialized version will + // cause the equality check to fail. - // The actual fields are nested in an array, so this regex matches fields with names of the form `snapshots.3.metadata` - return Pattern.compile("snapshots\\.\\d+\\.metadata.*").asMatchPredicate(); + // The actual fields are nested in an array, so this regex matches fields with names of the form + // `responses.0.snapshots.3.metadata` + .randomFieldsExcludeFilter(predicate) + .assertEqualsConsumer(this::assertEqualInstances) + // We set it to false, because GetSnapshotsResponse contains + // ElasticsearchException, whose xContent creation/parsing are not stable. + .assertToXContentEquivalence(false) + .test(); } -} + +} \ No newline at end of file diff --git a/server/src/test/java/org/elasticsearch/cluster/shards/ClusterShardLimitIT.java b/server/src/test/java/org/elasticsearch/cluster/shards/ClusterShardLimitIT.java index 434c371278e06..e79bf35dda335 100644 --- a/server/src/test/java/org/elasticsearch/cluster/shards/ClusterShardLimitIT.java +++ b/server/src/test/java/org/elasticsearch/cluster/shards/ClusterShardLimitIT.java @@ -230,7 +230,7 @@ public void testRestoreSnapshotOverLimit() { equalTo(createSnapshotResponse.getSnapshotInfo().totalShards())); List snapshotInfos = client.admin().cluster().prepareGetSnapshots("test-repo") - .setSnapshots("test-snap").get().getSnapshots(); + .setSnapshots("test-snap").get().getSnapshots("test-repo"); assertThat(snapshotInfos.size(), equalTo(1)); SnapshotInfo snapshotInfo = snapshotInfos.get(0); assertThat(snapshotInfo.state(), equalTo(SnapshotState.SUCCESS)); diff --git a/server/src/test/java/org/elasticsearch/discovery/SnapshotDisruptionIT.java b/server/src/test/java/org/elasticsearch/discovery/SnapshotDisruptionIT.java index c8bb9e33c6eac..371b811c82d94 100644 --- a/server/src/test/java/org/elasticsearch/discovery/SnapshotDisruptionIT.java +++ b/server/src/test/java/org/elasticsearch/discovery/SnapshotDisruptionIT.java @@ -179,7 +179,7 @@ private void assertAllSnapshotsCompleted() throws Exception { private void assertSnapshotExists(String repository, String snapshot) { GetSnapshotsResponse snapshotsStatusResponse = dataNodeClient().admin().cluster().prepareGetSnapshots(repository) .setSnapshots(snapshot).get(); - SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots().get(0); + SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots(repository).get(0); assertEquals(SnapshotState.SUCCESS, snapshotInfo.state()); assertEquals(snapshotInfo.totalShards(), snapshotInfo.successfulShards()); assertEquals(0, snapshotInfo.failedShards()); diff --git a/server/src/test/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java b/server/src/test/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java index 4710c59647c25..aca82d438976d 100644 --- a/server/src/test/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java +++ b/server/src/test/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java @@ -521,7 +521,7 @@ public void testSnapshotRecovery() throws Exception { equalTo(createSnapshotResponse.getSnapshotInfo().totalShards())); assertThat(client().admin().cluster().prepareGetSnapshots(REPO_NAME).setSnapshots(SNAP_NAME).get() - .getSnapshots().get(0).state(), equalTo(SnapshotState.SUCCESS)); + .getSnapshots(REPO_NAME).get(0).state(), equalTo(SnapshotState.SUCCESS)); client().admin().indices().prepareClose(INDEX_NAME).execute().actionGet(); diff --git a/server/src/test/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java b/server/src/test/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java index 9fe7356877c8e..032e8a982ed4b 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java +++ b/server/src/test/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java @@ -120,7 +120,7 @@ public SnapshotInfo waitForCompletion(String repository, String snapshotName, Ti long start = System.currentTimeMillis(); while (System.currentTimeMillis() - start < timeout.millis()) { List snapshotInfos = client().admin().cluster().prepareGetSnapshots(repository).setSnapshots(snapshotName) - .get().getSnapshots(); + .get().getSnapshots(repository); assertThat(snapshotInfos.size(), equalTo(1)); if (snapshotInfos.get(0).state().completed()) { // Make sure that snapshot clean up operations are finished diff --git a/server/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java index 4a28b1eeea440..765d1ee502988 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/DedicatedClusterSnapshotRestoreIT.java @@ -219,8 +219,7 @@ public void testExceptionWhenRestoringPersistentSettings() { assertThat(createSnapshotResponse.getSnapshotInfo().totalShards(), equalTo(0)); assertThat(createSnapshotResponse.getSnapshotInfo().successfulShards(), equalTo(0)); assertThat(client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test-snap").execute().actionGet() - .getSnapshots().get(0).state(), - equalTo(SnapshotState.SUCCESS)); + .getSnapshots("test-repo").get(0).state(), equalTo(SnapshotState.SUCCESS)); logger.info("--> change the test persistent setting and break it"); setSettingValue.accept("new value 2"); @@ -272,7 +271,7 @@ public void testRestoreCustomMetadata() throws Exception { assertThat(createSnapshotResponse.getSnapshotInfo().successfulShards(), equalTo(createSnapshotResponse.getSnapshotInfo().successfulShards())); assertThat(client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test-snap").execute().actionGet() - .getSnapshots().get(0).state(), + .getSnapshots("test-repo").get(0).state(), equalTo(SnapshotState.SUCCESS)); logger.info("--> change custom persistent metadata"); @@ -584,8 +583,8 @@ public void testRestoreIndexWithMissingShards() throws Exception { assertBusy(() -> { GetSnapshotsResponse response = client().admin().cluster().prepareGetSnapshots("test-repo") .setSnapshots("test-snap-2").get(); - assertThat(response.getSnapshots().size(), equalTo(1)); - SnapshotInfo snapshotInfo = response.getSnapshots().get(0); + assertThat(response.getSnapshots("test-repo").size(), equalTo(1)); + SnapshotInfo snapshotInfo = response.getSnapshots("test-repo").get(0); assertTrue(snapshotInfo.state().completed()); assertEquals(SnapshotState.PARTIAL, snapshotInfo.state()); }, 1, TimeUnit.MINUTES); @@ -600,7 +599,7 @@ public void testRestoreIndexWithMissingShards() throws Exception { assertThat(createSnapshotResponse.getSnapshotInfo().successfulShards(), lessThan(16)); assertThat(createSnapshotResponse.getSnapshotInfo().successfulShards(), greaterThan(10)); assertThat(client().admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test-snap-2").execute().actionGet() - .getSnapshots().get(0).state(), + .getSnapshots("test-repo").get(0).state(), equalTo(SnapshotState.PARTIAL)); } @@ -841,7 +840,7 @@ public void testMasterShutdownDuringSnapshot() throws Exception { assertBusy(() -> { GetSnapshotsResponse snapshotsStatusResponse = client().admin().cluster().prepareGetSnapshots("test-repo") .setSnapshots("test-snap").get(); - SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots().get(0); + SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots("test-repo").get(0); assertTrue(snapshotInfo.state().completed()); }, 1, TimeUnit.MINUTES); @@ -849,7 +848,7 @@ public void testMasterShutdownDuringSnapshot() throws Exception { GetSnapshotsResponse snapshotsStatusResponse = client().admin().cluster().prepareGetSnapshots("test-repo") .setSnapshots("test-snap").get(); - SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots().get(0); + SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots("test-repo").get(0); assertEquals(SnapshotState.SUCCESS, snapshotInfo.state()); assertEquals(snapshotInfo.totalShards(), snapshotInfo.successfulShards()); assertEquals(0, snapshotInfo.failedShards()); @@ -901,7 +900,7 @@ public void testMasterAndDataShutdownDuringSnapshot() throws Exception { assertBusy(() -> { GetSnapshotsResponse snapshotsStatusResponse = client().admin().cluster().prepareGetSnapshots("test-repo") .setSnapshots("test-snap").get(); - SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots().get(0); + SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots("test-repo").get(0); assertTrue(snapshotInfo.state().completed()); }, 1, TimeUnit.MINUTES); @@ -909,7 +908,7 @@ public void testMasterAndDataShutdownDuringSnapshot() throws Exception { GetSnapshotsResponse snapshotsStatusResponse = client().admin().cluster().prepareGetSnapshots("test-repo") .setSnapshots("test-snap").get(); - SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots().get(0); + SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots("test-repo").get(0); assertEquals(SnapshotState.PARTIAL, snapshotInfo.state()); assertNotEquals(snapshotInfo.totalShards(), snapshotInfo.successfulShards()); assertThat(snapshotInfo.failedShards(), greaterThan(0)); @@ -967,8 +966,8 @@ public void testMasterShutdownDuringFailedSnapshot() throws Exception { assertBusy(() -> { GetSnapshotsResponse snapshotsStatusResponse = client().admin().cluster() .prepareGetSnapshots("test-repo").setSnapshots("test-snap").setIgnoreUnavailable(true).get(); - assertEquals(1, snapshotsStatusResponse.getSnapshots().size()); - SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots().get(0); + assertEquals(1, snapshotsStatusResponse.getSnapshots("test-repo").size()); + SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots("test-repo").get(0); assertTrue(snapshotInfo.state().completed()); ClusterState clusterState = client().admin().cluster().prepareState().get().getState(); SnapshotsInProgress snapshotsInProgress = clusterState.custom(SnapshotsInProgress.TYPE); @@ -978,7 +977,7 @@ public void testMasterShutdownDuringFailedSnapshot() throws Exception { logger.info("--> verify that snapshot failed"); GetSnapshotsResponse snapshotsStatusResponse = client().admin().cluster() .prepareGetSnapshots("test-repo").setSnapshots("test-snap").get(); - SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots().get(0); + SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots("test-repo").get(0); assertEquals(SnapshotState.FAILED, snapshotInfo.state()); } @@ -1216,8 +1215,8 @@ public void testDataNodeRestartWithBusyMasterDuringSnapshot() throws Exception { assertBusy(() -> { GetSnapshotsResponse snapshotsStatusResponse = client().admin().cluster() .prepareGetSnapshots("test-repo").setSnapshots("test-snap").setIgnoreUnavailable(true).get(); - assertEquals(1, snapshotsStatusResponse.getSnapshots().size()); - SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots().get(0); + assertEquals(1, snapshotsStatusResponse.getSnapshots("test-repo").size()); + SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots("test-repo").get(0); assertTrue(snapshotInfo.state().toString(), snapshotInfo.state().completed()); }, 60L, TimeUnit.SECONDS); } diff --git a/server/src/test/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java index aeea321b8536b..367dc44a9a686 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/MetadataLoadingDuringSnapshotRestoreIT.java @@ -89,7 +89,7 @@ public void testWhenMetadataAreLoaded() throws Exception { // Getting a snapshot does not load any metadata GetSnapshotsResponse getSnapshotsResponse = client().admin().cluster().prepareGetSnapshots("repository").addSnapshots("snap").setVerbose(randomBoolean()).get(); - assertThat(getSnapshotsResponse.getSnapshots(), hasSize(1)); + assertThat(getSnapshotsResponse.getSnapshots("repository"), hasSize(1)); assertGlobalMetadataLoads("snap", 0); assertIndexMetadataLoads("snap", "docs", 0); assertIndexMetadataLoads("snap", "others", 0); diff --git a/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java index 885baa883ed63..0dd8d6af585d8 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/MinThreadsSnapshotRestoreIT.java @@ -104,7 +104,7 @@ public void testConcurrentSnapshotDeletionsNotAllowed() throws Exception { logger.info("--> delete second snapshot, which should now work"); client().admin().cluster().prepareDeleteSnapshot(repo, snapshot1).get(); - assertTrue(client().admin().cluster().prepareGetSnapshots(repo).setSnapshots("_all").get().getSnapshots().isEmpty()); + assertTrue(client().admin().cluster().prepareGetSnapshots(repo).setSnapshots("_all").get().getSnapshots(repo).isEmpty()); } public void testSnapshottingWithInProgressDeletionNotAllowed() throws Exception { @@ -150,7 +150,7 @@ public void testSnapshottingWithInProgressDeletionNotAllowed() throws Exception logger.info("--> creating second snapshot, which should now work"); client().admin().cluster().prepareCreateSnapshot(repo, snapshot2).setWaitForCompletion(true).get(); - assertEquals(1, client().admin().cluster().prepareGetSnapshots(repo).setSnapshots("_all").get().getSnapshots().size()); + assertEquals(1, client().admin().cluster().prepareGetSnapshots(repo).setSnapshots("_all").get().getSnapshots(repo).size()); } public void testRestoreWithInProgressDeletionsNotAllowed() throws Exception { @@ -204,6 +204,6 @@ public void testRestoreWithInProgressDeletionsNotAllowed() throws Exception { logger.info("--> restoring snapshot, which should now work"); client().admin().cluster().prepareRestoreSnapshot(repo, snapshot1).setWaitForCompletion(true).get(); - assertEquals(1, client().admin().cluster().prepareGetSnapshots(repo).setSnapshots("_all").get().getSnapshots().size()); + assertEquals(1, client().admin().cluster().prepareGetSnapshots(repo).setSnapshots("_all").get().getSnapshots(repo).size()); } } diff --git a/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java index 8fcaaf8695fbd..b0e4f584a603a 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java @@ -240,7 +240,7 @@ public void testBasicWorkFlow() throws Exception { equalTo(createSnapshotResponse.getSnapshotInfo().totalShards())); List snapshotInfos = client.admin().cluster().prepareGetSnapshots("test-repo") - .setSnapshots(randomFrom("test-snap", "_all", "*", "*-snap", "test*")).get().getSnapshots(); + .setSnapshots(randomFrom("test-snap", "_all", "*", "*-snap", "test*")).get().getSnapshots("test-repo"); assertThat(snapshotInfos.size(), equalTo(1)); SnapshotInfo snapshotInfo = snapshotInfos.get(0); assertThat(snapshotInfo.state(), equalTo(SnapshotState.SUCCESS)); @@ -479,8 +479,8 @@ public void testEmptySnapshot() throws Exception { assertThat(createSnapshotResponse.getSnapshotInfo().totalShards(), equalTo(0)); assertThat(createSnapshotResponse.getSnapshotInfo().successfulShards(), equalTo(0)); - assertThat(client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test-snap").get().getSnapshots().get(0).state(), - equalTo(SnapshotState.SUCCESS)); + assertThat(client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test-snap") + .get().getSnapshots("test-repo").get(0).state(), equalTo(SnapshotState.SUCCESS)); } public void testRestoreAliases() throws Exception { @@ -577,8 +577,8 @@ public void testRestoreTemplates() throws Exception { .setIndices().setWaitForCompletion(true).get(); assertThat(createSnapshotResponse.getSnapshotInfo().totalShards(), equalTo(0)); assertThat(createSnapshotResponse.getSnapshotInfo().successfulShards(), equalTo(0)); - assertThat(client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test-snap").get().getSnapshots().get(0).state(), - equalTo(SnapshotState.SUCCESS)); + assertThat(client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test-snap").get(). + getSnapshots("test-repo").get(0).state(), equalTo(SnapshotState.SUCCESS)); logger.info("--> delete test template"); assertThat(client.admin().indices().prepareDeleteTemplate("test-template").get().isAcknowledged(), equalTo(true)); @@ -661,7 +661,7 @@ public void testIncludeGlobalState() throws Exception { assertThat(createSnapshotResponse.getSnapshotInfo().totalShards(), equalTo(0)); assertThat(createSnapshotResponse.getSnapshotInfo().successfulShards(), equalTo(0)); assertThat(client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test-snap-no-global-state") - .get().getSnapshots().get(0).state(), + .get().getSnapshots("test-repo").get(0).state(), equalTo(SnapshotState.SUCCESS)); SnapshotsStatusResponse snapshotsStatusResponse = client.admin().cluster().prepareSnapshotStatus("test-repo") .addSnapshots("test-snap-no-global-state").get(); @@ -675,7 +675,7 @@ public void testIncludeGlobalState() throws Exception { assertThat(createSnapshotResponse.getSnapshotInfo().totalShards(), equalTo(0)); assertThat(createSnapshotResponse.getSnapshotInfo().successfulShards(), equalTo(0)); assertThat(client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test-snap-with-global-state") - .get().getSnapshots().get(0).state(), + .get().getSnapshots("test-repo").get(0).state(), equalTo(SnapshotState.SUCCESS)); snapshotsStatusResponse = client.admin().cluster().prepareSnapshotStatus("test-repo") .addSnapshots("test-snap-with-global-state").get(); @@ -750,7 +750,7 @@ public void testIncludeGlobalState() throws Exception { assertThat(createSnapshotResponse.getSnapshotInfo().successfulShards(), equalTo(createSnapshotResponse.getSnapshotInfo().totalShards())); assertThat(client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test-snap-no-global-state-with-index") - .get().getSnapshots().get(0).state(), + .get().getSnapshots("test-repo").get(0).state(), equalTo(SnapshotState.SUCCESS)); logger.info("--> delete global state and index "); @@ -823,8 +823,8 @@ public void testSnapshotFileFailureDuringSnapshot() { } GetSnapshotsResponse getSnapshotsResponse = client.admin().cluster().prepareGetSnapshots("test-repo") .addSnapshots("test-snap").get(); - assertThat(getSnapshotsResponse.getSnapshots().size(), equalTo(1)); - SnapshotInfo snapshotInfo = getSnapshotsResponse.getSnapshots().get(0); + assertThat(getSnapshotsResponse.getSnapshots("test-repo").size(), equalTo(1)); + SnapshotInfo snapshotInfo = getSnapshotsResponse.getSnapshots("test-repo").get(0); if (snapshotInfo.state() == SnapshotState.SUCCESS) { assertThat(snapshotInfo.shardFailures().size(), greaterThan(0)); assertThat(snapshotInfo.totalShards(), greaterThan(snapshotInfo.successfulShards())); @@ -879,8 +879,8 @@ public void testDataFileFailureDuringSnapshot() throws Exception { } GetSnapshotsResponse getSnapshotsResponse = client.admin().cluster().prepareGetSnapshots("test-repo") .addSnapshots("test-snap").get(); - assertThat(getSnapshotsResponse.getSnapshots().size(), equalTo(1)); - SnapshotInfo snapshotInfo = getSnapshotsResponse.getSnapshots().get(0); + assertThat(getSnapshotsResponse.getSnapshots("test-repo").size(), equalTo(1)); + SnapshotInfo snapshotInfo = getSnapshotsResponse.getSnapshots("test-repo").get(0); assertThat(snapshotInfo.state(), equalTo(SnapshotState.PARTIAL)); assertThat(snapshotInfo.shardFailures().size(), greaterThan(0)); assertThat(snapshotInfo.totalShards(), greaterThan(snapshotInfo.successfulShards())); @@ -1323,6 +1323,87 @@ public void testDeleteSnapshot() throws Exception { assertThat(numberOfFiles(repo), equalTo(numberOfFiles[0] + 2)); } + public void testGetSnapshotsMultipleRepos() { + final Client client = client(); + + List snapshotList = new ArrayList<>(); + List repoList = new ArrayList<>(); + Map> repo2SnapshotNames = new HashMap<>(); + + logger.info("--> create an index and index some documents"); + final String indexName = "test-idx"; + assertAcked(prepareCreate(indexName)); + ensureGreen(); + for (int i = 0; i < 10; i++) { + index(indexName, "_doc", Integer.toString(i), "foo", "bar" + i); + } + refresh(); + + for (int repoIndex = 0; repoIndex < randomIntBetween(2, 5); repoIndex++) { + final String repoName = "repo" + repoIndex; + repoList.add(repoName); + final Path repoPath = randomRepoPath(); + logger.info("--> create repository with name " + repoName); + assertAcked(client.admin().cluster().preparePutRepository(repoName) + .setType("fs").setSettings(Settings.builder().put("location", repoPath).build())); + List snapshotNames = new ArrayList<>(); + repo2SnapshotNames.put(repoName, snapshotNames); + + for (int snapshotIndex = 0; snapshotIndex < randomIntBetween(2, 5); snapshotIndex++) { + final String snapshotName = randomAlphaOfLength(10).toLowerCase(Locale.ROOT); + snapshotList.add(snapshotName); + logger.info("--> create snapshot with index {} and name {} in repository {}", snapshotIndex, snapshotName, repoName); + CreateSnapshotResponse createSnapshotResponse = client.admin() + .cluster() + .prepareCreateSnapshot(repoName, snapshotName) + .setWaitForCompletion(true) + .setIndices(indexName) + .get(); + assertThat(createSnapshotResponse.getSnapshotInfo().successfulShards(), greaterThan(0)); + snapshotNames.add(snapshotName); + } + } + + logger.info("--> get and verify snapshots"); + GetSnapshotsResponse getSnapshotsResponse = client.admin().cluster() + .prepareGetSnapshots(randomFrom(new String[]{"_all"}, new String[]{"repo*"}, repoList.toArray(new String[0]))) + .setSnapshots(randomFrom("_all", "*")) + .get(); + + for (Map.Entry> repo2Names : repo2SnapshotNames.entrySet()) { + String repo = repo2Names.getKey(); + List snapshotNames = repo2Names.getValue(); + List snapshots = getSnapshotsResponse.getSnapshots(repo); + assertEquals(snapshotNames, snapshots.stream().map(s -> s.snapshotId().getName()).collect(Collectors.toList())); + } + + logger.info("--> specify all snapshot names with ignoreUnavailable=false"); + GetSnapshotsResponse getSnapshotsResponse2 = client.admin().cluster() + .prepareGetSnapshots(randomFrom("_all", "repo*")) + .setIgnoreUnavailable(false) + .setSnapshots(snapshotList.toArray(new String[0])) + .get(); + + for (String repo : repoList) { + expectThrows(SnapshotMissingException.class, () -> getSnapshotsResponse2.getSnapshots(repo)); + } + + + logger.info("--> specify all snapshot names with ignoreUnavailable=true"); + GetSnapshotsResponse getSnapshotsResponse3 = client.admin().cluster() + .prepareGetSnapshots(randomFrom("_all", "repo*")) + .setIgnoreUnavailable(true) + .setSnapshots(snapshotList.toArray(new String[0])) + .get(); + + for (Map.Entry> repo2Names : repo2SnapshotNames.entrySet()) { + String repo = repo2Names.getKey(); + List snapshotNames = repo2Names.getValue(); + List snapshots = getSnapshotsResponse3.getSnapshots(repo); + assertEquals(snapshotNames, snapshots.stream().map(s -> s.snapshotId().getName()).collect(Collectors.toList())); + } + } + public void testDeleteSnapshotWithMissingIndexAndShardMetadata() throws Exception { Client client = client(); @@ -1367,8 +1448,9 @@ public void testDeleteSnapshotWithMissingIndexAndShardMetadata() throws Exceptio client.admin().cluster().prepareDeleteSnapshot("test-repo", "test-snap-1").get(); logger.info("--> make sure snapshot doesn't exist"); - assertThrows(client.admin().cluster().prepareGetSnapshots("test-repo") - .addSnapshots("test-snap-1"), SnapshotMissingException.class); + + expectThrows(SnapshotMissingException.class, () -> client.admin().cluster().prepareGetSnapshots("test-repo") + .addSnapshots("test-snap-1").get().getSnapshots("test-repo")); for (String index : indices) { assertTrue(Files.notExists(indicesPath.resolve(indexIds.get(index).getId()))); @@ -1407,8 +1489,8 @@ public void testDeleteSnapshotWithMissingMetadata() throws Exception { client.admin().cluster().prepareDeleteSnapshot("test-repo", "test-snap-1").get(); logger.info("--> make sure snapshot doesn't exist"); - assertThrows(client.admin().cluster().prepareGetSnapshots("test-repo") - .addSnapshots("test-snap-1"), SnapshotMissingException.class); + expectThrows(SnapshotMissingException.class, () -> client.admin().cluster().prepareGetSnapshots("test-repo") + .addSnapshots("test-snap-1").get().getSnapshots("test-repo")); } public void testDeleteSnapshotWithCorruptedSnapshotFile() throws Exception { @@ -1444,7 +1526,9 @@ public void testDeleteSnapshotWithCorruptedSnapshotFile() throws Exception { client.admin().cluster().prepareDeleteSnapshot("test-repo", "test-snap-1").get(); logger.info("--> make sure snapshot doesn't exist"); - assertThrows(client.admin().cluster().prepareGetSnapshots("test-repo").addSnapshots("test-snap-1"), SnapshotMissingException.class); + expectThrows(SnapshotMissingException.class, + () -> client.admin().cluster().prepareGetSnapshots("test-repo").addSnapshots("test-snap-1").get(). + getSnapshots("test-repo")); logger.info("--> make sure that we can create the snapshot again"); createSnapshotResponse = client.admin().cluster().prepareCreateSnapshot("test-repo", "test-snap-1") @@ -1490,7 +1574,7 @@ public void testDeleteSnapshotWithCorruptedGlobalState() throws Exception { } } - List snapshotInfos = client().admin().cluster().prepareGetSnapshots("test-repo").get().getSnapshots(); + List snapshotInfos = client().admin().cluster().prepareGetSnapshots("test-repo").get().getSnapshots("test-repo"); assertThat(snapshotInfos.size(), equalTo(1)); assertThat(snapshotInfos.get(0).state(), equalTo(SnapshotState.SUCCESS)); assertThat(snapshotInfos.get(0).snapshotId().getName(), equalTo("test-snap")); @@ -1501,8 +1585,8 @@ public void testDeleteSnapshotWithCorruptedGlobalState() throws Exception { assertThat(snapshotStatusResponse.getSnapshots().get(0).getSnapshot().getSnapshotId().getName(), equalTo("test-snap")); assertAcked(client().admin().cluster().prepareDeleteSnapshot("test-repo", "test-snap").get()); - assertThrows(client().admin().cluster().prepareGetSnapshots("test-repo").addSnapshots("test-snap"), - SnapshotMissingException.class); + expectThrows(SnapshotMissingException.class, () -> client().admin().cluster() + .prepareGetSnapshots("test-repo").addSnapshots("test-snap").get().getSnapshots("test-repo")); assertThrows(client().admin().cluster().prepareSnapshotStatus("test-repo").addSnapshots("test-snap"), SnapshotMissingException.class); @@ -1749,7 +1833,7 @@ public void testMoveShardWhileSnapshotting() throws Exception { logger.info("--> done"); List snapshotInfos = client().admin().cluster().prepareGetSnapshots("test-repo") - .setSnapshots("test-snap").get().getSnapshots(); + .setSnapshots("test-snap").get().getSnapshots("test-repo"); assertThat(snapshotInfos.size(), equalTo(1)); assertThat(snapshotInfos.get(0).state(), equalTo(SnapshotState.SUCCESS)); @@ -1834,7 +1918,7 @@ public void testDeleteRepositoryWhileSnapshotting() throws Exception { logger.info("--> done"); List snapshotInfos = client().admin().cluster().prepareGetSnapshots("test-repo") - .setSnapshots("test-snap").get().getSnapshots(); + .setSnapshots("test-snap").get().getSnapshots("test-repo"); assertThat(snapshotInfos.size(), equalTo(1)); assertThat(snapshotInfos.get(0).state(), equalTo(SnapshotState.SUCCESS)); @@ -1883,8 +1967,8 @@ public void testReadonlyRepository() throws Exception { assertThat(createSnapshotResponse.getSnapshotInfo().successfulShards(), equalTo(createSnapshotResponse.getSnapshotInfo().totalShards())); - assertThat(client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test-snap").get().getSnapshots().get(0).state(), - equalTo(SnapshotState.SUCCESS)); + assertThat(client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test-snap").get() + .getSnapshots("test-repo").get(0).state(), equalTo(SnapshotState.SUCCESS)); logger.info("--> delete index"); cluster().wipeIndices("test-idx"); @@ -1905,8 +1989,8 @@ public void testReadonlyRepository() throws Exception { logger.info("--> list available shapshots"); GetSnapshotsResponse getSnapshotsResponse = client.admin().cluster().prepareGetSnapshots("readonly-repo").get(); - assertThat(getSnapshotsResponse.getSnapshots(), notNullValue()); - assertThat(getSnapshotsResponse.getSnapshots().size(), equalTo(1)); + assertThat(getSnapshotsResponse.getSnapshots("readonly-repo"), notNullValue()); + assertThat(getSnapshotsResponse.getSnapshots("readonly-repo").size(), equalTo(1)); logger.info("--> try deleting snapshot"); assertThrows(client.admin().cluster().prepareDeleteSnapshot("readonly-repo", "test-snap"), RepositoryException.class, @@ -2047,8 +2131,8 @@ public void testSnapshotStatus() throws Exception { logger.info("--> checking that _current returns the currently running snapshot"); GetSnapshotsResponse getResponse = client.admin().cluster().prepareGetSnapshots("test-repo") .setCurrentSnapshot().execute().actionGet(); - assertThat(getResponse.getSnapshots().size(), equalTo(1)); - SnapshotInfo snapshotInfo = getResponse.getSnapshots().get(0); + assertThat(getResponse.getSnapshots("test-repo").size(), equalTo(1)); + SnapshotInfo snapshotInfo = getResponse.getSnapshots("test-repo").get(0); assertThat(snapshotInfo.state(), equalTo(SnapshotState.IN_PROGRESS)); logger.info("--> unblocking blocked node"); @@ -2078,7 +2162,7 @@ public void testSnapshotStatus() throws Exception { logger.info("--> checking that _current no longer returns the snapshot"); assertThat(client.admin().cluster().prepareGetSnapshots("test-repo").addSnapshots("_current") - .execute().actionGet().getSnapshots().isEmpty(), + .execute().actionGet().getSnapshots("test-repo").isEmpty(), equalTo(true)); // test that getting an unavailable snapshot status throws an exception if ignoreUnavailable is false on the request @@ -2168,8 +2252,8 @@ public void testSnapshotMoreThanOnce() throws ExecutionException, InterruptedExc assertThat(createSnapshotResponseFirst.getSnapshotInfo().successfulShards(), greaterThan(0)); assertThat(createSnapshotResponseFirst.getSnapshotInfo().successfulShards(), equalTo(createSnapshotResponseFirst.getSnapshotInfo().totalShards())); - assertThat(client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test").get().getSnapshots().get(0).state(), - equalTo(SnapshotState.SUCCESS)); + assertThat(client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test").get() + .getSnapshots("test-repo").get(0).state(), equalTo(SnapshotState.SUCCESS)); { SnapshotStatus snapshotStatus = client.admin().cluster().prepareSnapshotStatus("test-repo") .setSnapshots("test").get().getSnapshots().get(0); @@ -2184,8 +2268,8 @@ public void testSnapshotMoreThanOnce() throws ExecutionException, InterruptedExc assertThat(createSnapshotResponseSecond.getSnapshotInfo().successfulShards(), greaterThan(0)); assertThat(createSnapshotResponseSecond.getSnapshotInfo().successfulShards(), equalTo(createSnapshotResponseSecond.getSnapshotInfo().totalShards())); - assertThat(client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test-1").get().getSnapshots().get(0).state(), - equalTo(SnapshotState.SUCCESS)); + assertThat(client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test-1").get() + .getSnapshots("test-repo").get(0).state(), equalTo(SnapshotState.SUCCESS)); { SnapshotStatus snapshotStatus = client.admin().cluster().prepareSnapshotStatus("test-repo") .setSnapshots("test-1").get().getSnapshots().get(0); @@ -2201,8 +2285,8 @@ public void testSnapshotMoreThanOnce() throws ExecutionException, InterruptedExc assertThat(createSnapshotResponseThird.getSnapshotInfo().successfulShards(), greaterThan(0)); assertThat(createSnapshotResponseThird.getSnapshotInfo().successfulShards(), equalTo(createSnapshotResponseThird.getSnapshotInfo().totalShards())); - assertThat(client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test-2").get().getSnapshots().get(0).state(), - equalTo(SnapshotState.SUCCESS)); + assertThat(client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test-2").get() + .getSnapshots("test-repo").get(0).state(), equalTo(SnapshotState.SUCCESS)); { SnapshotStatus snapshotStatus = client.admin().cluster().prepareSnapshotStatus("test-repo") .setSnapshots("test-2").get().getSnapshots().get(0); @@ -2759,7 +2843,8 @@ public void testSnapshotName() throws Exception { expectThrows(InvalidSnapshotNameException.class, () -> client.admin().cluster().prepareCreateSnapshot("test-repo", "_foo").get()); expectThrows(SnapshotMissingException.class, - () -> client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("_foo").get()); + () -> client.admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("_foo") + .get().getSnapshots("test-repo")); expectThrows(SnapshotMissingException.class, () -> client.admin().cluster().prepareDeleteSnapshot("test-repo", "_foo").get()); expectThrows(SnapshotMissingException.class, @@ -2804,14 +2889,14 @@ public void testListCorruptedSnapshot() throws Exception { logger.info("--> get snapshots request should return both snapshots"); List snapshotInfos = client.admin().cluster() .prepareGetSnapshots("test-repo") - .setIgnoreUnavailable(true).get().getSnapshots(); + .setIgnoreUnavailable(true).get().getSnapshots("test-repo"); assertThat(snapshotInfos.size(), equalTo(1)); assertThat(snapshotInfos.get(0).state(), equalTo(SnapshotState.SUCCESS)); assertThat(snapshotInfos.get(0).snapshotId().getName(), equalTo("test-snap-1")); final SnapshotException ex = expectThrows(SnapshotException.class, () -> - client.admin().cluster().prepareGetSnapshots("test-repo").setIgnoreUnavailable(false).get()); + client.admin().cluster().prepareGetSnapshots("test-repo").setIgnoreUnavailable(false).get().getSnapshots("test-repo")); assertThat(ex.getRepositoryName(), equalTo("test-repo")); assertThat(ex.getSnapshotName(), equalTo("test-snap-2")); } @@ -2846,7 +2931,7 @@ public void testRestoreSnapshotWithCorruptedGlobalState() throws Exception { outChan.truncate(randomInt(10)); } - List snapshotInfos = client().admin().cluster().prepareGetSnapshots("test-repo").get().getSnapshots(); + List snapshotInfos = client().admin().cluster().prepareGetSnapshots("test-repo").get().getSnapshots("test-repo"); assertThat(snapshotInfos.size(), equalTo(1)); assertThat(snapshotInfos.get(0).state(), equalTo(SnapshotState.SUCCESS)); assertThat(snapshotInfos.get(0).snapshotId().getName(), equalTo("test-snap")); @@ -2936,7 +3021,7 @@ public void testRestoreSnapshotWithCorruptedIndexMetadata() throws Exception { outChan.truncate(randomInt(10)); } - List snapshotInfos = client().admin().cluster().prepareGetSnapshots("test-repo").get().getSnapshots(); + List snapshotInfos = client().admin().cluster().prepareGetSnapshots("test-repo").get().getSnapshots("test-repo"); assertThat(snapshotInfos.size(), equalTo(1)); assertThat(snapshotInfos.get(0).state(), equalTo(SnapshotState.SUCCESS)); assertThat(snapshotInfos.get(0).snapshotId().getName(), equalTo("test-snap")); @@ -3015,7 +3100,7 @@ public void testSnapshotWithCorruptedShardIndexFile() throws Exception { } logger.info("--> verifying snapshot state for [{}]", snapshot1); - List snapshotInfos = client().admin().cluster().prepareGetSnapshots("test-repo").get().getSnapshots(); + List snapshotInfos = client().admin().cluster().prepareGetSnapshots("test-repo").get().getSnapshots("test-repo"); assertThat(snapshotInfos.size(), equalTo(1)); assertThat(snapshotInfos.get(0).state(), equalTo(SnapshotState.SUCCESS)); assertThat(snapshotInfos.get(0).snapshotId().getName(), equalTo(snapshot1)); @@ -3147,7 +3232,8 @@ public void testGetSnapshotsRequest() throws Exception { .cluster() .prepareGetSnapshots(repositoryName) .addSnapshots("non-existent-snapshot") - .get()); + .get() + .getSnapshots(repositoryName)); // with ignore unavailable set to true, should not throw an exception GetSnapshotsResponse getSnapshotsResponse = client.admin() .cluster() @@ -3155,7 +3241,7 @@ public void testGetSnapshotsRequest() throws Exception { .setIgnoreUnavailable(true) .addSnapshots("non-existent-snapshot") .get(); - assertThat(getSnapshotsResponse.getSnapshots().size(), equalTo(0)); + assertThat(getSnapshotsResponse.getSnapshots(repositoryName).size(), equalTo(0)); logger.info("--> creating an index and indexing documents"); // Create index on 2 nodes and make sure each node has a primary by setting no replicas @@ -3180,8 +3266,8 @@ public void testGetSnapshotsRequest() throws Exception { .prepareGetSnapshots("test-repo") .setSnapshots(randomFrom("_all", "_current", "snap-on-*", "*-on-empty-repo", "snap-on-empty-repo")) .get(); - assertEquals(1, getSnapshotsResponse.getSnapshots().size()); - assertEquals("snap-on-empty-repo", getSnapshotsResponse.getSnapshots().get(0).snapshotId().getName()); + assertEquals(1, getSnapshotsResponse.getSnapshots("test-repo").size()); + assertEquals("snap-on-empty-repo", getSnapshotsResponse.getSnapshots("test-repo").get(0).snapshotId().getName()); unblockNode(repositoryName, initialBlockedNode); // unblock node responseListener.actionGet(TimeValue.timeValueMillis(10000L)); // timeout after 10 seconds client.admin().cluster().prepareDeleteSnapshot(repositoryName, "snap-on-empty-repo").get(); @@ -3235,8 +3321,8 @@ public void testGetSnapshotsRequest() throws Exception { .get(); List sortedNames = Arrays.asList(snapshotNames); Collections.sort(sortedNames); - assertThat(getSnapshotsResponse.getSnapshots().size(), equalTo(numSnapshots)); - assertThat(getSnapshotsResponse.getSnapshots().stream() + assertThat(getSnapshotsResponse.getSnapshots(repositoryName).size(), equalTo(numSnapshots)); + assertThat(getSnapshotsResponse.getSnapshots(repositoryName).stream() .map(s -> s.snapshotId().getName()) .sorted() .collect(Collectors.toList()), equalTo(sortedNames)); @@ -3247,8 +3333,8 @@ public void testGetSnapshotsRequest() throws Exception { .get(); sortedNames = Arrays.asList(snapshotNames); Collections.sort(sortedNames); - assertThat(getSnapshotsResponse.getSnapshots().size(), equalTo(numSnapshots)); - assertThat(getSnapshotsResponse.getSnapshots().stream() + assertThat(getSnapshotsResponse.getSnapshots(repositoryName).size(), equalTo(numSnapshots)); + assertThat(getSnapshotsResponse.getSnapshots(repositoryName).stream() .map(s -> s.snapshotId().getName()) .sorted() .collect(Collectors.toList()), equalTo(sortedNames)); @@ -3263,8 +3349,8 @@ public void testGetSnapshotsRequest() throws Exception { .addSnapshots(snapshotNames) .addSnapshots(firstRegex, secondRegex) .get(); - assertThat(getSnapshotsResponse.getSnapshots().size(), equalTo(numSnapshots)); - assertThat(getSnapshotsResponse.getSnapshots().stream() + assertThat(getSnapshotsResponse.getSnapshots(repositoryName).size(), equalTo(numSnapshots)); + assertThat(getSnapshotsResponse.getSnapshots(repositoryName).stream() .map(s -> s.snapshotId().getName()) .sorted() .collect(Collectors.toList()), equalTo(sortedNames)); @@ -3390,7 +3476,7 @@ public void testSnapshotSucceedsAfterSnapshotFailure() throws Exception { assertEquals(0, createSnapshotResponse.getSnapshotInfo().failedShards()); GetSnapshotsResponse getSnapshotsResponse = client.admin().cluster().prepareGetSnapshots("test-repo-2") .addSnapshots("test-snap-2").get(); - assertEquals(SnapshotState.SUCCESS, getSnapshotsResponse.getSnapshots().get(0).state()); + assertEquals(SnapshotState.SUCCESS, getSnapshotsResponse.getSnapshots("test-repo-2").get(0).state()); } public void testSnapshotStatusOnFailedIndex() throws Exception { @@ -3519,8 +3605,8 @@ public void testGetSnapshotsFromIndexBlobOnly() throws Exception { .setSnapshots("_all") .setVerbose(false) .get(); - assertEquals(indicesPerSnapshot.size(), response.getSnapshots().size()); - verifySnapshotInfo(response, indicesPerSnapshot); + assertEquals(indicesPerSnapshot.size(), response.getSnapshots("test-repo").size()); + verifySnapshotInfo("test-repo", response, indicesPerSnapshot); logger.info("--> verify wildcard returns snapshot info"); response = client().admin().cluster() @@ -3528,8 +3614,8 @@ public void testGetSnapshotsFromIndexBlobOnly() throws Exception { .setSnapshots("test-snap-*") .setVerbose(false) .get(); - assertEquals(indicesPerSnapshot.size(), response.getSnapshots().size()); - verifySnapshotInfo(response, indicesPerSnapshot); + assertEquals(indicesPerSnapshot.size(), response.getSnapshots("test-repo").size()); + verifySnapshotInfo("test-repo", response, indicesPerSnapshot); logger.info("--> verify individual requests return snapshot info"); for (int i = 0; i < numSnapshots; i++) { @@ -3538,8 +3624,8 @@ public void testGetSnapshotsFromIndexBlobOnly() throws Exception { .setSnapshots("test-snap-" + i) .setVerbose(false) .get(); - assertEquals(1, response.getSnapshots().size()); - verifySnapshotInfo(response, indicesPerSnapshot); + assertEquals(1, response.getSnapshots("test-repo").size()); + verifySnapshotInfo("test-repo", response, indicesPerSnapshot); } } @@ -3794,7 +3880,8 @@ public void testAbortedSnapshotDuringInitDoesNotStart() throws Exception { assertAcked(delete.get()); expectThrows(SnapshotMissingException.class, () -> - client.admin().cluster().prepareGetSnapshots("repository").setSnapshots("snap").get()); + client.admin().cluster().prepareGetSnapshots("repository").setSnapshots("snap").get() + .getSnapshots("repository")); assertFalse("Expecting snapshot state to be updated", states.isEmpty()); assertFalse("Expecting snapshot to be aborted and not started at all", states.contains(State.STARTED)); @@ -3861,8 +3948,9 @@ private RepositoryData getRepositoryData(Repository repository) throws Interrupt return repositoryData.get(); } - private void verifySnapshotInfo(final GetSnapshotsResponse response, final Map> indicesPerSnapshot) { - for (SnapshotInfo snapshotInfo : response.getSnapshots()) { + private void verifySnapshotInfo(final String repo, final GetSnapshotsResponse response, + final Map> indicesPerSnapshot) { + for (SnapshotInfo snapshotInfo : response.getSnapshots("test-repo")) { final List expected = snapshotInfo.indices(); assertEquals(expected, indicesPerSnapshot.get(snapshotInfo.snapshotId().getName())); assertEquals(SnapshotState.SUCCESS, snapshotInfo.state()); diff --git a/server/src/test/java/org/elasticsearch/snapshots/SnapshotShardsServiceIT.java b/server/src/test/java/org/elasticsearch/snapshots/SnapshotShardsServiceIT.java index 20dd3693f78cd..0b18ce15abd26 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SnapshotShardsServiceIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SnapshotShardsServiceIT.java @@ -77,7 +77,7 @@ public void testRetryPostingSnapshotStatusMessages() throws Exception { waitForBlock(blockedNode, "test-repo", TimeValue.timeValueSeconds(60)); final SnapshotId snapshotId = client().admin().cluster().prepareGetSnapshots("test-repo").setSnapshots("test-snap") - .get().getSnapshots().get(0).snapshotId(); + .get().getSnapshots("test-repo").get(0).snapshotId(); logger.info("--> start disrupting cluster"); final NetworkDisruption networkDisruption = new NetworkDisruption(new NetworkDisruption.TwoPartitions(masterNode, dataNode), @@ -106,7 +106,7 @@ public void testRetryPostingSnapshotStatusMessages() throws Exception { GetSnapshotsResponse snapshotsStatusResponse = client().admin().cluster() .prepareGetSnapshots("test-repo") .setSnapshots("test-snap").get(); - SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots().get(0); + SnapshotInfo snapshotInfo = snapshotsStatusResponse.getSnapshots("test-repo").get(0); logger.info("Snapshot status [{}], successfulShards [{}]", snapshotInfo.state(), snapshotInfo.successfulShards()); assertThat(snapshotInfo.state(), equalTo(SnapshotState.SUCCESS)); assertThat(snapshotInfo.successfulShards(), equalTo(shards)); diff --git a/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java b/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java index 305d911508087..52ed98ac811ee 100644 --- a/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/repositories/AbstractThirdPartyRepositoryTestCase.java @@ -119,7 +119,7 @@ public void testCreateSnapshot() { .prepareGetSnapshots("test-repo") .setSnapshots(snapshotName) .get() - .getSnapshots() + .getSnapshots("test-repo") .get(0) .state(), equalTo(SnapshotState.SUCCESS)); diff --git a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java index 8187a46fa7425..947a2c9887c10 100644 --- a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java @@ -148,7 +148,7 @@ public void testSnapshotAndRestore() throws Exception { assertAcked(client().admin().cluster().prepareDeleteSnapshot(repoName, snapshotName).get()); expectThrows(SnapshotMissingException.class, () -> - client().admin().cluster().prepareGetSnapshots(repoName).setSnapshots(snapshotName).get()); + client().admin().cluster().prepareGetSnapshots(repoName).setSnapshots(snapshotName).get().getSnapshots(repoName)); expectThrows(SnapshotMissingException.class, () -> client().admin().cluster().prepareDeleteSnapshot(repoName, snapshotName).get()); diff --git a/test/framework/src/main/java/org/elasticsearch/test/rest/ESRestTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/rest/ESRestTestCase.java index 87596beb451d1..90fc04400c476 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/rest/ESRestTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/rest/ESRestTestCase.java @@ -540,7 +540,16 @@ private void wipeCluster() throws Exception { // All other repo types we really don't have a chance of being able to iterate properly, sadly. Request listRequest = new Request("GET", "/_snapshot/" + repoName + "/_all"); listRequest.addParameter("ignore_unavailable", "true"); - List snapshots = (List) entityAsMap(adminClient.performRequest(listRequest)).get("snapshots"); + + Map response = entityAsMap(adminClient.performRequest(listRequest)); + Map oneRepoResponse; + if (response.containsKey("responses")) { + oneRepoResponse = ((Map)((List) response.get("responses")).get(0)); + } else { + oneRepoResponse = response; + } + + List snapshots = (List) oneRepoResponse.get("snapshots"); for (Object snapshot : snapshots) { Map snapshotInfo = (Map) snapshot; String name = (String) snapshotInfo.get("snapshot"); diff --git a/x-pack/plugin/ilm/qa/multi-cluster/src/test/java/org/elasticsearch/xpack/indexlifecycle/CCRIndexLifecycleIT.java b/x-pack/plugin/ilm/qa/multi-cluster/src/test/java/org/elasticsearch/xpack/indexlifecycle/CCRIndexLifecycleIT.java index aca20286eb377..14e70446ab120 100644 --- a/x-pack/plugin/ilm/qa/multi-cluster/src/test/java/org/elasticsearch/xpack/indexlifecycle/CCRIndexLifecycleIT.java +++ b/x-pack/plugin/ilm/qa/multi-cluster/src/test/java/org/elasticsearch/xpack/indexlifecycle/CCRIndexLifecycleIT.java @@ -11,7 +11,6 @@ import org.apache.logging.log4j.Logger; import org.elasticsearch.client.Request; import org.elasticsearch.client.Response; -import org.elasticsearch.client.ResponseException; import org.elasticsearch.client.RestClient; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; @@ -171,9 +170,6 @@ public void testCCRUnfollowDuringSnapshot() throws Exception { // assert that snapshot succeeded assertThat(getSnapshotState("snapshot"), equalTo("SUCCESS")); assertOK(client().performRequest(new Request("DELETE", "/_snapshot/repo/snapshot"))); - ResponseException e = expectThrows(ResponseException.class, - () -> client().performRequest(new Request("GET", "/_snapshot/repo/snapshot"))); - assertThat(e.getResponse().getStatusLine().getStatusCode(), equalTo(404)); } } else { fail("unexpected target cluster [" + targetCluster + "]"); @@ -775,13 +771,16 @@ public static void updatePolicy(String indexName, String policy) throws IOExcept assertOK(client().performRequest(changePolicyRequest)); } + @SuppressWarnings("unchecked") private String getSnapshotState(String snapshot) throws IOException { Response response = client().performRequest(new Request("GET", "/_snapshot/repo/" + snapshot)); Map responseMap; try (InputStream is = response.getEntity().getContent()) { responseMap = XContentHelper.convertToMap(XContentType.JSON.xContent(), is, true); } - @SuppressWarnings("unchecked") Map snapResponse = ((List>) responseMap.get("snapshots")).get(0); + + Map repoResponse = ((List>) responseMap.get("responses")).get(0); + Map snapResponse = ((List>) repoResponse.get("snapshots")).get(0); assertThat(snapResponse.get("snapshot"), equalTo(snapshot)); return (String) snapResponse.get("state"); } diff --git a/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/indexlifecycle/TimeSeriesLifecycleActionsIT.java b/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/indexlifecycle/TimeSeriesLifecycleActionsIT.java index db295cea5dff3..a492f1885e661 100644 --- a/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/indexlifecycle/TimeSeriesLifecycleActionsIT.java +++ b/x-pack/plugin/ilm/qa/multi-node/src/test/java/org/elasticsearch/xpack/indexlifecycle/TimeSeriesLifecycleActionsIT.java @@ -393,9 +393,6 @@ public void testDeleteDuringSnapshot() throws Exception { // assert that snapshot is still in progress and clean up assertThat(getSnapshotState("snapshot"), equalTo("SUCCESS")); assertOK(client().performRequest(new Request("DELETE", "/_snapshot/repo/snapshot"))); - ResponseException e = expectThrows(ResponseException.class, - () -> client().performRequest(new Request("GET", "/_snapshot/repo/snapshot"))); - assertThat(e.getResponse().getStatusLine().getStatusCode(), equalTo(404)); } public void testReadOnly() throws Exception { @@ -533,9 +530,6 @@ public void testShrinkDuringSnapshot() throws Exception { // assert that snapshot succeeded assertThat(getSnapshotState("snapshot"), equalTo("SUCCESS")); assertOK(client().performRequest(new Request("DELETE", "/_snapshot/repo/snapshot"))); - ResponseException e = expectThrows(ResponseException.class, - () -> client().performRequest(new Request("GET", "/_snapshot/repo/snapshot"))); - assertThat(e.getResponse().getStatusLine().getStatusCode(), equalTo(404)); } public void testFreezeAction() throws Exception { @@ -591,9 +585,6 @@ public void testFreezeDuringSnapshot() throws Exception { // assert that snapshot is still in progress and clean up assertThat(getSnapshotState("snapshot"), equalTo("SUCCESS")); assertOK(client().performRequest(new Request("DELETE", "/_snapshot/repo/snapshot"))); - ResponseException e = expectThrows(ResponseException.class, - () -> client().performRequest(new Request("GET", "/_snapshot/repo/snapshot"))); - assertThat(e.getResponse().getStatusLine().getStatusCode(), equalTo(404)); } public void testSetPriority() throws Exception { @@ -977,13 +968,16 @@ private void indexDocument() throws IOException { logger.info(response.getStatusLine()); } + @SuppressWarnings("unchecked") private String getSnapshotState(String snapshot) throws IOException { Response response = client().performRequest(new Request("GET", "/_snapshot/repo/" + snapshot)); Map responseMap; try (InputStream is = response.getEntity().getContent()) { responseMap = XContentHelper.convertToMap(XContentType.JSON.xContent(), is, true); } - Map snapResponse = ((List>) responseMap.get("snapshots")).get(0); + + Map repoResponse = ((List>) responseMap.get("responses")).get(0); + Map snapResponse = ((List>) repoResponse.get("snapshots")).get(0); assertThat(snapResponse.get("snapshot"), equalTo(snapshot)); return (String) snapResponse.get("state"); } diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java index 0f533477b94fd..1994e5b702061 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/SnapshotUserRoleIntegTests.java @@ -88,9 +88,10 @@ public void testSnapshotUserRoleCanSnapshotAndSeeAllIndices() { assertThat(snapshotResponse.getSnapshotInfo().indices(), containsInAnyOrder(INTERNAL_SECURITY_MAIN_INDEX_7, ordinaryIndex)); // view snapshots for repo final GetSnapshotsResponse getSnapshotResponse = client.admin().cluster().prepareGetSnapshots("repo").get(); - assertThat(getSnapshotResponse.getSnapshots().size(), is(1)); - assertThat(getSnapshotResponse.getSnapshots().get(0).snapshotId().getName(), is("snap")); - assertThat(getSnapshotResponse.getSnapshots().get(0).indices(), containsInAnyOrder(INTERNAL_SECURITY_MAIN_INDEX_7, ordinaryIndex)); + assertThat(getSnapshotResponse.getSnapshots("repo").size(), is(1)); + assertThat(getSnapshotResponse.getSnapshots("repo").get(0).snapshotId().getName(), is("snap")); + assertThat(getSnapshotResponse.getSnapshots("repo").get(0).indices(), containsInAnyOrder(INTERNAL_SECURITY_MAIN_INDEX_7, + ordinaryIndex)); } public void testSnapshotUserRoleIsReserved() {